<commit_before>package config

import (
	"log"

	"encoding/json"
	"fmt"
	"io/ioutil"
	"strings"
	"sync"

	"github.com/aerokube/selenoid/session"
	"github.com/docker/docker/api/types/container"
	"time"
)

// Session - session id and vnc flaf
type Session struct {
	ID        string       `json:"id"`
	Container string       `json:"container,omitempty"`
	VNC       bool         `json:"vnc"`
	Screen    string       `json:"screen"`
	Caps      session.Caps `json:"caps"`
}

// Sessions - used count and individual sessions for quota user
type Sessions struct {
	Count    int       `json:"count"`
	Sessions []Session `json:"sessions"`
}

// Quota - list of sessions for quota user
type Quota map[string]*Sessions

// Version - browser version for quota
type Version map[string]Quota

// Browsers - browser names for versions
type Browsers map[string]Version

// State - current state
type State struct {
	Total    int      `json:"total"`
	Used     int      `json:"used"`
	Queued   int      `json:"queued"`
	Pending  int      `json:"pending"`
	Browsers Browsers `json:"browsers"`
}

// Browser configuration
type Browser struct {
	Image   interface{}       `json:"image"`
	Port    string            `json:"port"`
	Path    string            `json:"path"`
	Tmpfs   map[string]string `json:"tmpfs,omitempty"`
	Volumes []string          `json:"volumes,omitempty"`
	Env     []string          `json:"env,omitempty"`
	Hosts   []string          `json:"env,hosts"`
	ShmSize int64             `json:"shmSize,omitempty"`
}

// Versions configuration
type Versions struct {
	Default  string              `json:"default"`
	Versions map[string]*Browser `json:"versions"`
}

// Config current configuration
type Config struct {
	lock           sync.RWMutex
	LastReloadTime time.Time
	Browsers       map[string]Versions
	ContainerLogs  *container.LogConfig
}

// NewConfig creates new config
func NewConfig() *Config {
	return &Config{Browsers: make(map[string]Versions), ContainerLogs: new(container.LogConfig), LastReloadTime: time.Now()}
}

func loadJSON(filename string, v interface{}) error {
	buf, err := ioutil.ReadFile(filename)
	if err != nil {
		return fmt.Errorf("read error: %v", err)
	}
	if err := json.Unmarshal(buf, v); err != nil {
		return fmt.Errorf("parse error: %v", err)
	}
	return nil
}

// Load loads config from file
func (config *Config) Load(browsers, containerLogs string) error {
	log.Println("Loading configuration files...")
	br := make(map[string]Versions)
	err := loadJSON(browsers, &br)
	if err != nil {
		return fmt.Errorf("browsers config: %v", err)
	}
	log.Printf("Loaded configuration from [%s]\n", browsers)
	var cl *container.LogConfig
	err = loadJSON(containerLogs, &cl)
	if err != nil {
		log.Printf("Using default containers log configuration because of: %v\n", err)
		cl = &container.LogConfig{}
	} else {
		log.Printf("Loaded configuration from [%s]\n", containerLogs)
	}
	config.lock.Lock()
	defer config.lock.Unlock()
	config.Browsers, config.ContainerLogs = br, cl
	config.LastReloadTime = time.Now()
	return nil
}

// Find - find concrete browser
func (config *Config) Find(name string, version string) (*Browser, string, bool) {
	config.lock.RLock()
	defer config.lock.RUnlock()
	browser, ok := config.Browsers[name]
	if !ok {
		return nil, "", false
	}
	if version == "" {
		log.Println("Using default version:", browser.Default)
		version = browser.Default
		if version == "" {
			return nil, "", false
		}
	}
	for v, b := range browser.Versions {
		if strings.HasPrefix(v, version) {
			return b, v, true
		}
	}
	return nil, version, false
}

// State - get current state
func (config *Config) State(sessions *session.Map, limit, queued, pending int) *State {
	config.lock.RLock()
	defer config.lock.RUnlock()
	state := &State{limit, 0, queued, pending, make(Browsers)}
	for n, b := range config.Browsers {
		state.Browsers[n] = make(Version)
		for v := range b.Versions {
			state.Browsers[n][v] = make(Quota)
		}
	}
	sessions.Each(func(id string, session *session.Session) {
		state.Used++
		browserName := session.Caps.Name
		version := session.Caps.Version
		_, ok := state.Browsers[browserName]
		if !ok {
			state.Browsers[browserName] = make(Version)
		}
		_, ok = state.Browsers[browserName][version]
		if !ok {
			state.Browsers[browserName][version] = make(Quota)
		}
		v, ok := state.Browsers[browserName][version][session.Quota]
		if !ok {
			v = &Sessions{0, []Session{}}
			state.Browsers[browserName][version][session.Quota] = v
		}
		v.Count++
		vnc := false
		if session.VNC != "" {
			vnc = true
		}
		v.Sessions = append(v.Sessions, Session{
			ID:        id,
			Container: session.Container,
			VNC:       vnc,
			Screen:    session.Caps.ScreenResolution,
			Caps:      session.Caps,
		})
	})
	return state
}
<commit_msg>Fixed issue in config struct<commit_after>package config

import (
	"log"

	"encoding/json"
	"fmt"
	"io/ioutil"
	"strings"
	"sync"

	"github.com/aerokube/selenoid/session"
	"github.com/docker/docker/api/types/container"
	"time"
)

// Session - session id and vnc flaf
type Session struct {
	ID        string       `json:"id"`
	Container string       `json:"container,omitempty"`
	VNC       bool         `json:"vnc"`
	Screen    string       `json:"screen"`
	Caps      session.Caps `json:"caps"`
}

// Sessions - used count and individual sessions for quota user
type Sessions struct {
	Count    int       `json:"count"`
	Sessions []Session `json:"sessions"`
}

// Quota - list of sessions for quota user
type Quota map[string]*Sessions

// Version - browser version for quota
type Version map[string]Quota

// Browsers - browser names for versions
type Browsers map[string]Version

// State - current state
type State struct {
	Total    int      `json:"total"`
	Used     int      `json:"used"`
	Queued   int      `json:"queued"`
	Pending  int      `json:"pending"`
	Browsers Browsers `json:"browsers"`
}

// Browser configuration
type Browser struct {
	Image   interface{}       `json:"image"`
	Port    string            `json:"port"`
	Path    string            `json:"path"`
	Tmpfs   map[string]string `json:"tmpfs,omitempty"`
	Volumes []string          `json:"volumes,omitempty"`
	Env     []string          `json:"env,omitempty"`
	Hosts   []string          `json:"hosts,omitempty"`
	ShmSize int64             `json:"shmSize,omitempty"`
}

// Versions configuration
type Versions struct {
	Default  string              `json:"default"`
	Versions map[string]*Browser `json:"versions"`
}

// Config current configuration
type Config struct {
	lock           sync.RWMutex
	LastReloadTime time.Time
	Browsers       map[string]Versions
	ContainerLogs  *container.LogConfig
}

// NewConfig creates new config
func NewConfig() *Config {
	return &Config{Browsers: make(map[string]Versions), ContainerLogs: new(container.LogConfig), LastReloadTime: time.Now()}
}

func loadJSON(filename string, v interface{}) error {
	buf, err := ioutil.ReadFile(filename)
	if err != nil {
		return fmt.Errorf("read error: %v", err)
	}
	if err := json.Unmarshal(buf, v); err != nil {
		return fmt.Errorf("parse error: %v", err)
	}
	return nil
}

// Load loads config from file
func (config *Config) Load(browsers, containerLogs string) error {
	log.Println("Loading configuration files...")
	br := make(map[string]Versions)
	err := loadJSON(browsers, &br)
	if err != nil {
		return fmt.Errorf("browsers config: %v", err)
	}
	log.Printf("Loaded configuration from [%s]\n", browsers)
	var cl *container.LogConfig
	err = loadJSON(containerLogs, &cl)
	if err != nil {
		log.Printf("Using default containers log configuration because of: %v\n", err)
		cl = &container.LogConfig{}
	} else {
		log.Printf("Loaded configuration from [%s]\n", containerLogs)
	}
	config.lock.Lock()
	defer config.lock.Unlock()
	config.Browsers, config.ContainerLogs = br, cl
	config.LastReloadTime = time.Now()
	return nil
}

// Find - find concrete browser
func (config *Config) Find(name string, version string) (*Browser, string, bool) {
	config.lock.RLock()
	defer config.lock.RUnlock()
	browser, ok := config.Browsers[name]
	if !ok {
		return nil, "", false
	}
	if version == "" {
		log.Println("Using default version:", browser.Default)
		version = browser.Default
		if version == "" {
			return nil, "", false
		}
	}
	for v, b := range browser.Versions {
		if strings.HasPrefix(v, version) {
			return b, v, true
		}
	}
	return nil, version, false
}

// State - get current state
func (config *Config) State(sessions *session.Map, limit, queued, pending int) *State {
	config.lock.RLock()
	defer config.lock.RUnlock()
	state := &State{limit, 0, queued, pending, make(Browsers)}
	for n, b := range config.Browsers {
		state.Browsers[n] = make(Version)
		for v := range b.Versions {
			state.Browsers[n][v] = make(Quota)
		}
	}
	sessions.Each(func(id string, session *session.Session) {
		state.Used++
		browserName := session.Caps.Name
		version := session.Caps.Version
		_, ok := state.Browsers[browserName]
		if !ok {
			state.Browsers[browserName] = make(Version)
		}
		_, ok = state.Browsers[browserName][version]
		if !ok {
			state.Browsers[browserName][version] = make(Quota)
		}
		v, ok := state.Browsers[browserName][version][session.Quota]
		if !ok {
			v = &Sessions{0, []Session{}}
			state.Browsers[browserName][version][session.Quota] = v
		}
		v.Count++
		vnc := false
		if session.VNC != "" {
			vnc = true
		}
		v.Sessions = append(v.Sessions, Session{
			ID:        id,
			Container: session.Container,
			VNC:       vnc,
			Screen:    session.Caps.ScreenResolution,
			Caps:      session.Caps,
		})
	})
	return state
}
<|endoftext|>


<commit_before>package config

import (
	"flag"
	"fmt"
	"gopkg.in/yaml.v2"
	"io/ioutil"
	"os"
	"path"
)

// 自动加载配置项
type ConfigInfo struct {
	Server   *serverModel   `yaml:"server"`
	Wechat   *wechatModel   `yaml:"wechat"`
	DataBase *dataBaseModel `yaml:"database"`
	MQ       *mqModel       `yaml:"mq"`
	Email    *emailModel    `yaml:"email"`
}

// 服务器配置项
type serverModel struct {
	Mode string `yaml:"mode"` // run mode
	Host string `yaml:"host"` // server host
	Port string `yaml:"port"` // server port
}

// 微信配置项
type wechatModel struct {
	AppID     string `yaml:"appID"`
	AppSecret string `yaml:"appSecret"`
}

