wgoodall01/wikipath

View on GitHub
cli/common.go

Summary

Maintainability
A
0 mins
Test Coverage
package main

import (
    "bufio"
    "fmt"
    "os"
    "strings"
    "sync"
    "time"

    "github.com/urfave/cli"
)

// NewFileError creates an error for a file I/O issue.
// Exits with code `1`.
func NewFileError(msg string, args ...interface{}) *cli.ExitError {
    return cli.NewExitError("wikipath: "+fmt.Sprintf(msg, args...)+"\n", 1)
}

// NewInternalError creates an error for an internal problem.
// Exits with code `2`.
func NewInternalError(msg string, args ...interface{}) *cli.ExitError {
    return cli.NewExitError("wikipath: "+fmt.Sprintf(msg, args...)+"\n", 2)
}

// NewUsageError creates an error for improper usage.
// Exits with code `3`.
func NewUsageError(msg string, args ...interface{}) *cli.ExitError {
    return cli.NewExitError("wikipath: "+fmt.Sprintf(msg, args...)+"\n", 3)
}

// Prompt prompts the user for input on stdin, which it then returns.
func Prompt(prompt string) string {
    in := bufio.NewReader(os.Stdin)
    fmt.Printf("%-15s: ", prompt)
    valRaw, _ := in.ReadString('\n')
    return strings.TrimSpace(valRaw)
}

// PrintTicker prints a line which overwrites the last on a tty.
func PrintTicker(prompt string, tick string) {
    width := 100
    status := prompt + tick + strings.Repeat(" ", width)
    status = status[:width] + "\r"
    fmt.Print(status)
}

// RateMeasure measures how frequently something happens.
// Add a number of events by using Add(n), and get the average
// over the last `n` seconds with Average().
type RateMeasure struct {
    mu      sync.Mutex
    count   int
    average float32
    ticker  *time.Ticker
}

// NewRateMeasure creates a RateMeasure with the given interval
// in seconds.
func NewRateMeasure(seconds float32) *RateMeasure {
    rm := &RateMeasure{
        count:   0,
        average: 0,
    }

    rm.ticker = time.NewTicker(time.Duration(seconds*1000) * time.Millisecond)

    go func() {
        for range rm.ticker.C {
            rm.mu.Lock()
            rm.average = float32(rm.count) / seconds
            rm.count = 0
            rm.mu.Unlock()
        }
    }()

    return rm
}

// Stop stops the RateMeasure.
func (rm *RateMeasure) Stop() {
    rm.ticker.Stop()
}

// Count adds `n` events to the RateMeasure.
func (rm *RateMeasure) Count(n int) {
    rm.mu.Lock()
    rm.count += n
    rm.mu.Unlock()
}

// Average returns the average number of events
// over the last interval.
func (rm *RateMeasure) Average() float32 {
    rm.mu.Lock()
    defer rm.mu.Unlock()
    return rm.average
}

type flags struct {
    WikiArchivePath cli.StringFlag
    WikiIndexPath   cli.StringFlag
    WpindexPath     cli.StringFlag
}

// WpFlags are CLI flags shared between subcommands.
var WpFlags = flags{
    WpindexPath: cli.StringFlag{
        Name:   "wpindex, i",
        Usage:  "Path to *.wpindex file",
        EnvVar: "WPINDEX_PATH",
        Value:  "./wikis/enwiki.wpindex",
    },
    WikiArchivePath: cli.StringFlag{
        Name:   "wiki-archive, wa",
        Usage:  "Wiki archive *-multistream.xml.bz2 file.",
        EnvVar: "WIKI_ARCHIVE_PATH",
        Value:  "./wikis/enwiki-multistream.xml.bz2",
    },
    WikiIndexPath: cli.StringFlag{
        Name:   "wiki-index, wi",
        Usage:  "Wiki index *-multistream-index.txt.bz2 file.",
        EnvVar: "WIKI_INDEX_PATH",
        Value:  "./wikis/enwiki-multistream-index.txt.bz2",
    },
}