// 数据库配置项
type dataBaseModel struct {
	Host     string `yaml:"host"`
	Port     string `yaml:"port"`
	Username string `yaml:"username"`
	Password string `yaml:"password"`
	Dbname   string `yaml:"dbname"`
	Dburl    string `yaml:"dburl"`
}

// 消息队列配置项
type mqModel struct {
	Host     string `yaml:"host"`
	Port     string `yaml:"port"`
	Username string `yaml:"username"`
	Password string `yaml:"password"`
}

// 邮箱服务配置
type emailModel struct {
	Host     string `yaml:"host"`
	Port     string `yaml:"port"`
	User     string `yaml:"user"`
	Password string `yaml:"password"`
}

//
var Config ConfigInfo

// 加载配置
func loadConfigInformation(fPath string) error {
	filePath := path.Join(fPath, "config.yaml")
	configData, err := ioutil.ReadFile(filePath)
	if err != nil {
		fmt.Printf(" config file read failed: %s", err)
		os.Exit(-1)
		return err
	}
	err = yaml.Unmarshal(configData, &Config)
	if err != nil {
		fmt.Printf(" config parse failed: %s", err)
		return err
	}
	return nil
}

func LoadConfig() {
	var err error
	fPath, _ := os.Getwd()
	fPath = path.Join(fPath, "config")
	configPath := flag.String("c", fPath, "config file path")
	flag.Parse()
	err = loadConfigInformation(*configPath)
	// fmt.Printf("%+v\n%+v",Config.Server, Config.Wechat)
	if err != nil {
		return
	}
}
<commit_msg>mq url add new field<commit_after>package config

import (
	"flag"
	"fmt"
	"gopkg.in/yaml.v2"
	"io/ioutil"
	"os"
	"path"
)

// 自动加载配置项
type ConfigInfo struct {
	Server   *serverModel   `yaml:"server"`
	Wechat   *wechatModel   `yaml:"wechat"`
	DataBase *dataBaseModel `yaml:"database"`
	MQ       *mqModel       `yaml:"mq"`
	Email    *emailModel    `yaml:"email"`
}

// 服务器配置项
type serverModel struct {
	Mode string `yaml:"mode"` // run mode
	Host string `yaml:"host"` // server host
	Port string `yaml:"port"` // server port
}

// 微信配置项
type wechatModel struct {
	AppID     string `yaml:"appID"`
	AppSecret string `yaml:"appSecret"`
}

// 数据库配置项
type dataBaseModel struct {
	Dburl    string `yaml:"dburl"`
	Host     string `yaml:"host"`
	Port     string `yaml:"port"`
	Username string `yaml:"username"`
	Password string `yaml:"password"`
	Dbname   string `yaml:"dbname"`
}

// 消息队列配置项
type mqModel struct {
	MqUrl    string `yaml:"mqurl"`
	Host     string `yaml:"host"`
	Port     string `yaml:"port"`
	Username string `yaml:"username"`
	Password string `yaml:"password"`
}

// 邮箱服务配置
type emailModel struct {
	Host     string `yaml:"host"`
	Port     string `yaml:"port"`
	User     string `yaml:"user"`
	Password string `yaml:"password"`
}

//
var Config ConfigInfo

// 加载配置
func loadConfigInformation(fPath string) error {
	filePath := path.Join(fPath, "config.yaml")
	configData, err := ioutil.ReadFile(filePath)
	if err != nil {
		fmt.Printf(" config file read failed: %s", err)
		os.Exit(-1)
		return err
	}
	err = yaml.Unmarshal(configData, &Config)
	if err != nil {
		fmt.Printf(" config parse failed: %s", err)
		return err
	}
	return nil
}

func LoadConfig() {
	var err error
	fPath, _ := os.Getwd()
	fPath = path.Join(fPath, "config")
	configPath := flag.String("c", fPath, "config file path")
	flag.Parse()
	err = loadConfigInformation(*configPath)
	// fmt.Printf("%+v\n%+v",Config.Server, Config.Wechat)
	if err != nil {
		return
	}
}
<|endoftext|>


<commit_before>package somaproto

type ProtoRequestMode struct {
	Mode *ProtoMode `json:"predicate,omitempty"`
}

type ProtoResultMode struct {
	Code   uint16      `json:"code,omitempty"`
	Status string      `json:"status,omitempty"`
	Text   []string    `json:"text,omitempty"`
	Modes  []ProtoMode `json:"predicates,omitempty"`
	JobId  string      `json:"jobid,omitempty"`
}

type ProtoMode struct {
	Mode    string            `json:"predicate,omitempty"`
	Details *ProtoModeDetails `json:"details,omitempty"`
}

type ProtoModeDetails struct {
	CreatedAt string `json:"createdat,omitempty"`
	CreatedBy string `json:"createdby,omitempty"`
}

//
func (p *ProtoResultMode) ErrorMark(err error, imp bool, found bool,
	length int, jobid string) bool {
	if p.markError(err) {
		return true
	}
	if p.markImplemented(imp) {
		return true
	}
	if p.markFound(found, length) {
		return true
	}
	if p.hasJobId(jobid) {
		return p.markAccepted()
	}
	return p.markOk()
}

func (p *ProtoResultMode) markError(err error) bool {
	if err != nil {
		p.Code = 500
		p.Status = "ERROR"
		p.Text = []string{err.Error()}
		return true
	}
	return false
}

func (p *ProtoResultMode) markImplemented(f bool) bool {
	if f {
		p.Code = 501
		p.Status = "NOT IMPLEMENTED"
		return true
	}
	return false
}

func (p *ProtoResultMode) markFound(f bool, i int) bool {
	if f || i == 0 {
		p.Code = 404
		p.Status = "NOT FOUND"
		return true
	}
	return false
}

func (p *ProtoResultMode) markOk() bool {
	p.Code = 200
	p.Status = "OK"
	return false
}

func (p *ProtoResultMode) hasJobId(s string) bool {
	if s != "" {
		p.JobId = s
		return true
	}
	return false
}

func (p *ProtoResultMode) markAccepted() bool {
	p.Code = 202
	p.Status = "ACCEPTED"
	return false
}

// vim: ts=4 sw=4 sts=4 noet fenc=utf-8 ffs=unix
<commit_msg>Fix json for modes<commit_after>package somaproto

type ProtoRequestMode struct {
	Mode *ProtoMode `json:"mode,omitempty"`
}

type ProtoResultMode struct {
	Code   uint16      `json:"code,omitempty"`
	Status string      `json:"status,omitempty"`
	Text   []string    `json:"text,omitempty"`
	Modes  []ProtoMode `json:"modes,omitempty"`
	JobId  string      `json:"jobid,omitempty"`
}

type ProtoMode struct {
	Mode    string            `json:"mode,omitempty"`
	Details *ProtoModeDetails `json:"details,omitempty"`
}

type ProtoModeDetails struct {
	CreatedAt string `json:"createdat,omitempty"`
	CreatedBy string `json:"createdby,omitempty"`
}

//
func (p *ProtoResultMode) ErrorMark(err error, imp bool, found bool,
	length int, jobid string) bool {
	if p.markError(err) {
		return true
	}
	if p.markImplemented(imp) {
		return true
	}
	if p.markFound(found, length) {
		return true
	}
	if p.hasJobId(jobid) {
		return p.markAccepted()
	}
	return p.markOk()
}

func (p *ProtoResultMode) markError(err error) bool {
	if err != nil {
		p.Code = 500
		p.Status = "ERROR"
		p.Text = []string{err.Error()}
		return true
	}
	return false
}

func (p *ProtoResultMode) markImplemented(f bool) bool {
	if f {
		p.Code = 501
		p.Status = "NOT IMPLEMENTED"
		return true
	}
	return false
}

func (p *ProtoResultMode) markFound(f bool, i int) bool {
	if f || i == 0 {
		p.Code = 404
		p.Status = "NOT FOUND"
		return true
	}
	return false
}

func (p *ProtoResultMode) markOk() bool {
	p.Code = 200
	p.Status = "OK"
	return false
}

func (p *ProtoResultMode) hasJobId(s string) bool {
	if s != "" {
		p.JobId = s
		return true
	}
	return false
}

func (p *ProtoResultMode) markAccepted() bool {
	p.Code = 202
	p.Status = "ACCEPTED"
	return false
}

// vim: ts=4 sw=4 sts=4 noet fenc=utf-8 ffs=unix
<|endoftext|>


<commit_before>package gown

import (
    "bufio"
    "fmt"
    "io"
    "os"
    "path/filepath"
    "strings"
)

var (
    suffixReplacements = []map[string][]string {
        // noun
        map[string][]string {
            "s": []string { "" },
            "ses": []string { "s" },
            "xes": []string { "x" },
            "zes": []string { "z" },
            "ches": []string { "ch" },
            "shes": []string { "sh" },
            "men": []string { "man" },
            "ies": []string { "y" },
        },
        // verb
        map[string][]string {
            "s": []string { "" },
            "ies": []string { "y" },
            "es": []string { "e", "" },
            "ed": []string { "e", "" },
            "ing": []string { "e", "" },

        },
        // adjective
        map[string][]string {
            "er": []string { "", "e" },
            "est": []string { "", "e"},
        },
    }

    addr = [][]string {
        // noun
        []string { "", "s", "x", "z", "ch", "sh", "man", "y" },
        // verb
        []string { "", "y", "e", "", "e", "", "e", "" },
        // adjective
        []string { "", "", "e", "e" },
    }

    prepositions = map[string]struct{} {
        "to": struct{}{},
        "at": struct{}{},
        "of": struct{}{},
        "on": struct{}{},
        "off": struct{}{},
        "in": struct{}{},
        "out": struct{}{},
        "up": struct{}{},
        "down": struct{}{},
        "from": struct{}{},
        "with": struct{}{},
        "into": struct{}{},
        "for": struct{}{},
        "about": struct{}{},
        "between": struct{}{},
    }

    exceptions []map[string]string = []map[string]string {
        map[string]string{},    // noun
        map[string]string{},    // verb
        map[string]string{},    // adjective
        map[string]string{},    // adverb
    }
)

func InitiMorphData(dictDirname string) {
    posNames := []string { "noun", "verb", "adj", "adv" }
    for posIndex, posName := range posNames {
        exceptionFilename := dictDirname + string(filepath.Separator) + posName + ".exc"
        infile, err := os.Open(exceptionFilename)
        if err != nil {
            panic(fmt.Sprintf("Can't open morph exception file %s: %v", exceptionFilename, err))
        }
        r := bufio.NewReader(infile)
        if (r == nil) {
            panic(fmt.Sprintf("Can't open morph exception file %s: %v" + exceptionFilename, err))
        }

        var readerr error = nil
        for ; readerr == nil ; {
            bytebuf, readerr := r.ReadBytes('\n')
            if readerr != nil && readerr != io.EOF {
                panic(readerr)
            }
            if len(bytebuf) == 0 {
                break;
            }
            fields := strings.SplitN(strings.TrimSpace(string(bytebuf)), " ", -1)
            derivedForm := strings.Replace(fields[0], "_", " ", -1)
            baseForm := strings.Replace(fields[1], "_", " ", -1)
            exceptions[posIndex][derivedForm] = baseForm
        }
        infile.Close()
    }
}

// Returns a set of lemmatizations for the word. We assume the word is in the
// raw form. (i.e. spaces are spaces, not '_')
func Morph(origword string, partOfSpeech int) []string {
    partOfSpeechIndex := getPosIndex(partOfSpeech)
    if partOfSpeechIndex < 0  {
        // no idea, it's not a supported part of speech
        return []string { origword }
    }

    // check the exception lists
    lemma, exists := exceptions[partOfSpeechIndex][origword]
    if exists {
        return []string{ lemma }
    }

    if partOfSpeech == POS_VERB {
        toks := strings.Split(" ", origword)
        ending := ""
        if len(toks) > 1 {
            ending = " " + strings.Join(toks[1:], " ")
        }
        results := []string{}
        for _, lemma := range findLemmas(toks[0], partOfSpeech) {
            results = append(results, lemma + ending)
        }
        return results
    } else {
        return morphword(origword, partOfSpeech)
    }
}

func morphword(origword string, partOfSpeech int) []string {
    lemmas := []string{}
    partOfSpeechIndex := getPosIndex(partOfSpeech)
    exception, exists := exceptions[partOfSpeechIndex][origword]
    if exists {
        lemmas = append(lemmas, exception)
    }

    if partOfSpeech == POS_ADVERB {
         // skip it
        if len(lemmas) == 0 {
            return []string { origword }
        } else {
            return lemmas
        }
    } else if partOfSpeech == POS_NOUN {
        if strings.HasSuffix(origword, "ful") {
            origword = origword[:len(origword) - 3]
        } else {
            if strings.HasSuffix(origword, "ss") || len(origword) <= 2 {
                return []string { origword }
            }
        }
    }

    return append(lemmas, findLemmas(origword, partOfSpeech)...)
}

func getPosIndex(partOfSpeech int) int {
    if partOfSpeech == POS_ADJECTIVE_SATELLITE {
        partOfSpeech = POS_ADJECTIVE
    }
    return partOfSpeech - 1
}

func findLemmas(origword string, partOfSpeech int) []string {
    partOfSpeechIndex := getPosIndex(partOfSpeech)
    exception, exists := exceptions[partOfSpeechIndex][origword]
    if exists {
        return []string { exception }
    } else {
        lemmas := []string{}
        wordlen := len(origword)
        for lastIndex := 1; lastIndex <= 4; lastIndex++ {
            if (wordlen - lastIndex) > 0 {
                suffix := origword[lastIndex:]
                replacements, suffixFound := suffixReplacements[partOfSpeechIndex][suffix]
                if suffixFound {
                    prefix := origword[:lastIndex]
                    for _, replace := range replacements {
                        lemmas = append(lemmas, prefix + replace)
                    }
                }
            } else {
                // not enough letters
                break
            }
        }

        if len(lemmas) == 0 {
            return []string { origword }
        } else {
            return lemmas
        }
    }
}
<commit_msg>my own morph<commit_after>package gown

import (
    "bufio"
    "fmt"
    "io"
    "os"
    "path/filepath"
    "strings"
)

var (
    suffixReplacements = []map[string][]string {
        // noun
        map[string][]string {
            "s": []string { "" },
            "ses": []string { "s" },
            "xes": []string { "x" },
            "zes": []string { "z" },
            "ches": []string { "ch" },
            "shes": []string { "sh" },
            "men": []string { "man" },
            "ies": []string { "y" },
        },
        // verb
        map[string][]string {
            "s": []string { "" },
            "ies": []string { "y" },
            "es": []string { "e", "" },
            "ed": []string { "e", "" },
            "ing": []string { "e", "" },

        },
        // adjective
        map[string][]string {
            "er": []string { "", "e" },
            "est": []string { "", "e"},
        },
    }

    exceptions []map[string]string = []map[string]string {
        map[string]string{},    // noun
        map[string]string{},    // verb
        map[string]string{},    // adjective
        map[string]string{},    // adverb
    }
)

func InitiMorphData(dictDirname string) {
    posNames := []string { "noun", "verb", "adj", "adv" }
    for posIndex, posName := range posNames {
        exceptionFilename := dictDirname + string(filepath.Separator) + posName + ".exc"
        infile, err := os.Open(exceptionFilename)
        if err != nil {
            panic(fmt.Sprintf("Can't open morph exception file %s: %v", exceptionFilename, err))
        }
        r := bufio.NewReader(infile)
        if (r == nil) {
            panic(fmt.Sprintf("Can't open morph exception file %s: %v" + exceptionFilename, err))
        }

        var readerr error = nil
        for ; readerr == nil ; {
            bytebuf, readerr := r.ReadBytes('\n')
            if readerr != nil && readerr != io.EOF {
                panic(readerr)
            }
            if len(bytebuf) == 0 {
                break;
            }
            fields := strings.SplitN(strings.TrimSpace(string(bytebuf)), " ", -1)
            derivedForm := strings.Replace(fields[0], "_", " ", -1)
            baseForm := strings.Replace(fields[1], "_", " ", -1)
            exceptions[posIndex][derivedForm] = baseForm
        }
        infile.Close()
    }
}

// Returns a lemmatizations for the word. We assume the word is in the
// raw form. (i.e. spaces are spaces, not '_') This algorithim is similar to,
// but not exactly the same as the Wordnet Morphy algorithm.
func (wn *WN) Morph(origword string, partOfSpeech int) string {
    partOfSpeechIndex := getPosIndex(partOfSpeech)
    if partOfSpeechIndex < 0  {
        // no idea, it's not a supported part of speech
        return origword
    }

    // check the exception lists
    lemma, exists := exceptions[partOfSpeechIndex][origword]
    if exists {
        return lemma
    } else {
        lemma = origword
    }

    if partOfSpeech == POS_ADVERB {
        // only use the exception lists for adverbs
        return origword
    } else {
        // replace the suffxes
        if partOfSpeech == POS_NOUN {
            if strings.HasSuffix(origword, "ful") {
                origword = origword[:len(origword) - 3]
            } else {
                if strings.HasSuffix(origword, "ss") || len(origword) <= 2 {
                    // too small
                    return origword
                }
            }
        }

        for i := 1; i <= 4; i++ {
            suffixIndex := len(origword) - i

            if suffixIndex <= 0 {
                break;
            }

            baseword := origword[:suffixIndex]
            suffix := origword[suffixIndex:]
            replacements, found := suffixReplacements[partOfSpeechIndex][suffix]
            if found {
                for _, replacement := range replacements {
                    possibleLemma := baseword + replacement
                    resp := wn.Lookup(possibleLemma)
                    if len(resp) > 0 {
                        // found it!
                        return possibleLemma
                    }
                }
            }
        }

        return origword
    }
}

func getPosIndex(pos int) int {
    if pos == POS_ADJECTIVE_SATELLITE {
        pos = POS_ADJECTIVE
    }
    return pos - 1
}
<|endoftext|>


<commit_before>package build

import (
	"bytes"

	"github.com/stellar/go-stellar-base"
	"github.com/stellar/go-stellar-base/xdr"
)

// Transaction groups the creation of a new TransactionBuilder with a call
// to Mutate.
func Transaction(muts ...TransactionMutator) (result TransactionBuilder) {
	result.Mutate(Defaults{})
	for _, m := range muts {
		m.MutateTransaction(&result.TX)
	}
	return
}

// TransactionMutator is a interface that wraps the
// MutateTransaction operation.  types may implement this interface to
// specify how they modify an xdr.Transaction object
type TransactionMutator interface {
	MutateTransaction(*xdr.Transaction) error
}

// TransactionBuilder represents a Transaction that is being constructed.
type TransactionBuilder struct {
	TX  xdr.Transaction
	Err error
}

// Mutate applies the provided TransactionMutators to this builder's transaction
func (b *TransactionBuilder) Mutate(muts ...TransactionMutator) {
	for _, m := range muts {
		err := m.MutateTransaction(&b.TX)
		if err != nil {
			b.Err = err
			return
		}
	}
}

// Hash returns the hash of this builder's transaction.
func (b *TransactionBuilder) Hash() ([32]byte, error) {
	var txBytes bytes.Buffer
	_, err := xdr.Marshal(&txBytes, b.TX)
	if err != nil {
		return [32]byte{}, err
	}

	return stellarbase.Hash(txBytes.Bytes()), nil
}

// Sign returns an new TransactionEnvelopeBuilder using this builder's
// transaction as the basis and with signatures of that transaction from the
// provided Signers.
func (b *TransactionBuilder) Sign(signers ...stellarbase.Signer) (result TransactionEnvelopeBuilder) {
	result.Mutate(*b)

	for _, s := range signers {
		result.Mutate(Sign{s})
	}

	return
}

// MutateTransaction for SourceAccount sets the transaction's SourceAccount
// to the pubilic key for the address provided
func (m Defaults) MutateTransaction(o *xdr.Transaction) error {
	o.Fee = 10
	o.Memo = xdr.NewMemoMemoNone()
	return nil
}

// MutateTransaction for SourceAccount sets the transaction's SourceAccount
// to the pubilic key for the address provided
func (m SourceAccount) MutateTransaction(o *xdr.Transaction) error {
	aid, err := stellarbase.AddressToAccountId(m.Address)
	o.SourceAccount = aid
	return err
}

// MutateTransaction for PaymentBuilder causes the underylying PaymentOp
// to be added to the operation list for the provided transaction
func (m PaymentBuilder) MutateTransaction(o *xdr.Transaction) error {
	if m.Err != nil {
		return m.Err
	}

	m.O.Body = xdr.NewOperationBodyPayment(m.P)
	o.Operations = append(o.Operations, m.O)
	return nil
}

// MutateTransaction for CreateAccountBuilder causes the underylying
// CreateAccountOp to be added to the operation list for the provided
// transaction
func (m CreateAccountBuilder) MutateTransaction(o *xdr.Transaction) error {
	if m.Err != nil {
		return m.Err
	}

	m.O.Body = xdr.NewOperationBodyCreateAccount(m.CA)
	o.Operations = append(o.Operations, m.O)
	return nil
}

// MutateTransaction for Sequence sets the SeqNum on the transaction.
func (m Sequence) MutateTransaction(o *xdr.Transaction) error {
	o.SeqNum = xdr.SequenceNumber(m.Sequence)
	return nil
}
<commit_msg>Add HashHex helper<commit_after>package build

import (
	"bytes"
	"encoding/hex"

	"github.com/stellar/go-stellar-base"
	"github.com/stellar/go-stellar-base/xdr"
)

// Transaction groups the creation of a new TransactionBuilder with a call
// to Mutate.
func Transaction(muts ...TransactionMutator) (result TransactionBuilder) {
	result.Mutate(Defaults{})
	for _, m := range muts {
		m.MutateTransaction(&result.TX)
	}
	return
}

// TransactionMutator is a interface that wraps the
// MutateTransaction operation.  types may implement this interface to
// specify how they modify an xdr.Transaction object
type TransactionMutator interface {
	MutateTransaction(*xdr.Transaction) error
}

// TransactionBuilder represents a Transaction that is being constructed.
type TransactionBuilder struct {
	TX  xdr.Transaction
	Err error
}

// Mutate applies the provided TransactionMutators to this builder's transaction
func (b *TransactionBuilder) Mutate(muts ...TransactionMutator) {
	for _, m := range muts {
		err := m.MutateTransaction(&b.TX)
		if err != nil {
			b.Err = err
			return
		}
	}
}

// Hash returns the hash of this builder's transaction.
func (b *TransactionBuilder) Hash() ([32]byte, error) {
	var txBytes bytes.Buffer
	_, err := xdr.Marshal(&txBytes, b.TX)
	if err != nil {
		return [32]byte{}, err
	}

	return stellarbase.Hash(txBytes.Bytes()), nil
}

// HashHex returns the hex-encoded hash of this builder's transaction
func (b *TransactionBuilder) HashHex() (string, error) {
	hash, err := b.Hash()
	if err != nil {
		return "", err
	}

	return hex.EncodeToString(hash[:]), nil
}

// Sign returns an new TransactionEnvelopeBuilder using this builder's
// transaction as the basis and with signatures of that transaction from the
// provided Signers.
func (b *TransactionBuilder) Sign(signers ...stellarbase.Signer) (result TransactionEnvelopeBuilder) {
	result.Mutate(*b)

	for _, s := range signers {
		result.Mutate(Sign{s})
	}

	return
}

// MutateTransaction for SourceAccount sets the transaction's SourceAccount
// to the pubilic key for the address provided
func (m Defaults) MutateTransaction(o *xdr.Transaction) error {
	o.Fee = 10
	o.Memo = xdr.NewMemoMemoNone()
	return nil
}

// MutateTransaction for SourceAccount sets the transaction's SourceAccount
// to the pubilic key for the address provided
func (m SourceAccount) MutateTransaction(o *xdr.Transaction) error {
	aid, err := stellarbase.AddressToAccountId(m.Address)
	o.SourceAccount = aid
	return err
}

// MutateTransaction for PaymentBuilder causes the underylying PaymentOp
// to be added to the operation list for the provided transaction
func (m PaymentBuilder) MutateTransaction(o *xdr.Transaction) error {
	if m.Err != nil {
		return m.Err
	}

	m.O.Body = xdr.NewOperationBodyPayment(m.P)
	o.Operations = append(o.Operations, m.O)
	return nil
}

// MutateTransaction for CreateAccountBuilder causes the underylying
// CreateAccountOp to be added to the operation list for the provided
// transaction
func (m CreateAccountBuilder) MutateTransaction(o *xdr.Transaction) error {
	if m.Err != nil {
		return m.Err
	}

	m.O.Body = xdr.NewOperationBodyCreateAccount(m.CA)
	o.Operations = append(o.Operations, m.O)
	return nil
}

// MutateTransaction for Sequence sets the SeqNum on the transaction.
func (m Sequence) MutateTransaction(o *xdr.Transaction) error {
	o.SeqNum = xdr.SequenceNumber(m.Sequence)
	return nil
}
<|endoftext|>


<commit_before>/*
Copyright 2020 The Knative Authors

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 metrics

import (
	"context"
	"fmt"
	"os"
	"regexp"
	"strconv"
	"strings"
	"testing"
	"time"

	"io/ioutil"

	"github.com/stretchr/testify/assert"
	corev1 "k8s.io/api/core/v1"
	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes/fake"
	"knative.dev/eventing-kafka/pkg/channel/distributed/common/config"
	"knative.dev/eventing-kafka/pkg/channel/distributed/common/env"
	commontesting "knative.dev/eventing-kafka/pkg/channel/distributed/common/testing"
	"knative.dev/eventing-kafka/pkg/common/constants"
	injectionclient "knative.dev/pkg/client/injection/kube/client"
	logtesting "knative.dev/pkg/logging/testing"
	"knative.dev/pkg/metrics"
	"knative.dev/pkg/system"
)

// Test The MetricsServer's Report() Functionality
func TestMetricsServer_Report(t *testing.T) {

	// Test Data
	metricsPort := 9878
	metricsDomain := "eventing-kafka"
	topicName := "test-topic-name"
	msgCount := 13579

	// Initialize The Environment For The Test
	assert.Nil(t, os.Setenv(system.NamespaceEnvKey, constants.KnativeEventingNamespace))
	assert.Nil(t, os.Setenv(env.MetricsDomainEnvVarKey, metricsDomain))

	// Create An Observability ConfigMap For The InitializeObservability() Call To Watch
	observabilityConfigMap := &corev1.ConfigMap{
		TypeMeta: v1.TypeMeta{
			Kind:       "ConfigMap",
			APIVersion: corev1.SchemeGroupVersion.String(),
		},
		ObjectMeta: v1.ObjectMeta{
			Name:      metrics.ConfigMapName(),
			Namespace: system.Namespace(),
		},
		Data: map[string]string{
			"metrics.backend-destination": "prometheus",
		},
	}

	// Create The Fake K8S Client And Add It To The ConfigMap
	fakeK8sClient := fake.NewSimpleClientset(observabilityConfigMap)

	// Add The Fake K8S Client To The Context (Required By InitializeObservability)
	ctx := context.WithValue(context.TODO(), injectionclient.Key{}, fakeK8sClient)

	// Create A Test Logger
	logger := logtesting.TestLogger(t).Desugar()

	// Initialize The Observability Watcher
	err := config.InitializeObservability(ctx, logger.Sugar(), metricsDomain, metricsPort)
	assert.Nil(t, err)

	// Create A New StatsReporter To Test
	statsReporter := NewStatsReporter(logger)

	// Create The Stats / Metrics To Report
	stats := createTestMetrics(topicName, int64(msgCount))

	// Perform The Test
	statsReporter.Report(stats)

	// Verify The Results By Querying Metrics Endpoint And Parsing Results
	resp, err := commontesting.RetryGet(fmt.Sprintf("http://localhost:%v/metrics", metricsPort), 100*time.Millisecond, 20, 404)
	assert.Nil(t, err)
	body, err := ioutil.ReadAll(resp.Body)
	assert.Nil(t, err)
	err = resp.Body.Close()
	assert.Nil(t, err)
	bodyStrings := strings.Split(string(body), "\n")
	assert.True(t, verifyMetric(bodyStrings, "eventing_kafka_produced_msg_count", topicName, strconv.Itoa(msgCount)))
}

// Utility Function For Creating Sample Test Metrics  (Representative Data From Sarama Metrics Trace - With Custom Test Data)
func createTestMetrics(topic string, count int64) map[string]map[string]interface{} {
	testMetrics := make(map[string]map[string]interface{})
	testMetrics["batch-size"] = map[string]interface{}{"75%": 422, "95%": 422, "99%": 422, "99.9%": 422, "count": 5, "max": 422, "mean": 422, "median": 422, "min": 422, "stddev": 0}
	testMetrics["batch-size-for-topic-"+topic] = map[string]interface{}{"75%": 422, "95%": 422, "99%": 422, "99.9%": 422, "count": 5, "max": 422, "mean": 422, "median": 422, "min": 422, "stddev": 0}
	testMetrics["compression-ratio"] = map[string]interface{}{"75%": 100, "95%": 100, "99%": 100, "99.9%": 100, "count": 5, "max": 100, "mean": 100, "median": 100, "min": 100, "stddev": 0}
	testMetrics["compression-ratio-for-topic-stage_sample-kafka-channel-1"] = map[string]interface{}{"75%": 100, "95%": 100, "99%": 100, "99.9%": 100, "count": 5, "max": 100, "mean": 100, "median": 100, "min": 100, "stddev": 0}
	testMetrics["incoming-byte-rate"] = map[string]interface{}{"15m.rate": 338.48922714325533, "1m.rate": 148.6636907525621, "5m.rate": 300.3520357972228, "count": 2157, "mean.rate": 36.136821927158024}
	testMetrics["incoming-byte-rate-for-broker-0"] = map[string]interface{}{"15m.rate": 57.04287862876796, "1m.rate": 49.81665008593679, "5m.rate": 55.94572447585394, "count": 360, "mean.rate": 26.962040661298193}
	testMetrics["outgoing-byte-rate"] = map[string]interface{}{"15m.rate": 8.542065819239612, "1m.rate": 36.494569810073976, "5m.rate": 13.085405055952117, "count": 2501, "mean.rate": 41.89999208758941}
	testMetrics["outgoing-byte-rate-for-broker-0"] = map[string]interface{}{"15m.rate": 391.3775283696023, "1m.rate": 341.7975714229552, "5m.rate": 383.8498318204423, "count": 2470, "mean.rate": 184.9934008427559}
	testMetrics["record-send-rate"] = map[string]interface{}{"15m.rate": 0.7922622031773328, "1m.rate": 0.6918979178602331, "5m.rate": 0.777023951053527, "count": 5, "mean.rate": 0.3744896470537649}
	testMetrics[RecordSendRateForTopicPrefix+topic] = map[string]interface{}{"15m.rate": 0.7922622031773328, "1m.rate": 0.6918979178602331, "5m.rate": 0.777023951053527, "count": count, "mean.rate": 0.3744894223293246}
	testMetrics["records-per-request"] = map[string]interface{}{"75%": 1, "95%": 1, "99%": 1, "99.9%": 1, "count": 5, "max": 1, "mean": 1, "median": 1, "min": 1, "stddev": 0}
	testMetrics["records-per-request-for-topic-stage_sample-kafka-channel-1"] = map[string]interface{}{"75%": 1, "95%": 1, "99%": 1, "99.9%": 1, "count": 5, "max": 1, "mean": 1, "median": 1, "min": 1, "stddev": 0}
	testMetrics["request-latency-in-ms"] = map[string]interface{}{"75%": 24, "95%": 78, "99%": 78, "99.9%": 78, "count": 6, "max": 78, "mean": 16.666666666666668, "median": 5, "min": 3, "stddev": 27.45096638655105}
	testMetrics["request-latency-in-ms-for-broker-0"] = map[string]interface{}{"75%": 42, "95%": 78, "99%": 78, "99.9%": 78, "count": 5, "max": 78, "mean": 19.4, "median": 5, "min": 3, "stddev": 29.31620712165883}
	testMetrics["request-rate"] = map[string]interface{}{"15m.rate": 0.19362878205360173, "1m.rate": 0.1488272222720787, "5m.rate": 0.1825385339752764, "count": 6, "mean.rate": 0.1005196891551448}
	testMetrics["request-rate-for-broker-0"] = map[string]interface{}{"15m.rate": 0.7922622031773328, "1m.rate": 0.6918979178602331, "5m.rate": 0.777023951053527, "count": 5, "mean.rate": 0.37447298101266696}
	testMetrics["request-size"] = map[string]interface{}{"75%": 494, "95%": 494, "99%": 494, "99.9%": 494, "count": 6, "max": 494, "mean": 416.8333333333333, "median": 494, "min": 31, "stddev": 172.54991226373375}
	testMetrics["request-size-for-broker-0"] = map[string]interface{}{"75%": 494, "95%": 494, "99%": 494, "99.9%": 494, "count": 5, "max": 494, "mean": 494, "median": 494, "min": 494, "stddev": 0}
	testMetrics["response-rate"] = map[string]interface{}{"15m.rate": 0.19362878205360173, "1m.rate": 0.1488272222720787, "5m.rate": 0.1825385339752764, "count": 6, "mean.rate": 0.10051977925613151}
	testMetrics["response-rate-for-broker-0"] = map[string]interface{}{"15m.rate": 0.7922622031773328, "1m.rate": 0.6918979178602331, "5m.rate": 0.777023951053527, "count": 5, "mean.rate": 0.3744806601376294}
	testMetrics["response-size"] = map[string]interface{}{"75%": 503.25, "95%": 1797, "99%": 1797, "99.9%": 1797, "count": 6, "max": 1797, "mean": 359.5, "median": 72, "min": 72, "stddev": 642.8695435311895}
	testMetrics["response-size-for-broker-0"] = map[string]interface{}{"75%": 72, "95%": 72, "99%": 72, "99.9%": 72, "count": 5, "max": 72, "mean": 72, "median": 72, "min": 72, "stddev": 0}
	return testMetrics
}

// Verifies that the metrics response string slice contains the desired values
// This is test code so a quick regex check will suffice rather than parsing the Prometheus output in a more structured manner
func verifyMetric(body []string, name string, topicName string, expectedValue string) bool {
	for _, line := range body {
		if isMatch(line, fmt.Sprintf(`^%s`, name)) &&
			isMatch(line, fmt.Sprintf(`topic="%s"`, topicName)) &&
			isMatch(line, fmt.Sprintf(` %s$`, expectedValue)) {
			return true
		}
	}
	return false
}

// Simple regex match that treats errors as false, for testing only
func isMatch(source string, regex string) bool {
	match, err := regexp.MatchString(regex, source)
	if err != nil {
		return false
	}
	return match
}
<commit_msg>Skipping a flaky test (#228)<commit_after>/*
Copyright 2020 The Knative Authors

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 metrics

import (
	"context"
	"fmt"
	"os"
	"regexp"
	"strconv"
	"strings"
	"testing"
	"time"

	"io/ioutil"

	"github.com/stretchr/testify/assert"
	corev1 "k8s.io/api/core/v1"
	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes/fake"
	"knative.dev/eventing-kafka/pkg/channel/distributed/common/config"
	"knative.dev/eventing-kafka/pkg/channel/distributed/common/env"
	commontesting "knative.dev/eventing-kafka/pkg/channel/distributed/common/testing"
	"knative.dev/eventing-kafka/pkg/common/constants"
	injectionclient "knative.dev/pkg/client/injection/kube/client"
	logtesting "knative.dev/pkg/logging/testing"
	"knative.dev/pkg/metrics"
	"knative.dev/pkg/system"
)

// Test The MetricsServer's Report() Functionality
func TestMetricsServer_Report(t *testing.T) {
	// see https://github.com/knative-sandbox/eventing-kafka/issues/218
	t.Skip("Flaky test, therefore skipping for now")

	// Test Data
	metricsPort := 9878
	metricsDomain := "eventing-kafka"
	topicName := "test-topic-name"
	msgCount := 13579

	// Initialize The Environment For The Test
	assert.Nil(t, os.Setenv(system.NamespaceEnvKey, constants.KnativeEventingNamespace))
	assert.Nil(t, os.Setenv(env.MetricsDomainEnvVarKey, metricsDomain))

	// Create An Observability ConfigMap For The InitializeObservability() Call To Watch
	observabilityConfigMap := &corev1.ConfigMap{
		TypeMeta: v1.TypeMeta{
			Kind:       "ConfigMap",
			APIVersion: corev1.SchemeGroupVersion.String(),
		},
		ObjectMeta: v1.ObjectMeta{
			Name:      metrics.ConfigMapName(),
			Namespace: system.Namespace(),
		},
		Data: map[string]string{
			"metrics.backend-destination": "prometheus",
		},
	}

	// Create The Fake K8S Client And Add It To The ConfigMap
	fakeK8sClient := fake.NewSimpleClientset(observabilityConfigMap)

	// Add The Fake K8S Client To The Context (Required By InitializeObservability)
	ctx := context.WithValue(context.TODO(), injectionclient.Key{}, fakeK8sClient)

	// Create A Test Logger
	logger := logtesting.TestLogger(t).Desugar()

	// Initialize The Observability Watcher
	err := config.InitializeObservability(ctx, logger.Sugar(), metricsDomain, metricsPort)
	assert.Nil(t, err)

	// Create A New StatsReporter To Test
	statsReporter := NewStatsReporter(logger)

	// Create The Stats / Metrics To Report
	stats := createTestMetrics(topicName, int64(msgCount))

	// Perform The Test
	statsReporter.Report(stats)

	// Verify The Results By Querying Metrics Endpoint And Parsing Results
	resp, err := commontesting.RetryGet(fmt.Sprintf("http://localhost:%v/metrics", metricsPort), 100*time.Millisecond, 20, 404)
	assert.Nil(t, err)
	body, err := ioutil.ReadAll(resp.Body)
	assert.Nil(t, err)
	err = resp.Body.Close()
	assert.Nil(t, err)
	bodyStrings := strings.Split(string(body), "\n")
	assert.True(t, verifyMetric(bodyStrings, "eventing_kafka_produced_msg_count", topicName, strconv.Itoa(msgCount)))
}

// Utility Function For Creating Sample Test Metrics  (Representative Data From Sarama Metrics Trace - With Custom Test Data)
func createTestMetrics(topic string, count int64) map[string]map[string]interface{} {
	testMetrics := make(map[string]map[string]interface{})
	testMetrics["batch-size"] = map[string]interface{}{"75%": 422, "95%": 422, "99%": 422, "99.9%": 422, "count": 5, "max": 422, "mean": 422, "median": 422, "min": 422, "stddev": 0}
	testMetrics["batch-size-for-topic-"+topic] = map[string]interface{}{"75%": 422, "95%": 422, "99%": 422, "99.9%": 422, "count": 5, "max": 422, "mean": 422, "median": 422, "min": 422, "stddev": 0}
	testMetrics["compression-ratio"] = map[string]interface{}{"75%": 100, "95%": 100, "99%": 100, "99.9%": 100, "count": 5, "max": 100, "mean": 100, "median": 100, "min": 100, "stddev": 0}
	testMetrics["compression-ratio-for-topic-stage_sample-kafka-channel-1"] = map[string]interface{}{"75%": 100, "95%": 100, "99%": 100, "99.9%": 100, "count": 5, "max": 100, "mean": 100, "median": 100, "min": 100, "stddev": 0}
	testMetrics["incoming-byte-rate"] = map[string]interface{}{"15m.rate": 338.48922714325533, "1m.rate": 148.6636907525621, "5m.rate": 300.3520357972228, "count": 2157, "mean.rate": 36.136821927158024}
	testMetrics["incoming-byte-rate-for-broker-0"] = map[string]interface{}{"15m.rate": 57.04287862876796, "1m.rate": 49.81665008593679, "5m.rate": 55.94572447585394, "count": 360, "mean.rate": 26.962040661298193}
	testMetrics["outgoing-byte-rate"] = map[string]interface{}{"15m.rate": 8.542065819239612, "1m.rate": 36.494569810073976, "5m.rate": 13.085405055952117, "count": 2501, "mean.rate": 41.89999208758941}
	testMetrics["outgoing-byte-rate-for-broker-0"] = map[string]interface{}{"15m.rate": 391.3775283696023, "1m.rate": 341.7975714229552, "5m.rate": 383.8498318204423, "count": 2470, "mean.rate": 184.9934008427559}
	testMetrics["record-send-rate"] = map[string]interface{}{"15m.rate": 0.7922622031773328, "1m.rate": 0.6918979178602331, "5m.rate": 0.777023951053527, "count": 5, "mean.rate": 0.3744896470537649}
	testMetrics[RecordSendRateForTopicPrefix+topic] = map[string]interface{}{"15m.rate": 0.7922622031773328, "1m.rate": 0.6918979178602331, "5m.rate": 0.777023951053527, "count": count, "mean.rate": 0.3744894223293246}
	testMetrics["records-per-request"] = map[string]interface{}{"75%": 1, "95%": 1, "99%": 1, "99.9%": 1, "count": 5, "max": 1, "mean": 1, "median": 1, "min": 1, "stddev": 0}
	testMetrics["records-per-request-for-topic-stage_sample-kafka-channel-1"] = map[string]interface{}{"75%": 1, "95%": 1, "99%": 1, "99.9%": 1, "count": 5, "max": 1, "mean": 1, "median": 1, "min": 1, "stddev": 0}
	testMetrics["request-latency-in-ms"] = map[string]interface{}{"75%": 24, "95%": 78, "99%": 78, "99.9%": 78, "count": 6, "max": 78, "mean": 16.666666666666668, "median": 5, "min": 3, "stddev": 27.45096638655105}
	testMetrics["request-latency-in-ms-for-broker-0"] = map[string]interface{}{"75%": 42, "95%": 78, "99%": 78, "99.9%": 78, "count": 5, "max": 78, "mean": 19.4, "median": 5, "min": 3, "stddev": 29.31620712165883}
	testMetrics["request-rate"] = map[string]interface{}{"15m.rate": 0.19362878205360173, "1m.rate": 0.1488272222720787, "5m.rate": 0.1825385339752764, "count": 6, "mean.rate": 0.1005196891551448}
	testMetrics["request-rate-for-broker-0"] = map[string]interface{}{"15m.rate": 0.7922622031773328, "1m.rate": 0.6918979178602331, "5m.rate": 0.777023951053527, "count": 5, "mean.rate": 0.37447298101266696}
	testMetrics["request-size"] = map[string]interface{}{"75%": 494, "95%": 494, "99%": 494, "99.9%": 494, "count": 6, "max": 494, "mean": 416.8333333333333, "median": 494, "min": 31, "stddev": 172.54991226373375}
	testMetrics["request-size-for-broker-0"] = map[string]interface{}{"75%": 494, "95%": 494, "99%": 494, "99.9%": 494, "count": 5, "max": 494, "mean": 494, "median": 494, "min": 494, "stddev": 0}
	testMetrics["response-rate"] = map[string]interface{}{"15m.rate": 0.19362878205360173, "1m.rate": 0.1488272222720787, "5m.rate": 0.1825385339752764, "count": 6, "mean.rate": 0.10051977925613151}
	testMetrics["response-rate-for-broker-0"] = map[string]interface{}{"15m.rate": 0.7922622031773328, "1m.rate": 0.6918979178602331, "5m.rate": 0.777023951053527, "count": 5, "mean.rate": 0.3744806601376294}
	testMetrics["response-size"] = map[string]interface{}{"75%": 503.25, "95%": 1797, "99%": 1797, "99.9%": 1797, "count": 6, "max": 1797, "mean": 359.5, "median": 72, "min": 72, "stddev": 642.8695435311895}
	testMetrics["response-size-for-broker-0"] = map[string]interface{}{"75%": 72, "95%": 72, "99%": 72, "99.9%": 72, "count": 5, "max": 72, "mean": 72, "median": 72, "min": 72, "stddev": 0}
	return testMetrics
}

// Verifies that the metrics response string slice contains the desired values
// This is test code so a quick regex check will suffice rather than parsing the Prometheus output in a more structured manner
func verifyMetric(body []string, name string, topicName string, expectedValue string) bool {
	for _, line := range body {
		if isMatch(line, fmt.Sprintf(`^%s`, name)) &&
			isMatch(line, fmt.Sprintf(`topic="%s"`, topicName)) &&
			isMatch(line, fmt.Sprintf(` %s$`, expectedValue)) {
			return true
		}
	}
	return false
}

// Simple regex match that treats errors as false, for testing only
func isMatch(source string, regex string) bool {
	match, err := regexp.MatchString(regex, source)
	if err != nil {
		return false
	}
	return match
}
<|endoftext|>


<commit_before><commit_msg>nil checks<commit_after><|endoftext|>


<commit_before>package main

import (
	"flag"
	"io"
	"net/http"
	"os"
	"regexp"
	"strconv"
	"strings"

	"github.com/PuerkitoBio/goquery"
	"github.com/olekukonko/tablewriter"
)

var (
	Board   = flag.String("b", "home-sale", "Specific ptt board")
	Page    = flag.Int("p", 2, "Default pages to fetched")
	Feature = flag.String("f", "hot", "Special features")
)

var (
	BaseUrl = "https://www.ptt.cc/bbs/"
)

func main() {
	flag.Parse()
	fetchMultiPages(*Board, *Page)
}

func fetchSingle(url string, str chan string) {
	resp := fetch(url)
	defer resp.Body.Close()

	doc := getDocument(resp)
	tmp := ""
	doc.Find("div.r-ent").Each(func(i int, s *goquery.Selection) {
		link, _ := s.Find("a").Attr("href")
		title := s.Find("div.title a").Text()
		push := s.Find("span").Text()
		if push == "" {
			push = "X"
		}

		if len(link) != 0 {
			tmp += push + "\t" + title + "\t" + "https://www.ptt.cc" + link + "\n"
		}
	})
	str <- tmp
}

func fetchPages(url string, ch chan int) {
	resp := fetch(url)
	defer resp.Body.Close()

	doc := getDocument(resp)
	href, _ := doc.Find("div.action-bar").Find("a.btn").Eq(3).Attr("href")
	pages, _ := strconv.Atoi(strings.Trim(strings.Split(strings.Split(href, "/")[3], ".")[0], "index"))
	ch <- pages
}

func fetchMultiPages(board string, pre int) {
	ch := make(chan int)
	url := BaseUrl + board + "/index.html"
	go fetchPages(url, ch)
	p := <-ch

	var output string

	var pagesURL = make([]string, pre+1)
	for i := pre; i >= 0; i-- {
		pagesURL[i] = BaseUrl + board + "/index" + strconv.Itoa(p+1-i) + ".html"
		s := make(chan string)
		go fetchSingle(pagesURL[i], s)
		result := <-s
		output += result
	}

	printOutput(output)
}

func printOutput(output string) {
	spaceRex := regexp.MustCompile(`\s+`)
	table := tablewriter.NewWriter(os.Stdout)
	table.SetHeader([]string{"Push", "Title", "URL"})
	table.SetBorder(false)
	table.SetAlignment(tablewriter.ALIGN_LEFT)
	o := [][]string{}

	rows := strings.Split(output, "\n")
	for i := 0; i < len(rows); i++ {
		row := strings.Split(rows[i], "\t") // row[0], row[1], row[2]

		if len(row) == 3 {
			push := row[0]
			title := spaceRex.ReplaceAllString(row[1], "") // remove space to aviod wrong table format
			url := row[2]
			arr := []string{push, title, url}
			o = append(o, arr)
		}
	}

	table.AppendBulk(o)
	table.Render() // Send output
}

func getDocument(resp *http.Response) *goquery.Document {
	r := io.Reader(resp.Body)
	doc, _ := goquery.NewDocumentFromReader(r)
	return doc
}

func fetch(url string) *http.Response {
	resp, _ := http.Get(url)
	return resp
}
<commit_msg>Restore border<commit_after>package main

import (
	"flag"
	"io"
	"net/http"
	"os"
	"regexp"
	"strconv"
	"strings"

	"github.com/PuerkitoBio/goquery"
	"github.com/olekukonko/tablewriter"
)

var (
	Board   = flag.String("b", "home-sale", "Specific ptt board")
	Page    = flag.Int("p", 2, "Default pages to fetched")
	Feature = flag.String("f", "hot", "Special features")
)

var (
	BaseUrl = "https://www.ptt.cc/bbs/"
)

func main() {
	flag.Parse()
	fetchMultiPages(*Board, *Page)
}

func fetchSingle(url string, str chan string) {
	resp := fetch(url)
	defer resp.Body.Close()

	doc := getDocument(resp)
	tmp := ""
	doc.Find("div.r-ent").Each(func(i int, s *goquery.Selection) {
		link, _ := s.Find("a").Attr("href")
		title := s.Find("div.title a").Text()
		push := s.Find("span").Text()
		if push == "" {
			push = "X"
		}

		if len(link) != 0 {
			tmp += push + "\t" + title + "\t" + "https://www.ptt.cc" + link + "\n"
		}
	})
	str <- tmp
}

func fetchPages(url string, ch chan int) {
	resp := fetch(url)
	defer resp.Body.Close()

	doc := getDocument(resp)
	href, _ := doc.Find("div.action-bar").Find("a.btn").Eq(3).Attr("href")
	pages, _ := strconv.Atoi(strings.Trim(strings.Split(strings.Split(href, "/")[3], ".")[0], "index"))
	ch <- pages
}

func fetchMultiPages(board string, pre int) {
	ch := make(chan int)
	url := BaseUrl + board + "/index.html"
	go fetchPages(url, ch)
	p := <-ch

	var output string

	var pagesURL = make([]string, pre+1)
	for i := pre; i >= 0; i-- {
		pagesURL[i] = BaseUrl + board + "/index" + strconv.Itoa(p+1-i) + ".html"
		s := make(chan string)
		go fetchSingle(pagesURL[i], s)
		result := <-s
		output += result
	}

	printOutput(output)
}

func printOutput(output string) {
	spaceRex := regexp.MustCompile(`\s+`)
	table := tablewriter.NewWriter(os.Stdout)
	table.SetHeader([]string{"Push", "Title", "URL"})
	table.SetAlignment(tablewriter.ALIGN_LEFT)
	o := [][]string{}

	rows := strings.Split(output, "\n")
	for i := 0; i < len(rows); i++ {
		row := strings.Split(rows[i], "\t") // row[0], row[1], row[2]

		if len(row) == 3 {
			push := row[0]
			title := spaceRex.ReplaceAllString(row[1], "") // remove space to aviod wrong table format
			url := row[2]
			arr := []string{push, title, url}
			o = append(o, arr)
		}
	}
	table.AppendBulk(o)
	table.Render() // Send output
}

func getDocument(resp *http.Response) *goquery.Document {
	r := io.Reader(resp.Body)
	doc, _ := goquery.NewDocumentFromReader(r)
	return doc
}

func fetch(url string) *http.Response {
	resp, _ := http.Get(url)
	return resp
}
<|endoftext|>


<commit_before>package buildkite

import "fmt"
import "strings"

// You can overriden buildVersion at compile time by using:
//
//  go run -ldflags "-X github.com/buildkite/agent/buildkite.buildVersion abc" *.go --version
//
// On CI, the binaries are always build with the buildVersion variable set.

var baseVersion string = "1.0-beta.25"
var buildVersion string = ""

func Version() string {
	// Only output the build version if a pre-release
	if strings.Contains(baseVersion, "beta") || strings.Contains(baseVersion, "alpha") {
		// Use a default buildVersion if one doesn't exist
		actualBuildVersion := buildVersion
		if actualBuildVersion == "" {
			actualBuildVersion = "x"
		}

		return fmt.Sprintf("%s.%s", baseVersion, actualBuildVersion)
	} else {
		return baseVersion
	}
}
<commit_msg>Bumping to 1.0-beta.26<commit_after>package buildkite

import "fmt"
import "strings"

// You can overriden buildVersion at compile time by using:
//
//  go run -ldflags "-X github.com/buildkite/agent/buildkite.buildVersion abc" *.go --version
//
// On CI, the binaries are always build with the buildVersion variable set.

var baseVersion string = "1.0-beta.26"
var buildVersion string = ""

func Version() string {
	// Only output the build version if a pre-release
	if strings.Contains(baseVersion, "beta") || strings.Contains(baseVersion, "alpha") {
		// Use a default buildVersion if one doesn't exist
		actualBuildVersion := buildVersion
		if actualBuildVersion == "" {
			actualBuildVersion = "x"
		}

		return fmt.Sprintf("%s.%s", baseVersion, actualBuildVersion)
	} else {
		return baseVersion
	}
}
<|endoftext|>


<commit_before>package archiver

import (
	"os"
	"restic"
	"testing"

	"restic/pipe"
)

var treeJobs = []string{
	"foo/baz/subdir",
	"foo/baz",
	"foo",
	"quu/bar/file1",
	"quu/bar/file2",
	"quu/foo/file1",
	"quu/foo/file2",
	"quu/foo/file3",
	"quu/foo",
	"quu/fooz",
	"quu",
	"yy/a",
	"yy/b",
	"yy",
}

var pipeJobs = []string{
	"foo/baz/subdir",
	"foo/baz/subdir2", // subdir2 added
	"foo/baz",
	"foo",
	"quu/bar/.file1.swp", // file with . added
	"quu/bar/file1",
	"quu/bar/file2",
	"quu/foo/file1", // file2 removed
	"quu/foo/file3",
	"quu/foo",
	"quu",
	"quv/file1", // files added and removed
	"quv/file2",
	"quv",
	"yy",
	"zz/file1", // files removed and added at the end
	"zz/file2",
	"zz",
}

var resultJobs = []struct {
	path   string
	action string
}{
	{"foo/baz/subdir", "same, not a file"},
	{"foo/baz/subdir2", "new, no old job"},
	{"foo/baz", "same, not a file"},
	{"foo", "same, not a file"},
	{"quu/bar/.file1.swp", "new, no old job"},
	{"quu/bar/file1", "same, not a file"},
	{"quu/bar/file2", "same, not a file"},
	{"quu/foo/file1", "same, not a file"},
	{"quu/foo/file3", "same, not a file"},
	{"quu/foo", "same, not a file"},
	{"quu", "same, not a file"},
	{"quv/file1", "new, no old job"},
	{"quv/file2", "new, no old job"},
	{"quv", "new, no old job"},
	{"yy", "same, not a file"},
	{"zz/file1", "testPipeJob"},
	{"zz/file2", "testPipeJob"},
	{"zz", "testPipeJob"},
}

type testPipeJob struct {
	path string
	err  error
	fi   os.FileInfo
	res  chan<- pipe.Result
}

func (j testPipeJob) Path() string               { return j.path }
func (j testPipeJob) Fullpath() string           { return j.path }
func (j testPipeJob) Error() error               { return j.err }
func (j testPipeJob) Info() os.FileInfo          { return j.fi }
func (j testPipeJob) Result() chan<- pipe.Result { return j.res }

func testTreeWalker(done <-chan struct{}, out chan<- restic.WalkTreeJob) {
	for _, e := range treeJobs {
		select {
		case <-done:
			return
		case out <- restic.WalkTreeJob{Path: e}:
		}
	}

	close(out)
}

func testPipeWalker(done <-chan struct{}, out chan<- pipe.Job) {
	for _, e := range pipeJobs {
		select {
		case <-done:
			return
		case out <- testPipeJob{path: e}:
		}
	}

	close(out)
}

func TestArchivePipe(t *testing.T) {
	done := make(chan struct{})

	treeCh := make(chan restic.WalkTreeJob)
	pipeCh := make(chan pipe.Job)

	go testTreeWalker(done, treeCh)
	go testPipeWalker(done, pipeCh)

	p := archivePipe{Old: treeCh, New: pipeCh}

	ch := make(chan pipe.Job)

	go p.compare(done, ch)

	i := 0
	for job := range ch {
		if job.Path() != resultJobs[i].path {
			t.Fatalf("wrong job received: wanted %v, got %v", resultJobs[i], job)
		}

		// switch j := job.(type) {
		// case archivePipeJob:
		// 	if j.action != resultJobs[i].action {
		// 		t.Fatalf("wrong action for %v detected: wanted %q, got %q", job.Path(), resultJobs[i].action, j.action)
		// 	}
		// case testPipeJob:
		// 	if resultJobs[i].action != "testPipeJob" {
		// 		t.Fatalf("unexpected testPipeJob, expected %q: %v", resultJobs[i].action, j)
		// 	}
		// }

		i++
	}
}
<commit_msg>Fix archiver test<commit_after>package archiver

import (
	"os"
	"testing"

	"restic/pipe"
	"restic/walk"
)

var treeJobs = []string{
	"foo/baz/subdir",
	"foo/baz",
	"foo",
	"quu/bar/file1",
	"quu/bar/file2",
	"quu/foo/file1",
	"quu/foo/file2",
	"quu/foo/file3",
	"quu/foo",
	"quu/fooz",
	"quu",
	"yy/a",
	"yy/b",
	"yy",
}

var pipeJobs = []string{
	"foo/baz/subdir",
	"foo/baz/subdir2", // subdir2 added
	"foo/baz",
	"foo",
	"quu/bar/.file1.swp", // file with . added
	"quu/bar/file1",
	"quu/bar/file2",
	"quu/foo/file1", // file2 removed
	"quu/foo/file3",
	"quu/foo",
	"quu",
	"quv/file1", // files added and removed
	"quv/file2",
	"quv",
	"yy",
	"zz/file1", // files removed and added at the end
	"zz/file2",
	"zz",
}

var resultJobs = []struct {
	path   string
	action string
}{
	{"foo/baz/subdir", "same, not a file"},
	{"foo/baz/subdir2", "new, no old job"},
	{"foo/baz", "same, not a file"},
	{"foo", "same, not a file"},
	{"quu/bar/.file1.swp", "new, no old job"},
	{"quu/bar/file1", "same, not a file"},
	{"quu/bar/file2", "same, not a file"},
	{"quu/foo/file1", "same, not a file"},
	{"quu/foo/file3", "same, not a file"},
	{"quu/foo", "same, not a file"},
	{"quu", "same, not a file"},
	{"quv/file1", "new, no old job"},
	{"quv/file2", "new, no old job"},
	{"quv", "new, no old job"},
	{"yy", "same, not a file"},
	{"zz/file1", "testPipeJob"},
	{"zz/file2", "testPipeJob"},
	{"zz", "testPipeJob"},
}

type testPipeJob struct {
	path string
	err  error
	fi   os.FileInfo
	res  chan<- pipe.Result
}

func (j testPipeJob) Path() string               { return j.path }
func (j testPipeJob) Fullpath() string           { return j.path }
func (j testPipeJob) Error() error               { return j.err }
func (j testPipeJob) Info() os.FileInfo          { return j.fi }
func (j testPipeJob) Result() chan<- pipe.Result { return j.res }

func testTreeWalker(done <-chan struct{}, out chan<- walk.TreeJob) {
	for _, e := range treeJobs {
		select {
		case <-done:
			return
		case out <- walk.TreeJob{Path: e}:
		}
	}

	close(out)
}

func testPipeWalker(done <-chan struct{}, out chan<- pipe.Job) {
	for _, e := range pipeJobs {
		select {
		case <-done:
			return
		case out <- testPipeJob{path: e}:
		}
	}

	close(out)
}

func TestArchivePipe(t *testing.T) {
	done := make(chan struct{})

	treeCh := make(chan walk.TreeJob)
	pipeCh := make(chan pipe.Job)

	go testTreeWalker(done, treeCh)
	go testPipeWalker(done, pipeCh)

	p := archivePipe{Old: treeCh, New: pipeCh}

	ch := make(chan pipe.Job)

	go p.compare(done, ch)

	i := 0
	for job := range ch {
		if job.Path() != resultJobs[i].path {
			t.Fatalf("wrong job received: wanted %v, got %v", resultJobs[i], job)
		}

		// switch j := job.(type) {
		// case archivePipeJob:
		// 	if j.action != resultJobs[i].action {
		// 		t.Fatalf("wrong action for %v detected: wanted %q, got %q", job.Path(), resultJobs[i].action, j.action)
		// 	}
		// case testPipeJob:
		// 	if resultJobs[i].action != "testPipeJob" {
		// 		t.Fatalf("unexpected testPipeJob, expected %q: %v", resultJobs[i].action, j)
		// 	}
		// }

		i++
	}
}
<|endoftext|>


<commit_before>package fea

import (
	"github.com/coreswitch/component"
)

var (
	Inits  []func() error
	VrfAdd func(vrfName string, index int) error
)

type FeaParam map[string]string

type FeaComponent struct {
	Params *FeaParam
}

func NewFeaComponent(param *FeaParam) *FeaComponent {
	return &FeaComponent{
		Params: param,
	}
}

func (fea *FeaComponent) Start() component.Component {
	//fea_linux.Ipv4ForwardingSet(true)
	//fmt.Println("ipv4 forwarding", fea_linux.Ipv4ForwardingGet())
	//fea_linux.Ipv6ForwardingSet(true)
	//fmt.Println("ipv6 forwarding", fea_linux.Ipv6ForwardingGet())
	return fea
}

func (fea *FeaComponent) Stop() component.Component {
	return fea
}
<commit_msg>Change VrfAdd index type from int to uint32.<commit_after>package fea

import (
	"github.com/coreswitch/component"
)

var (
	Inits  []func() error
	VrfAdd func(vrfName string, index uint32) error
)

type FeaParam map[string]string

type FeaComponent struct {
	Params *FeaParam
}

func NewFeaComponent(param *FeaParam) *FeaComponent {
	return &FeaComponent{
		Params: param,
	}
}

func (fea *FeaComponent) Start() component.Component {
	//fea_linux.Ipv4ForwardingSet(true)
	//fmt.Println("ipv4 forwarding", fea_linux.Ipv4ForwardingGet())
	//fea_linux.Ipv6ForwardingSet(true)
	//fmt.Println("ipv6 forwarding", fea_linux.Ipv6ForwardingGet())
	return fea
}

func (fea *FeaComponent) Stop() component.Component {
	return fea
}
<|endoftext|>


<commit_before>package pigeon

import (
	vision "google.golang.org/api/vision/v1"
)

const (
	// TypeUnspecified - Unspecified feature type.
	TypeUnspecified = iota
	// FaceDetection - Run face detection.
	FaceDetection
	// LandmarkDetection - Run landmark detection.
	LandmarkDetection
	// LogoDetection - Run logo detection.
	LogoDetection
	// LabelDetection - Run label detection.
	LabelDetection
	// TextDetection - Run OCR.
	TextDetection
	// SafeSearchDetection - Run various computer vision models to
	SafeSearchDetection
	// ImageProperties - compute image safe-search properties.
	ImageProperties
)

// DetectionType returns a value of detection type.
func DetectionType(d int) string {
	switch d {
	case TypeUnspecified:
		return "TYPE_UNSPECIFIED"
	case FaceDetection:
		return "FACE_DETECTION"
	case LandmarkDetection:
		return "LANDMARK_DETECTION"
	case LogoDetection:
		return "LOGO_DETECTION"
	case LabelDetection:
		return "LABEL_DETECTION"
	case TextDetection:
		return "TEXT_DETECTION"
	case SafeSearchDetection:
		return "SAFE_SEARCH_DETECTION"
	case ImageProperties:
		return "IMAGE_PROPERTIES"
	}
	return ""
}

// NewFeature returns a pointer to a new vision's Feature object.
func NewFeature(d int) *vision.Feature {
	return &vision.Feature{Type: DetectionType(d)}
}
<commit_msg>Update feature.go<commit_after>package pigeon

import (
	vision "google.golang.org/api/vision/v1"
)

const (
	// TypeUnspecified - Unspecified feature type.
	TypeUnspecified = iota
	// FaceDetection - Run face detection.
	FaceDetection
	// LandmarkDetection - Run landmark detection.
	LandmarkDetection
	// LogoDetection - Run logo detection.
	LogoDetection
	// LabelDetection - Run label detection.
	LabelDetection
	// TextDetection - Run OCR with big text
	TextDetection
	// DocumentTextDetection - Run OCR on document
	DocumentTextDetection
	// SafeSearchDetection - Run various computer vision models to
	SafeSearchDetection
	// ImageProperties - compute image safe-search properties.
	ImageProperties
)

// DetectionType returns a value of detection type.
func DetectionType(d int) string {
	switch d {
	case TypeUnspecified:
		return "TYPE_UNSPECIFIED"
	case FaceDetection:
		return "FACE_DETECTION"
	case LandmarkDetection:
		return "LANDMARK_DETECTION"
	case LogoDetection:
		return "LOGO_DETECTION"
	case LabelDetection:
		return "LABEL_DETECTION"
	case TextDetection:
		return "TEXT_DETECTION"
	case DocumentTextDetection:
		return "DOCUMENT_TEXT_DETECTION"
	case SafeSearchDetection:
		return "SAFE_SEARCH_DETECTION"
	case ImageProperties:
		return "IMAGE_PROPERTIES"
	}
	return ""
}

// NewFeature returns a pointer to a new vision's Feature object.
func NewFeature(d int) *vision.Feature {
	return &vision.Feature{Type: DetectionType(d)}
}
<|endoftext|>


<commit_before>// Copyright 2015 Google Inc. All Rights Reserved.
//
// 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 main

import (
	"fmt"
	"log"
	"os"

	"golang.org/x/net/context"

	"github.com/googlecloudplatform/gcsfuse/internal/fs"
	"github.com/googlecloudplatform/gcsfuse/internal/perms"
	"github.com/jacobsa/fuse"
	"github.com/jacobsa/fuse/fsutil"
	"github.com/jacobsa/gcloud/gcs"
	"github.com/jacobsa/timeutil"
)

// Mount the file system based on the supplied arguments, returning a
// fuse.MountedFileSystem that can be joined to wait for unmounting.
func mount(
	ctx context.Context,
	bucketName string,
	mountPoint string,
	flags *flagStorage,
	conn gcs.Conn) (mfs *fuse.MountedFileSystem, err error) {
	// Sanity check: make sure the temporary directory exists and is writable
	// currently. This gives a better user experience than harder to debug EIO
	// errors when reading files in the future.
	if flags.TempDir != "" {
		var f *os.File
		f, err = fsutil.AnonymousFile(flags.TempDir)
		f.Close()

		if err != nil {
			err = fmt.Errorf(
				"Error writing to temporary directory (%q); are you sure it exists "+
					"with the correct permissions?",
				err.Error())
			return
		}
	}

	// Choose UID and GID.
	uid, gid, err := perms.MyUserAndGroup()
	if err != nil {
		err = fmt.Errorf("MyUserAndGroup: %v", err)
		return
	}

	if flags.Uid >= 0 {
		uid = uint32(flags.Uid)
	}

	if flags.Gid >= 0 {
		gid = uint32(flags.Gid)
	}

	// Set up the bucket.
	bucket, err := setUpBucket(
		ctx,
		flags,
		conn,
		bucketName)

	if err != nil {
		err = fmt.Errorf("setUpBucket: %v", err)
		return
	}

	// Create a file system server.
	serverCfg := &fs.ServerConfig{
		Clock:               timeutil.RealClock(),
		Bucket:              bucket,
		TempDir:             flags.TempDir,
		ImplicitDirectories: flags.ImplicitDirs,
		DirTypeCacheTTL:     flags.TypeCacheTTL,
		Uid:                 uid,
		Gid:                 gid,
		FilePerms:           os.FileMode(flags.FileMode),
		DirPerms:            os.FileMode(flags.DirMode),

		AppendThreshold: 1 << 21, // 2 MiB, a total guess.
		TmpObjectPrefix: ".gcsfuse_tmp/",
	}

	server, err := fs.NewServer(serverCfg)
	if err != nil {
		err = fmt.Errorf("fs.NewServer: %v", err)
		return
	}

	// Mount the file system.
	mountCfg := &fuse.MountConfig{
		FSName:      bucket.Name(),
		Options:     flags.MountOptions,
		ErrorLogger: log.New(os.Stderr, "fuse: ", log.Flags()),
	}

	if flags.DebugFuse {
		mountCfg.DebugLogger = log.New(os.Stderr, "fuse_debug: ", 0)
	}

	mfs, err = fuse.Mount(mountPoint, server, mountCfg)
	if err != nil {
		err = fmt.Errorf("Mount: %v", err)
		return
	}

	return
}
<commit_msg>Fixed mount.go.<commit_after>// Copyright 2015 Google Inc. All Rights Reserved.
//
// 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 main

import (
	"fmt"
	"log"
	"os"

	"golang.org/x/net/context"

	"github.com/googlecloudplatform/gcsfuse/internal/fs"
	"github.com/googlecloudplatform/gcsfuse/internal/perms"
	"github.com/jacobsa/fuse"
	"github.com/jacobsa/fuse/fsutil"
	"github.com/jacobsa/gcloud/gcs"
	"github.com/jacobsa/timeutil"
)

// Mount the file system based on the supplied arguments, returning a
// fuse.MountedFileSystem that can be joined to wait for unmounting.
func mount(
	ctx context.Context,
	bucketName string,
	mountPoint string,
	flags *flagStorage,
	conn gcs.Conn) (mfs *fuse.MountedFileSystem, err error) {
	// Sanity check: make sure the temporary directory exists and is writable
	// currently. This gives a better user experience than harder to debug EIO
	// errors when reading files in the future.
	if flags.TempDir != "" {
		var f *os.File
		f, err = fsutil.AnonymousFile(flags.TempDir)
		f.Close()

		if err != nil {
			err = fmt.Errorf(
				"Error writing to temporary directory (%q); are you sure it exists "+
					"with the correct permissions?",
				err.Error())
			return
		}
	}

	// Choose UID and GID.
	uid, gid, err := perms.MyUserAndGroup()
	if err != nil {
		err = fmt.Errorf("MyUserAndGroup: %v", err)
		return
	}

	if flags.Uid >= 0 {
		uid = uint32(flags.Uid)
	}

	if flags.Gid >= 0 {
		gid = uint32(flags.Gid)
	}

	// Set up the bucket.
	bucket, err := setUpBucket(
		ctx,
		flags,
		conn,
		bucketName)

	if err != nil {
		err = fmt.Errorf("setUpBucket: %v", err)
		return
	}

	// Create a file system server.
	serverCfg := &fs.ServerConfig{
		CacheClock:          timeutil.RealClock(),
		Bucket:              bucket,
		TempDir:             flags.TempDir,
		ImplicitDirectories: flags.ImplicitDirs,
		DirTypeCacheTTL:     flags.TypeCacheTTL,
		Uid:                 uid,
		Gid:                 gid,
		FilePerms:           os.FileMode(flags.FileMode),
		DirPerms:            os.FileMode(flags.DirMode),

		AppendThreshold: 1 << 21, // 2 MiB, a total guess.
		TmpObjectPrefix: ".gcsfuse_tmp/",
	}

	server, err := fs.NewServer(serverCfg)
	if err != nil {
		err = fmt.Errorf("fs.NewServer: %v", err)
		return
	}

	// Mount the file system.
	mountCfg := &fuse.MountConfig{
		FSName:      bucket.Name(),
		Options:     flags.MountOptions,
		ErrorLogger: log.New(os.Stderr, "fuse: ", log.Flags()),
	}

	if flags.DebugFuse {
		mountCfg.DebugLogger = log.New(os.Stderr, "fuse_debug: ", 0)
	}

	mfs, err = fuse.Mount(mountPoint, server, mountCfg)
	if err != nil {
		err = fmt.Errorf("Mount: %v", err)
		return
	}

	return
}
<|endoftext|>


<commit_before>package mount

import (
	"context"
	"net/http"

	"github.com/acoshift/httperror"
)

// Mounter type
type Mounter struct {
	c Config
}

// Config is the mounter config
type Config struct {
	Binder         func(*http.Request, interface{}) error
	SuccessHandler func(w http.ResponseWriter, r *http.Request, res interface{})
	ErrorHandler   func(w http.ResponseWriter, r *http.Request, err error)
}

// Validatable interface
type Validatable interface {
	Validate() error
}

// New creates new mounter
func New(config Config) *Mounter {
	m := &Mounter{Config{
		Binder:         func(*http.Request, interface{}) error { return nil },
		SuccessHandler: func(w http.ResponseWriter, r *http.Request, res interface{}) {},
		ErrorHandler:   func(w http.ResponseWriter, r *http.Request, err error) {},
	}}
	if config.Binder != nil {
		m.c.Binder = config.Binder
	}
	if config.SuccessHandler != nil {
		m.c.SuccessHandler = config.SuccessHandler
	}
	if config.ErrorHandler != nil {
		m.c.ErrorHandler = config.ErrorHandler
	}
	return m
}

// Func type
type Func func(context.Context, interface{}) (interface{}, error)

// Handler func
func (m *Mounter) Handler(req interface{}, f Func) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.Method != http.MethodPost {
			m.c.ErrorHandler(w, r, httperror.MethodNotAllowed)
			return
		}
		err := m.c.Binder(r, req)
		if err != nil {
			m.c.ErrorHandler(w, r, httperror.BadRequestWith(err))
			return
		}
		if req, ok := req.(Validatable); ok {
			err = req.Validate()
			if err != nil {
				m.c.ErrorHandler(w, r, httperror.BadRequestWith(err))
				return
			}
		}
		res, err := f(r.Context(), req)
		if err != nil {
			m.c.ErrorHandler(w, r, err)
			return
		}
		m.c.SuccessHandler(w, r, res)
	})
}
<commit_msg>fix req not create new object<commit_after>package mount

import (
	"context"
	"net/http"

	"reflect"

	"github.com/acoshift/httperror"
)

// Mounter type
type Mounter struct {
	c Config
}

// Config is the mounter config
type Config struct {
	Binder         func(*http.Request, interface{}) error
	SuccessHandler func(w http.ResponseWriter, r *http.Request, res interface{})
	ErrorHandler   func(w http.ResponseWriter, r *http.Request, err error)
}

// Validatable interface
type Validatable interface {
	Validate() error
}

// New creates new mounter
func New(config Config) *Mounter {
	m := &Mounter{Config{
		Binder:         func(*http.Request, interface{}) error { return nil },
		SuccessHandler: func(w http.ResponseWriter, r *http.Request, res interface{}) {},
		ErrorHandler:   func(w http.ResponseWriter, r *http.Request, err error) {},
	}}
	if config.Binder != nil {
		m.c.Binder = config.Binder
	}
	if config.SuccessHandler != nil {
		m.c.SuccessHandler = config.SuccessHandler
	}
	if config.ErrorHandler != nil {
		m.c.ErrorHandler = config.ErrorHandler
	}
	return m
}

// Func type
type Func func(context.Context, interface{}) (interface{}, error)

// Handler func
func (m *Mounter) Handler(req interface{}, f Func) http.Handler {
	typ := reflect.TypeOf(req)
	if typ.Kind() == reflect.Ptr {
		typ = typ.Elem()
	}
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.Method != http.MethodPost {
			m.c.ErrorHandler(w, r, httperror.MethodNotAllowed)
			return
		}
		req := reflect.New(typ).Interface()
		err := m.c.Binder(r, req)
		if err != nil {
			m.c.ErrorHandler(w, r, httperror.BadRequestWith(err))
			return
		}
		if req, ok := req.(Validatable); ok {
			err = req.Validate()
			if err != nil {
				m.c.ErrorHandler(w, r, httperror.BadRequestWith(err))
				return
			}
		}
		res, err := f(r.Context(), req)
		if err != nil {
			m.c.ErrorHandler(w, r, err)
			return
		}
		m.c.SuccessHandler(w, r, res)
	})
}
<|endoftext|>