<commit_before>package main

import (
	"context"
	"net/http"
	"net/http/httputil"
	"net/url"
	"strings"
	"time"

	"github.com/subutai-io/agent/log"

	"github.com/subutai-io/gorjun/apt"
	"github.com/subutai-io/gorjun/auth"
	"github.com/subutai-io/gorjun/config"
	"github.com/subutai-io/gorjun/db"
	"github.com/subutai-io/gorjun/raw"
	"github.com/subutai-io/gorjun/template"
	"github.com/subutai-io/gorjun/upload"
	"github.com/jasonlvhit/gocron"
)

var version = "6.3.0"

var (
	srv      *http.Server
	testMode bool = false
	stop     chan bool
)
func main() {
	defer db.Close()
	// defer torrent.Close()
	// go torrent.SeedLocal()
	gocron.Every(6).Hours().Do(apt.GenerateReleaseFile)
	<- gocron.Start()

	if len(config.CDN.Node) > 0 {
		target := url.URL{Scheme: "https", Host: config.CDN.Node}
		proxy := httputil.NewSingleHostReverseProxy(&target)
		targetQuery := target.RawQuery
		proxy.Director = func(req *http.Request) {
			req.URL.Scheme = target.Scheme
			req.URL.Host = target.Host
			req.Host = config.CDN.Node
			req.URL.Path = singleJoiningSlash(target.Path, req.URL.Path)
			if targetQuery == "" || req.URL.RawQuery == "" {
				req.URL.RawQuery = targetQuery + req.URL.RawQuery
			} else {
				req.URL.RawQuery = targetQuery + "&" + req.URL.RawQuery
			}
			if _, ok := req.Header["User-Agent"]; !ok {
				// explicitly disable User-Agent so it's not set to default value
				req.Header.Set("User-Agent", "")
			}
		}
		log.Check(log.ErrorLevel, "Starting to listen :"+config.Network.Port, http.ListenAndServe(":"+config.Network.Port, proxy))
		return
	}

	log.Info("Server has started. " + "Listening at " + "127.0.0.1:8080")

	http.HandleFunc("/kurjun/rest/file/get", raw.Download)
	http.HandleFunc("/kurjun/rest/file/info", raw.Info)
	http.HandleFunc("/kurjun/rest/raw/get", raw.Download)
	http.HandleFunc("/kurjun/rest/template/get", template.Download)

	http.HandleFunc("/kurjun/rest/apt/", apt.Download)
	http.HandleFunc("/kurjun/rest/apt/info", apt.Info)
	http.HandleFunc("/kurjun/rest/apt/list", apt.Info)
	http.HandleFunc("/kurjun/rest/apt/delete", apt.Delete)
	http.HandleFunc("/kurjun/rest/apt/upload", apt.Upload)
	http.HandleFunc("/kurjun/rest/apt/download", apt.Download)

	http.HandleFunc("/kurjun/rest/raw/", raw.Download)
	http.HandleFunc("/kurjun/rest/raw/info", raw.Info)
	http.HandleFunc("/kurjun/rest/raw/list", raw.Info)
	http.HandleFunc("/kurjun/rest/raw/delete", raw.Delete)
	http.HandleFunc("/kurjun/rest/raw/upload", raw.Upload)
	http.HandleFunc("/kurjun/rest/raw/download", raw.Download)

	http.HandleFunc("/kurjun/rest/template/", template.Download)
	http.HandleFunc("/kurjun/rest/template/tag", template.Tag)
	http.HandleFunc("/kurjun/rest/template/info", template.Info)
	http.HandleFunc("/kurjun/rest/template/list", template.Info)
	http.HandleFunc("/kurjun/rest/template/delete", template.Delete)
	http.HandleFunc("/kurjun/rest/template/upload", template.Upload)
	http.HandleFunc("/kurjun/rest/template/download", template.Download)
	// http.HandleFunc("/kurjun/rest/template/torrent", template.Torrent)

	http.HandleFunc("/kurjun/rest/auth/key", auth.Key)
	http.HandleFunc("/kurjun/rest/auth/keys", auth.Keys)
	http.HandleFunc("/kurjun/rest/auth/sign", auth.Sign)
	http.HandleFunc("/kurjun/rest/auth/token", auth.Token)
	http.HandleFunc("/kurjun/rest/auth/register", auth.Register)
	http.HandleFunc("/kurjun/rest/auth/validate", auth.Validate)

	http.HandleFunc("/kurjun/rest/share", upload.Share)
	http.HandleFunc("/kurjun/rest/quota", upload.Quota)
	http.HandleFunc("/kurjun/rest/about", about)

	if testMode {
		http.HandleFunc("/kurjun/rest/shutdown", shutdown)
	}

	srv = &http.Server{
		Addr:    ":" + config.Network.Port,
		Handler: nil,
	}
	srv.ListenAndServe()
}

func shutdown(w http.ResponseWriter, r *http.Request) {
	log.Info("Shutting down the server")
	stop <- true
}

func about(w http.ResponseWriter, r *http.Request) {
	if strings.Split(r.RemoteAddr, ":")[0] == "127.0.0.1" {
		_, err := w.Write([]byte(version))
		log.Check(log.DebugLevel, "Writing Kurjun version", err)
	} else {
		w.WriteHeader(http.StatusUnauthorized)
	}
}

func singleJoiningSlash(a, b string) string {
	aslash := strings.HasSuffix(a, "/")
	bslash := strings.HasPrefix(b, "/")
	switch {
	case aslash && bslash:
		return a + b[1:]
	case !aslash && !bslash:
		return a + "/" + b
	}
	return a + b
}

func runMain() {
	// start the stop channel
	stop = make(chan bool)
	// put the service in "testMode"
	testMode = true
	// run the main entry point
	go main()
	// watch for the stop channel
	<-stop
	// stop the graceful server
	ctx, _ := context.WithTimeout(context.Background(), 5*time.Second)
	srv.Shutdown(ctx)
}
<commit_msg>Revert changes<commit_after>package main

import (
	"context"
	"net/http"
	"net/http/httputil"
	"net/url"
	"strings"
	"time"

	"github.com/subutai-io/agent/log"

	"github.com/subutai-io/gorjun/apt"
	"github.com/subutai-io/gorjun/auth"
	"github.com/subutai-io/gorjun/config"
	"github.com/subutai-io/gorjun/db"
	"github.com/subutai-io/gorjun/raw"
	"github.com/subutai-io/gorjun/template"
	"github.com/subutai-io/gorjun/upload"
	//"github.com/jasonlvhit/gocron"
)

var version = "6.3.0"

var (
	srv      *http.Server
	testMode bool = false
	stop     chan bool
)
func main() {
	defer db.Close()
	// defer torrent.Close()
	// go torrent.SeedLocal()
	//gocron.Every(6).Hours().Do(apt.GenerateReleaseFile)
	//<- gocron.Start()

	if len(config.CDN.Node) > 0 {
		target := url.URL{Scheme: "https", Host: config.CDN.Node}
		proxy := httputil.NewSingleHostReverseProxy(&target)
		targetQuery := target.RawQuery
		proxy.Director = func(req *http.Request) {
			req.URL.Scheme = target.Scheme
			req.URL.Host = target.Host
			req.Host = config.CDN.Node
			req.URL.Path = singleJoiningSlash(target.Path, req.URL.Path)
			if targetQuery == "" || req.URL.RawQuery == "" {
				req.URL.RawQuery = targetQuery + req.URL.RawQuery
			} else {
				req.URL.RawQuery = targetQuery + "&" + req.URL.RawQuery
			}
			if _, ok := req.Header["User-Agent"]; !ok {
				// explicitly disable User-Agent so it's not set to default value
				req.Header.Set("User-Agent", "")
			}
		}
		log.Check(log.ErrorLevel, "Starting to listen :"+config.Network.Port, http.ListenAndServe(":"+config.Network.Port, proxy))
		return
	}

	log.Info("Server has started. " + "Listening at " + "127.0.0.1:8080")

	http.HandleFunc("/kurjun/rest/file/get", raw.Download)
	http.HandleFunc("/kurjun/rest/file/info", raw.Info)
	http.HandleFunc("/kurjun/rest/raw/get", raw.Download)
	http.HandleFunc("/kurjun/rest/template/get", template.Download)

	http.HandleFunc("/kurjun/rest/apt/", apt.Download)
	http.HandleFunc("/kurjun/rest/apt/info", apt.Info)
	http.HandleFunc("/kurjun/rest/apt/list", apt.Info)
	http.HandleFunc("/kurjun/rest/apt/delete", apt.Delete)
	http.HandleFunc("/kurjun/rest/apt/upload", apt.Upload)
	http.HandleFunc("/kurjun/rest/apt/download", apt.Download)

	http.HandleFunc("/kurjun/rest/raw/", raw.Download)
	http.HandleFunc("/kurjun/rest/raw/info", raw.Info)
	http.HandleFunc("/kurjun/rest/raw/list", raw.Info)
	http.HandleFunc("/kurjun/rest/raw/delete", raw.Delete)
	http.HandleFunc("/kurjun/rest/raw/upload", raw.Upload)
	http.HandleFunc("/kurjun/rest/raw/download", raw.Download)

	http.HandleFunc("/kurjun/rest/template/", template.Download)
	http.HandleFunc("/kurjun/rest/template/tag", template.Tag)
	http.HandleFunc("/kurjun/rest/template/info", template.Info)
	http.HandleFunc("/kurjun/rest/template/list", template.Info)
	http.HandleFunc("/kurjun/rest/template/delete", template.Delete)
	http.HandleFunc("/kurjun/rest/template/upload", template.Upload)
	http.HandleFunc("/kurjun/rest/template/download", template.Download)
	// http.HandleFunc("/kurjun/rest/template/torrent", template.Torrent)

	http.HandleFunc("/kurjun/rest/auth/key", auth.Key)
	http.HandleFunc("/kurjun/rest/auth/keys", auth.Keys)
	http.HandleFunc("/kurjun/rest/auth/sign", auth.Sign)
	http.HandleFunc("/kurjun/rest/auth/token", auth.Token)
	http.HandleFunc("/kurjun/rest/auth/register", auth.Register)
	http.HandleFunc("/kurjun/rest/auth/validate", auth.Validate)

	http.HandleFunc("/kurjun/rest/share", upload.Share)
	http.HandleFunc("/kurjun/rest/quota", upload.Quota)
	http.HandleFunc("/kurjun/rest/about", about)

	if testMode {
		http.HandleFunc("/kurjun/rest/shutdown", shutdown)
	}

	srv = &http.Server{
		Addr:    ":" + config.Network.Port,
		Handler: nil,
	}
	srv.ListenAndServe()
}

func shutdown(w http.ResponseWriter, r *http.Request) {
	log.Info("Shutting down the server")
	stop <- true
}

func about(w http.ResponseWriter, r *http.Request) {
	if strings.Split(r.RemoteAddr, ":")[0] == "127.0.0.1" {
		_, err := w.Write([]byte(version))
		log.Check(log.DebugLevel, "Writing Kurjun version", err)
	} else {
		w.WriteHeader(http.StatusUnauthorized)
	}
}

func singleJoiningSlash(a, b string) string {
	aslash := strings.HasSuffix(a, "/")
	bslash := strings.HasPrefix(b, "/")
	switch {
	case aslash && bslash:
		return a + b[1:]
	case !aslash && !bslash:
		return a + "/" + b
	}
	return a + b
}

func runMain() {
	// start the stop channel
	stop = make(chan bool)
	// put the service in "testMode"
	testMode = true
	// run the main entry point
	go main()
	// watch for the stop channel
	<-stop
	// stop the graceful server
	ctx, _ := context.WithTimeout(context.Background(), 5*time.Second)
	srv.Shutdown(ctx)
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

// Based on github.com/jmhodges/certificatetransparency/tools/lecsv

package main

import (
	"database/sql"
	"flag"
	"fmt"
	"log"
	"net/url"
	"os"
	"runtime"
	"strings"
	"sync"
	"time"

	_ "github.com/go-sql-driver/mysql"

	"github.com/go-gorp/gorp"
	"github.com/google/certificate-transparency/go"
	"github.com/google/certificate-transparency/go/client"
	"github.com/jcjones/ct-sql/censysdata"
	"github.com/jcjones/ct-sql/sqldb"
)

var (
	logUrl     = flag.String("log", "", "URL of the CT Log")
	censysPath = flag.String("censysJson", "", "Path to a Censys.io certificate json dump")
	dbConnect  = flag.String("dbConnect", "", "DB Connection String")
	verbose    = flag.Bool("v", false, "verbose output")
	fullCerts  = flag.Bool("fullCerts", false, "store full DER-encoded certificates in a certificateraw table")
	offset     = flag.Uint64("offset", 0, "offset from the beginning")
	offsetByte = flag.Uint64("offsetByte", 0, "byte offset from the beginning, only for censysJson and not compatible with offset")
	limit      = flag.Uint64("limit", 0, "limit processing to this many entries")
	reproNames = flag.Bool("reprocessNames", false, "reprocess names")
)

// OperationStatus contains the current state of a large operation (i.e.
// download or tree hash).
type OperationStatus struct {
	// Start contains the requested starting index of the operation.
	Start int64
	// Current contains the greatest index that has been processed.
	Current int64
	// Length contains the total number of entries.
	Length int64
}

func (status OperationStatus) Percentage() float32 {
	total := float32(status.Length - status.Start)
	done := float32(status.Current - status.Start)

	if total == 0 {
		return 100
	}
	return done * 100 / total
}

// Taken from Boulder
func recombineURLForDB(dbConnect string) (string, error) {
	dbConnect = strings.TrimSpace(dbConnect)
	dbURL, err := url.Parse(dbConnect)
	if err != nil {
		return "", err
	}

	if dbURL.Scheme != "mysql+tcp" {
		format := "given database connection string was not a mysql+tcp:// URL, was %#v"
		return "", fmt.Errorf(format, dbURL.Scheme)
	}

	dsnVals, err := url.ParseQuery(dbURL.RawQuery)
	if err != nil {
		return "", err
	}

	dsnVals.Set("parseTime", "true")

	// Required to make UPDATE return the number of rows matched,
	// instead of the number of rows changed by the UPDATE.
	dsnVals.Set("clientFoundRows", "true")

	// Ensures that MySQL/MariaDB warnings are treated as errors. This
	// avoids a number of nasty edge conditions we could wander
	// into. Common things this discovers includes places where data
	// being sent had a different type than what is in the schema,
	// strings being truncated, writing null to a NOT NULL column, and
	// so on. See
	// <https://dev.mysql.com/doc/refman/5.0/en/sql-mode.html#sql-mode-strict>.
	dsnVals.Set("strict", "true")

	user := dbURL.User.Username()
	passwd, hasPass := dbURL.User.Password()
	dbConn := ""
	if user != "" {
		dbConn = url.QueryEscape(user)
	}
	if hasPass {
		dbConn += ":" + passwd
	}
	dbConn += "@tcp(" + dbURL.Host + ")"
	return dbConn + dbURL.EscapedPath() + "?" + dsnVals.Encode(), nil
}

func clearLine() {
	fmt.Printf("\x1b[80D\x1b[2K")
}

func displayProgress(statusChan chan OperationStatus, wg *sync.WaitGroup) {
	wg.Add(1)

	go func() {
		defer wg.Done()
		symbols := []string{"|", "/", "-", "\\"}
		symbolIndex := 0

		status, ok := <-statusChan
		if !ok {
			return
		}

		ticker := time.NewTicker(200 * time.Millisecond)
		defer ticker.Stop()

		isInteractive := strings.Contains(os.Getenv("TERM"), "xterm") || strings.Contains(os.Getenv("TERM"), "screen")

		if !isInteractive {
			ticker.Stop()
		}

		for {
			select {
			case status, ok = <-statusChan:
				if !ok {
					return
				}
			case <-ticker.C:
				symbolIndex = (symbolIndex + 1) % len(symbols)
			}

			if isInteractive {
				clearLine()
				fmt.Printf("%s %.1f%% (%d of %d)", symbols[symbolIndex], status.Percentage(), status.Current, status.Length)
			} else {
				fmt.Println(fmt.Printf("%.1f%% (%d of %d)", status.Percentage(), status.Current, status.Length))
			}
		}
	}()
}

func insertCTWorker(entries <-chan ct.LogEntry, db *sqldb.EntriesDatabase, wg *sync.WaitGroup) {
	wg.Add(1)
	defer wg.Done()
	for ep := range entries {
		err := db.InsertCTEntry(&ep)
		if err != nil {
			log.Printf("Problem inserting certificate: index: %d log: %s error: %s", ep.Index, *logUrl, err)
		}
	}
}

func insertCensysWorker(entries <-chan censysdata.CensysEntry, db *sqldb.EntriesDatabase, wg *sync.WaitGroup) {
	wg.Add(1)
	defer wg.Done()
	for ep := range entries {
		if ep.Valid_nss {
			err := db.InsertCensysEntry(&ep)
			if err != nil {
				log.Printf("Problem inserting certificate: index: %d error: %s", ep.Offset, err)
			}
		}
	}
}

// DownloadRange downloads log entries from the given starting index till one
// less than upTo. If status is not nil then status updates will be written to
// it until the function is complete, when it will be closed. The log entries
// are provided to an output channel.
func downloadCTRangeToChannel(ctLog *client.LogClient, outEntries chan<- ct.LogEntry,
	status chan<- OperationStatus, start, upTo int64) (int64, error) {
	if outEntries == nil {
		return 0, fmt.Errorf("No output channel provided")
	}
	defer close(outEntries)
	if status != nil {
		defer close(status)
	}

	index := start
	for index < upTo {
		if status != nil {
			status <- OperationStatus{start, index, upTo}
		}

		max := index + 2000
		if max >= upTo {
			max = upTo - 1
		}
		rawEnts, err := ctLog.GetEntries(index, max)
		if err != nil {
			return index, err
		}

		for _, ent := range rawEnts {
			outEntries <- ent
			if (ent.Index) != index {
				return index, fmt.Errorf("Index mismatch, local: %v, remote: %v", index, ent.Index)
			}

			index++
		}
	}

	return index, nil
}

func downloadLog(ctLogUrl *url.URL, ctLog *client.LogClient, db *sqldb.EntriesDatabase) error {
	if *offsetByte > 0 {
		return fmt.Errorf("Cannot set offsetByte for CT log downloads")
	}

	fmt.Printf("Fetching signed tree head... ")
	sth, err := ctLog.GetSTH()
	if err != nil {
		return err
	}

	// Set pointer in DB, now that we've verified the log works
	err = db.SetLog(fmt.Sprintf("%s%s", ctLogUrl.Host, ctLogUrl.Path))
	if err != nil {
		log.Fatalf("unable to set Certificate Log: %s", err)
	}

	var origCount uint64
	// Now we're OK to use the DB
	if *offset > 0 {
		log.Printf("Starting from offset %d", *offset)
		origCount = *offset
	} else {
		log.Printf("Counting existing entries... ")
		origCount, err = db.Count()
		if err != nil {
			err = fmt.Errorf("Failed to read entries file: %s", err)
			return err
		}
	}

	fmt.Printf("%d total entries at %s\n", sth.TreeSize, sqldb.Uint64ToTimestamp(sth.Timestamp).Format(time.ANSIC))
	if origCount == sth.TreeSize {
		fmt.Printf("Nothing to do\n")
		return nil
	}

	endPos := sth.TreeSize
	if *limit > 0 && endPos > origCount+*limit {
		endPos = origCount + *limit
	}

	fmt.Printf("Going from %d to %d\n", origCount, endPos)

	entryChan := make(chan ct.LogEntry, 100)
	statusChan := make(chan OperationStatus, 1)
	wg := new(sync.WaitGroup)

	displayProgress(statusChan, wg)
	for i := 0; i < runtime.NumCPU(); i++ {
		go insertCTWorker(entryChan, db, wg)
	}
	_, err = downloadCTRangeToChannel(ctLog, entryChan, statusChan, int64(origCount), int64(endPos))
	wg.Wait()

	clearLine()
	if err != nil {
		err = fmt.Errorf("Error while downloading: %s", err)
		return err
	}

	return nil
}

func processImporter(importer *censysdata.Importer, db *sqldb.EntriesDatabase, wg *sync.WaitGroup) error {
	entryChan := make(chan censysdata.CensysEntry, 100)
	defer close(entryChan)
	statusChan := make(chan OperationStatus, 1)
	defer close(statusChan)
	wg.Add(1)
	defer wg.Done()

	displayProgress(statusChan, wg)
	for i := 0; i < runtime.NumCPU(); i++ {
		go insertCensysWorker(entryChan, db, wg)
	}

	startOffset := *offsetByte
	maxOffset, err := importer.Size()
	if err != nil {
		return err
	}

	//
	// Fast forward
	//
	if *offset > 0 && *offsetByte > 0 {
		return fmt.Errorf("You may not set both offset and offsetByte")
	}

	if *offset > 0 {
		err = importer.SeekLine(*offset)
		if err != nil {
			return err
		}
	}

	if *offsetByte > 0 {
		err = importer.SeekByte(*offsetByte)
		if err != nil {
			return err
		}
	}

	log.Printf("Starting import from offset=%d, line_limit=%d / size=%d.", importer.ByteOffset(), *limit, maxOffset)

	// We've already fast-forwarded, so start at 0.
	for count := uint64(0); ; count++ {
		if *limit > uint64(0) && count >= *limit {
			return nil
		}
		ent, err := importer.NextEntry()
		if err != nil || ent == nil {
			return err
		}
		if count%128 == 0 {
			statusChan <- OperationStatus{int64(startOffset), int64(ent.Offset), int64(maxOffset)}
		}
		entryChan <- *ent
	}

	return nil
}

func reprocessNames(db *sqldb.EntriesDatabase, wg *sync.WaitGroup) error {
	statusChan := make(chan OperationStatus, 1)
	defer close(statusChan)
	wg.Add(1)
	defer wg.Done()

	displayProgress(statusChan, wg)

	certIDs, err := db.GetNamesWithoutRegisteredDomains(*limit)
	if err != nil {
		return err
	}

	for count, id := range certIDs {
		if count%1024 == 0 {
			statusChan <- OperationStatus{int64(0), int64(count), int64(len(certIDs))}
		}

		err = db.ReprocessRegisteredDomainsForCertId(id)

		if err != nil {
			log.Printf("Problem reprocessing certificate: certID: %d error: %s", id, err)
		}
	}

	return nil
}

func main() {
	flag.Parse()
	log.SetFlags(0)
	log.SetPrefix("")
	dbConnectStr, err := recombineURLForDB(*dbConnect)
	if err != nil {
		log.Printf("unable to parse %s: %s", *dbConnect, err)
	}

	if len(dbConnectStr) == 0 || (censysPath == nil && logUrl == nil) {
		flag.Usage()
		os.Exit(2)
	}

	db, err := sql.Open("mysql", dbConnectStr)
	if err != nil {
		log.Fatalf("unable to open SQL: %s: %s", dbConnectStr, err)
	}
	if err = db.Ping(); err != nil {
		log.Fatalf("unable to ping SQL: %s: %s", dbConnectStr, err)
	}

	dialect := gorp.MySQLDialect{Engine: "InnoDB", Encoding: "UTF8"}
	dbMap := &gorp.DbMap{Db: db, Dialect: dialect}
	entriesDb := &sqldb.EntriesDatabase{DbMap: dbMap, Verbose: *verbose, FullCerts: *fullCerts}
	err = entriesDb.InitTables()
	if err != nil {
		log.Fatalf("unable to prepare SQL: %s: %s", dbConnectStr, err)
	}

	if *reproNames {
		wg := new(sync.WaitGroup)
		err = reprocessNames(entriesDb, wg)
		if err != nil {
			log.Fatalf("error while reprocessing the names: %s", err)
		}
		wg.Wait()
		os.Exit(0)
	}

	if logUrl != nil && len(*logUrl) > 5 {
		ctLogUrl, err := url.Parse(*logUrl)
		if err != nil {
			log.Fatalf("unable to set Certificate Log: %s", err)
		}

		ctLog := client.New(*logUrl)

		err = downloadLog(ctLogUrl, ctLog, entriesDb)
		if err != nil {
			log.Fatalf("error while updating CT entries: %s", err)
		}

		os.Exit(0)
	}

	if censysPath != nil && len(*censysPath) > 5 {
		importer := &censysdata.Importer{}
		err = importer.OpenFile(*censysPath)
		if err != nil {
			log.Fatalf("unable to open Censys file: %s", err)
		}
		defer importer.Close()

		wg := new(sync.WaitGroup)
		err := processImporter(importer, entriesDb, wg)

		if err != nil {
			log.Fatalf("error while running importer: %s", err)
		}

		wg.Wait()
		os.Exit(0)
	}

	// Didn't include a mandatory action, so print usage and exit.
	flag.Usage()
	os.Exit(2)
}
<commit_msg>Support an ini file; see https://github.com/vharitonsky/iniflags<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

// Based on github.com/jmhodges/certificatetransparency/tools/lecsv

package main

import (
	"database/sql"
	"flag"
	"fmt"
	"log"
	"net/url"
	"os"
	"runtime"
	"strings"
	"sync"
	"time"

	_ "github.com/go-sql-driver/mysql"

	"github.com/go-gorp/gorp"
	"github.com/google/certificate-transparency/go"
	"github.com/google/certificate-transparency/go/client"
	"github.com/jcjones/ct-sql/censysdata"
	"github.com/jcjones/ct-sql/sqldb"
	"github.com/vharitonsky/iniflags"
)

var (
	logUrl     = flag.String("log", "", "URL of the CT Log")
	censysPath = flag.String("censysJson", "", "Path to a Censys.io certificate json dump")
	dbConnect  = flag.String("dbConnect", "", "DB Connection String")
	verbose    = flag.Bool("v", false, "verbose output")
	fullCerts  = flag.Bool("fullCerts", false, "store full DER-encoded certificates in a certificateraw table")
	offset     = flag.Uint64("offset", 0, "offset from the beginning")
	offsetByte = flag.Uint64("offsetByte", 0, "byte offset from the beginning, only for censysJson and not compatible with offset")
	limit      = flag.Uint64("limit", 0, "limit processing to this many entries")
	reproNames = flag.Bool("reprocessNames", false, "reprocess names")
)

// OperationStatus contains the current state of a large operation (i.e.
// download or tree hash).
type OperationStatus struct {
	// Start contains the requested starting index of the operation.
	Start int64
	// Current contains the greatest index that has been processed.
	Current int64
	// Length contains the total number of entries.
	Length int64
}

func (status OperationStatus) Percentage() float32 {
	total := float32(status.Length - status.Start)
	done := float32(status.Current - status.Start)

	if total == 0 {
		return 100
	}
	return done * 100 / total
}

// Taken from Boulder
func recombineURLForDB(dbConnect string) (string, error) {
	dbConnect = strings.TrimSpace(dbConnect)
	dbURL, err := url.Parse(dbConnect)
	if err != nil {
		return "", err
	}

	if dbURL.Scheme != "mysql+tcp" {
		format := "given database connection string was not a mysql+tcp:// URL, was %#v"
		return "", fmt.Errorf(format, dbURL.Scheme)
	}

	dsnVals, err := url.ParseQuery(dbURL.RawQuery)
	if err != nil {
		return "", err
	}

	dsnVals.Set("parseTime", "true")

	// Required to make UPDATE return the number of rows matched,
	// instead of the number of rows changed by the UPDATE.
	dsnVals.Set("clientFoundRows", "true")

	// Ensures that MySQL/MariaDB warnings are treated as errors. This
	// avoids a number of nasty edge conditions we could wander
	// into. Common things this discovers includes places where data
	// being sent had a different type than what is in the schema,
	// strings being truncated, writing null to a NOT NULL column, and
	// so on. See
	// <https://dev.mysql.com/doc/refman/5.0/en/sql-mode.html#sql-mode-strict>.
	dsnVals.Set("strict", "true")

	user := dbURL.User.Username()
	passwd, hasPass := dbURL.User.Password()
	dbConn := ""
	if user != "" {
		dbConn = url.QueryEscape(user)
	}
	if hasPass {
		dbConn += ":" + passwd
	}
	dbConn += "@tcp(" + dbURL.Host + ")"
	return dbConn + dbURL.EscapedPath() + "?" + dsnVals.Encode(), nil
}

func clearLine() {
	fmt.Printf("\x1b[80D\x1b[2K")
}

func displayProgress(statusChan chan OperationStatus, wg *sync.WaitGroup) {
	wg.Add(1)

	go func() {
		defer wg.Done()
		symbols := []string{"|", "/", "-", "\\"}
		symbolIndex := 0

		status, ok := <-statusChan
		if !ok {
			return
		}

		ticker := time.NewTicker(200 * time.Millisecond)
		defer ticker.Stop()

		isInteractive := strings.Contains(os.Getenv("TERM"), "xterm") || strings.Contains(os.Getenv("TERM"), "screen")

		if !isInteractive {
			ticker.Stop()
		}

		for {
			select {
			case status, ok = <-statusChan:
				if !ok {
					return
				}
			case <-ticker.C:
				symbolIndex = (symbolIndex + 1) % len(symbols)
			}

			if isInteractive {
				clearLine()
				fmt.Printf("%s %.1f%% (%d of %d)", symbols[symbolIndex], status.Percentage(), status.Current, status.Length)
			} else {
				fmt.Println(fmt.Printf("%.1f%% (%d of %d)", status.Percentage(), status.Current, status.Length))
			}
		}
	}()
}

func insertCTWorker(entries <-chan ct.LogEntry, db *sqldb.EntriesDatabase, wg *sync.WaitGroup) {
	wg.Add(1)
	defer wg.Done()
	for ep := range entries {
		err := db.InsertCTEntry(&ep)
		if err != nil {
			log.Printf("Problem inserting certificate: index: %d log: %s error: %s", ep.Index, *logUrl, err)
		}
	}
}

func insertCensysWorker(entries <-chan censysdata.CensysEntry, db *sqldb.EntriesDatabase, wg *sync.WaitGroup) {
	wg.Add(1)
	defer wg.Done()
	for ep := range entries {
		if ep.Valid_nss {
			err := db.InsertCensysEntry(&ep)
			if err != nil {
				log.Printf("Problem inserting certificate: index: %d error: %s", ep.Offset, err)
			}
		}
	}
}

// DownloadRange downloads log entries from the given starting index till one
// less than upTo. If status is not nil then status updates will be written to
// it until the function is complete, when it will be closed. The log entries
// are provided to an output channel.
func downloadCTRangeToChannel(ctLog *client.LogClient, outEntries chan<- ct.LogEntry,
	status chan<- OperationStatus, start, upTo int64) (int64, error) {
	if outEntries == nil {
		return 0, fmt.Errorf("No output channel provided")
	}
	defer close(outEntries)
	if status != nil {
		defer close(status)
	}

	index := start
	for index < upTo {
		if status != nil {
			status <- OperationStatus{start, index, upTo}
		}

		max := index + 2000
		if max >= upTo {
			max = upTo - 1
		}
		rawEnts, err := ctLog.GetEntries(index, max)
		if err != nil {
			return index, err
		}

		for _, ent := range rawEnts {
			outEntries <- ent
			if (ent.Index) != index {
				return index, fmt.Errorf("Index mismatch, local: %v, remote: %v", index, ent.Index)
			}

			index++
		}
	}

	return index, nil
}

func downloadLog(ctLogUrl *url.URL, ctLog *client.LogClient, db *sqldb.EntriesDatabase) error {
	if *offsetByte > 0 {
		return fmt.Errorf("Cannot set offsetByte for CT log downloads")
	}

	fmt.Printf("Fetching signed tree head... ")
	sth, err := ctLog.GetSTH()
	if err != nil {
		return err
	}

	// Set pointer in DB, now that we've verified the log works
	err = db.SetLog(fmt.Sprintf("%s%s", ctLogUrl.Host, ctLogUrl.Path))
	if err != nil {
		log.Fatalf("unable to set Certificate Log: %s", err)
	}

	var origCount uint64
	// Now we're OK to use the DB
	if *offset > 0 {
		log.Printf("Starting from offset %d", *offset)
		origCount = *offset
	} else {
		log.Printf("Counting existing entries... ")
		origCount, err = db.Count()
		if err != nil {
			err = fmt.Errorf("Failed to read entries file: %s", err)
			return err
		}
	}

	fmt.Printf("%d total entries at %s\n", sth.TreeSize, sqldb.Uint64ToTimestamp(sth.Timestamp).Format(time.ANSIC))
	if origCount == sth.TreeSize {
		fmt.Printf("Nothing to do\n")
		return nil
	}

	endPos := sth.TreeSize
	if *limit > 0 && endPos > origCount+*limit {
		endPos = origCount + *limit
	}

	fmt.Printf("Going from %d to %d\n", origCount, endPos)

	entryChan := make(chan ct.LogEntry, 100)
	statusChan := make(chan OperationStatus, 1)
	wg := new(sync.WaitGroup)

	displayProgress(statusChan, wg)
	for i := 0; i < runtime.NumCPU(); i++ {
		go insertCTWorker(entryChan, db, wg)
	}
	_, err = downloadCTRangeToChannel(ctLog, entryChan, statusChan, int64(origCount), int64(endPos))
	wg.Wait()

	clearLine()
	if err != nil {
		err = fmt.Errorf("Error while downloading: %s", err)
		return err
	}

	return nil
}

func processImporter(importer *censysdata.Importer, db *sqldb.EntriesDatabase, wg *sync.WaitGroup) error {
	entryChan := make(chan censysdata.CensysEntry, 100)
	defer close(entryChan)
	statusChan := make(chan OperationStatus, 1)
	defer close(statusChan)
	wg.Add(1)
	defer wg.Done()

	displayProgress(statusChan, wg)
	for i := 0; i < runtime.NumCPU(); i++ {
		go insertCensysWorker(entryChan, db, wg)
	}

	startOffset := *offsetByte
	maxOffset, err := importer.Size()
	if err != nil {
		return err
	}

	//
	// Fast forward
	//
	if *offset > 0 && *offsetByte > 0 {
		return fmt.Errorf("You may not set both offset and offsetByte")
	}

	if *offset > 0 {
		err = importer.SeekLine(*offset)
		if err != nil {
			return err
		}
	}

	if *offsetByte > 0 {
		err = importer.SeekByte(*offsetByte)
		if err != nil {
			return err
		}
	}

	log.Printf("Starting import from offset=%d, line_limit=%d / size=%d.", importer.ByteOffset(), *limit, maxOffset)

	// We've already fast-forwarded, so start at 0.
	for count := uint64(0); ; count++ {
		if *limit > uint64(0) && count >= *limit {
			return nil
		}
		ent, err := importer.NextEntry()
		if err != nil || ent == nil {
			return err
		}
		if count%128 == 0 {
			statusChan <- OperationStatus{int64(startOffset), int64(ent.Offset), int64(maxOffset)}
		}
		entryChan <- *ent
	}

	return nil
}

func reprocessNames(db *sqldb.EntriesDatabase, wg *sync.WaitGroup) error {
	statusChan := make(chan OperationStatus, 1)
	defer close(statusChan)
	wg.Add(1)
	defer wg.Done()

	displayProgress(statusChan, wg)

	certIDs, err := db.GetNamesWithoutRegisteredDomains(*limit)
	if err != nil {
		return err
	}

	for count, id := range certIDs {
		if count%1024 == 0 {
			statusChan <- OperationStatus{int64(0), int64(count), int64(len(certIDs))}
		}

		err = db.ReprocessRegisteredDomainsForCertId(id)

		if err != nil {
			log.Printf("Problem reprocessing certificate: certID: %d error: %s", id, err)
		}
	}

	return nil
}

func main() {
	iniflags.Parse()
	log.SetFlags(0)
	log.SetPrefix("")
	dbConnectStr, err := recombineURLForDB(*dbConnect)
	if err != nil {
		log.Printf("unable to parse %s: %s", *dbConnect, err)
	}

	if len(dbConnectStr) == 0 || (censysPath == nil && logUrl == nil) {
		flag.Usage()
		os.Exit(2)
	}

	db, err := sql.Open("mysql", dbConnectStr)
	if err != nil {
		log.Fatalf("unable to open SQL: %s: %s", dbConnectStr, err)
	}
	if err = db.Ping(); err != nil {
		log.Fatalf("unable to ping SQL: %s: %s", dbConnectStr, err)
	}

	dialect := gorp.MySQLDialect{Engine: "InnoDB", Encoding: "UTF8"}
	dbMap := &gorp.DbMap{Db: db, Dialect: dialect}
	entriesDb := &sqldb.EntriesDatabase{DbMap: dbMap, Verbose: *verbose, FullCerts: *fullCerts}
	err = entriesDb.InitTables()
	if err != nil {
		log.Fatalf("unable to prepare SQL: %s: %s", dbConnectStr, err)
	}

	if *reproNames {
		wg := new(sync.WaitGroup)
		err = reprocessNames(entriesDb, wg)
		if err != nil {
			log.Fatalf("error while reprocessing the names: %s", err)
		}
		wg.Wait()
		os.Exit(0)
	}

	if logUrl != nil && len(*logUrl) > 5 {
		ctLogUrl, err := url.Parse(*logUrl)
		if err != nil {
			log.Fatalf("unable to set Certificate Log: %s", err)
		}

		ctLog := client.New(*logUrl)

		err = downloadLog(ctLogUrl, ctLog, entriesDb)
		if err != nil {
			log.Fatalf("error while updating CT entries: %s", err)
		}

		os.Exit(0)
	}

	if censysPath != nil && len(*censysPath) > 5 {
		importer := &censysdata.Importer{}
		err = importer.OpenFile(*censysPath)
		if err != nil {
			log.Fatalf("unable to open Censys file: %s", err)
		}
		defer importer.Close()

		wg := new(sync.WaitGroup)
		err := processImporter(importer, entriesDb, wg)

		if err != nil {
			log.Fatalf("error while running importer: %s", err)
		}

		wg.Wait()
		os.Exit(0)
	}

	// Didn't include a mandatory action, so print usage and exit.
	flag.Usage()
	os.Exit(2)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"os"
	"sort"
	"strings"

	"github.com/ryanuber/columnize"
	"github.com/tylerfowle/dtags/db"
)

var database *db.Database

func main() {
	var err error

	database, err = db.Init()
	if err != nil {
		panic(err)
	}

	defer database.Instance.Close()

	cmd := os.Args[1]
	args := os.Args[2:]

	switch cmd {
	case "add":
		addNewTag(args)
		break
	case "del":
		database.DeleteKey(strings.ToLower(args[0]))
		break
	case "list", "completion":
		printAllTags()
		break
	case "ls":
		printBoth()
		break
	default:
		args := os.Args[1:]
		printPath(args)
	}
}

func addNewTag(args []string) {
	k := strings.ToLower(args[0])
	v := database.CurrentDirectory

	if len(args[0:]) > 1 {
		v = args[1]
	}

	if database.Exists(k) {
		fmt.Printf("Overwrite existing tag? [%s] (y/n)", k)
		if confirmation() == false {
			return
		}
	}

	database.AddKey(k, v)
}

func printAllTags() {
	for _, tag := range database.GetTags() {
		fmt.Println(tag)
	}
}

func printBoth() {
	var unformattedlist []string
	for tag, path := range database.All() {
		unformattedlist = append(unformattedlist, fmt.Sprintf("%s|%s\n", tag, path))
	}
	sort.Strings(unformattedlist)
	formattedList := columnize.SimpleFormat(unformattedlist)
	fmt.Println(formattedList)
}

func printPath(args []string) {

	cwd := database.GetValue(args[0])
	if cwd == "" {
		fmt.Printf("tag not found\n")
		os.Exit(1)
	}

	fmt.Fprint(os.Stdout, cwd)
	os.Exit(1)

}

func confirmation() bool {
	var response string

	_, err := fmt.Scanln(&response)
	if err != nil {
		log.Fatal(err)
	}
	y := []string{"y", "Y", "yes", "Yes", "YES"}
	n := []string{"n", "N", "no", "No", "NO"}

	response = strings.TrimSpace(response)
	response = strings.ToLower(response)

	if containsString(y, response) {
		return true
	} else if containsString(n, response) {
		return false
	} else {
		fmt.Println("yes or no required:")
		return confirmation()
	}
}

func posString(slice []string, element string) int {
	for index, elem := range slice {
		if elem == element {
			return index
		}
	}
	return -1
}

// containsString returns true iff slice contains element
func containsString(slice []string, element string) bool {
	return !(posString(slice, element) == -1)
}
<commit_msg>clean up confim strings<commit_after>package main

import (
	"fmt"
	"log"
	"os"
	"sort"
	"strings"

	"github.com/ryanuber/columnize"
	"github.com/tylerfowle/dtags/db"
)

var database *db.Database

func main() {
	var err error

	database, err = db.Init()
	if err != nil {
		panic(err)
	}

	defer database.Instance.Close()

	cmd := os.Args[1]
	args := os.Args[2:]

	switch cmd {
	case "add":
		addNewTag(args)
		break
	case "del":
		database.DeleteKey(strings.ToLower(args[0]))
		break
	case "list", "completion":
		printAllTags()
		break
	case "ls":
		printBoth()
		break
	default:
		args := os.Args[1:]
		printPath(args)
	}
}

func addNewTag(args []string) {
	k := strings.ToLower(args[0])
	v := database.CurrentDirectory

	if len(args[0:]) > 1 {
		v = args[1]
	}

	if database.Exists(k) {
		fmt.Printf("Overwrite existing tag? [%s] (y/n)", k)
		if confirmation() == false {
			return
		}
	}

	database.AddKey(k, v)
}

func printAllTags() {
	for _, tag := range database.GetTags() {
		fmt.Println(tag)
	}
}

func printBoth() {
	var unformattedlist []string
	for tag, path := range database.All() {
		unformattedlist = append(unformattedlist, fmt.Sprintf("%s|%s\n", tag, path))
	}
	sort.Strings(unformattedlist)
	formattedList := columnize.SimpleFormat(unformattedlist)
	fmt.Println(formattedList)
}

func printPath(args []string) {
	cwd := database.GetValue(args[0])
	if cwd == "" {
		fmt.Printf("tag not found\n")
		os.Exit(1)
	}

	fmt.Fprint(os.Stdout, cwd)
	os.Exit(1)
}

func confirmation() bool {
	var response string

	_, err := fmt.Scanln(&response)
	if err != nil {
		log.Fatal(err)
	}
	y := []string{"y", "yes"}
	n := []string{"n", "no"}

	response = strings.TrimSpace(response)
	response = strings.ToLower(response)

	if containsString(y, response) {
		return true
	} else if containsString(n, response) {
		return false
	} else {
		fmt.Println("yes or no required:")
		return confirmation()
	}
}

func posString(slice []string, element string) int {
	for index, elem := range slice {
		if elem == element {
			return index
		}
	}
	return -1
}

// containsString returns true iff slice contains element
func containsString(slice []string, element string) bool {
	return !(posString(slice, element) == -1)
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/base64"
	"encoding/hex"
	"fmt"
	"io/ioutil"
	"os"

	"github.com/midnightfreddie/McpeTool/api"
	"github.com/midnightfreddie/McpeTool/world"
	"github.com/urfave/cli"
)

func main() {
	app := cli.NewApp()
	app.Name = "MCPE Tool"
	app.Version = "0.1.0"
	app.Usage = "Reads and writes a Minecraft Pocket Edition world directory."

	app.Commands = []cli.Command{
		{
			Name:      "api",
			Aliases:   []string{"www"},
			ArgsUsage: "\"<path/to/world>\"",
			Usage:     "Open world, start API at http://127.0.0.1:8080 . Control-c to exit.",
			Action: func(c *cli.Context) error {
				world, err := world.OpenWorld(c.Args().First())
				if err != nil {
					panic("error")
				}
				defer world.Close()
				err = api.Server(&world)
				if err != nil {
					panic("error")
				}
				return nil
			},
		},
		{
			Name:      "keys",
			Aliases:   []string{"k"},
			ArgsUsage: "\"<path/to/world>\"",
			Usage:     "Lists all keys in the database.",
			Action: func(c *cli.Context) error {
				world, err := world.OpenWorld(c.Args().First())
				if err != nil {
					return err
				}
				defer world.Close()
				keys, err := world.GetKeys()
				if err != nil {
					return err
				}
				for i := 0; i < len(keys); i++ {
					fmt.Println(hex.EncodeToString(keys[i]))
				}
				return nil
			},
		},
		{
			Name:      "get",
			ArgsUsage: "\"<path/to/world>\" <key>",
			Usage:     "Retruns a key's value in base64 format.",
			Flags: []cli.Flag{
				cli.BoolFlag{
					Name:  "dump, d",
					Usage: "Display value as hexdump",
				},
			},
			Action: func(c *cli.Context) error {
				world, err := world.OpenWorld(c.Args().First())
				if err != nil {
					return err
				}
				defer world.Close()
				key, err := hex.DecodeString(c.Args().Get(1))
				if err != nil {
					return err
				}
				value, err := world.Get(key)
				if err != nil {
					return err
				}
				if c.String("dump") == "true" {
					fmt.Println(hex.Dump(value))
				} else {
					fmt.Println(base64.StdEncoding.EncodeToString(value))
				}
				return nil
			},
		},
		{
			Name:      "put",
			ArgsUsage: "\"<path/to/world>\" <key>",
			Usage:     "Put a key/value into the DB. The base64-encoded value read from stdin.",
			Action: func(c *cli.Context) error {
				world, err := world.OpenWorld(c.Args().First())
				key, err := hex.DecodeString(c.Args().Get(1))
				if err != nil {
					return err
				}
				if err != nil {
					return err
				}
				defer world.Close()
				base64Data, err := ioutil.ReadAll(os.Stdin)
				if err != nil {
					return err
				}
				value, err := base64.StdEncoding.DecodeString(string(base64Data[:]))
				if err != nil {
					return err
				}
				err = world.Put(key, value)
				if err != nil {
					return err
				}
				return nil
			},
		},
		{
			Name:      "delete",
			ArgsUsage: "\"<path/to/world>\" <key>",
			Usage:     "Deletes a key and its value.",
			Action: func(c *cli.Context) error {
				world, err := world.OpenWorld(c.Args().First())
				if err != nil {
					return err
				}
				defer world.Close()
				key, err := hex.DecodeString(c.Args().Get(1))
				if err != nil {
					return err
				}
				err = world.Delete(key)
				if err != nil {
					return err
				}
				return nil
			},
		},
	}

	app.Run(os.Args)
}
<commit_msg>Incremented to v0.1.1 . Because I mis-tagged v0.1.0 and released the wrong version.<commit_after>package main

import (
	"encoding/base64"
	"encoding/hex"
	"fmt"
	"io/ioutil"
	"os"

	"github.com/midnightfreddie/McpeTool/api"
	"github.com/midnightfreddie/McpeTool/world"
	"github.com/urfave/cli"
)

func main() {
	app := cli.NewApp()
	app.Name = "MCPE Tool"
	app.Version = "0.1.1"
	app.Usage = "Reads and writes a Minecraft Pocket Edition world directory."

	app.Commands = []cli.Command{
		{
			Name:      "api",
			Aliases:   []string{"www"},
			ArgsUsage: "\"<path/to/world>\"",
			Usage:     "Open world, start API at http://127.0.0.1:8080 . Control-c to exit.",
			Action: func(c *cli.Context) error {
				world, err := world.OpenWorld(c.Args().First())
				if err != nil {
					panic("error")
				}
				defer world.Close()
				err = api.Server(&world)
				if err != nil {
					panic("error")
				}
				return nil
			},
		},
		{
			Name:      "keys",
			Aliases:   []string{"k"},
			ArgsUsage: "\"<path/to/world>\"",
			Usage:     "Lists all keys in the database.",
			Action: func(c *cli.Context) error {
				world, err := world.OpenWorld(c.Args().First())
				if err != nil {
					return err
				}
				defer world.Close()
				keys, err := world.GetKeys()
				if err != nil {
					return err
				}
				for i := 0; i < len(keys); i++ {
					fmt.Println(hex.EncodeToString(keys[i]))
				}
				return nil
			},
		},
		{
			Name:      "get",
			ArgsUsage: "\"<path/to/world>\" <key>",
			Usage:     "Retruns a key's value in base64 format.",
			Flags: []cli.Flag{
				cli.BoolFlag{
					Name:  "dump, d",
					Usage: "Display value as hexdump",
				},
			},
			Action: func(c *cli.Context) error {
				world, err := world.OpenWorld(c.Args().First())
				if err != nil {
					return err
				}
				defer world.Close()
				key, err := hex.DecodeString(c.Args().Get(1))
				if err != nil {
					return err
				}
				value, err := world.Get(key)
				if err != nil {
					return err
				}
				if c.String("dump") == "true" {
					fmt.Println(hex.Dump(value))
				} else {
					fmt.Println(base64.StdEncoding.EncodeToString(value))
				}
				return nil
			},
		},
		{
			Name:      "put",
			ArgsUsage: "\"<path/to/world>\" <key>",
			Usage:     "Put a key/value into the DB. The base64-encoded value read from stdin.",
			Action: func(c *cli.Context) error {
				world, err := world.OpenWorld(c.Args().First())
				key, err := hex.DecodeString(c.Args().Get(1))
				if err != nil {
					return err
				}
				if err != nil {
					return err
				}
				defer world.Close()
				base64Data, err := ioutil.ReadAll(os.Stdin)
				if err != nil {
					return err
				}
				value, err := base64.StdEncoding.DecodeString(string(base64Data[:]))
				if err != nil {
					return err
				}
				err = world.Put(key, value)
				if err != nil {
					return err
				}
				return nil
			},
		},
		{
			Name:      "delete",
			ArgsUsage: "\"<path/to/world>\" <key>",
			Usage:     "Deletes a key and its value.",
			Action: func(c *cli.Context) error {
				world, err := world.OpenWorld(c.Args().First())
				if err != nil {
					return err
				}
				defer world.Close()
				key, err := hex.DecodeString(c.Args().Get(1))
				if err != nil {
					return err
				}
				err = world.Delete(key)
				if err != nil {
					return err
				}
				return nil
			},
		},
	}

	app.Run(os.Args)
}
<|endoftext|>


<commit_before>// A project to simulate traffic navigation in the city of Hastings.
//
// Team members: Frederick Stoddart, Levi Fraser-Daley, Nikolas Burke
package main

import "fmt"

type funCityLoc struct {
	name string
	outsideCity bool
}

type funStreet struct {
	name string
	exit funExit
}

type funExit string

type funDriver struct {
	number int
	name string
}

var hastings = []funCityLoc{
	{"Mayfair", false},
	{"Akina", false},
	{"Stortford Lodge", false},
	{"Mahora", false},
	{"Outside City", true},
}

// Main() :p
func main() {

	fmt.Println(hastings)

}
<commit_msg>Added, FunCity Drivers, array of object<commit_after>// A project to simulate traffic navigation in the city of Hastings.
//
// Team members: Frederick Stoddart, Levi Fraser-Daley, Nikolas Burke
package main

import "fmt"

// A location representing a suburb in a city
type funCityLoc struct {
	name        string
	outsideCity bool
}

//
type funStreet struct {
	name string
	exit funExit
}

type funExit string

type funDriver struct {
	number int
	name   string
}

var hastings = []funCityLoc{
	{"Mayfair", false},
	{"Akina", false},
	{"Stortford Lodge", false},
	{"Mahora", false},
	{"Outside City", true},
}

var drivers = []funDriver{
	{1, "Fred"},
	{2, "Caitlyn"},
	{3, "Mason"},
	{4, "Bea"},
	{5, "Tara"},
}

// Main() :p
func main() {

	fmt.Println(hastings)
	fmt.Println(drivers)

}
<|endoftext|>


<commit_before>// Copyright 2017 Istio 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 cmd

import (
	"github.com/spf13/cobra"

	"istio.io/istio/mixer/cmd/shared"
	"istio.io/istio/mixer/pkg/adapter"
	"istio.io/istio/mixer/pkg/il/evaluator"
	mixerRuntime "istio.io/istio/mixer/pkg/runtime"
	"istio.io/istio/mixer/pkg/server"
	"istio.io/istio/mixer/pkg/template"
	"istio.io/istio/pkg/version"
)

func serverCmd(info map[string]template.Info, adapters []adapter.InfoFn, printf, fatalf shared.FormatFn) *cobra.Command {
	sa := server.NewArgs()
	sa.Templates = info
	sa.Adapters = adapters

	serverCmd := &cobra.Command{
		Use:   "server",
		Short: "Starts Mixer as a server",
		Run: func(cmd *cobra.Command, args []string) {
			runServer(sa, printf, fatalf)
		},
	}

	// TODO: need to pick appropriate defaults for all these settings below

	serverCmd.PersistentFlags().Uint16VarP(&sa.APIPort, "port", "p", 9091, "TCP port to use for Mixer's gRPC API")
	serverCmd.PersistentFlags().Uint16Var(&sa.MonitoringPort, "monitoringPort", 9093, "HTTP port to use for the exposing mixer self-monitoring information")
	serverCmd.PersistentFlags().UintVarP(&sa.MaxMessageSize, "maxMessageSize", "", 1024*1024, "Maximum size of individual gRPC messages")
	serverCmd.PersistentFlags().UintVarP(&sa.MaxConcurrentStreams, "maxConcurrentStreams", "", 1024, "Maximum number of outstanding RPCs per connection")
	serverCmd.PersistentFlags().IntVarP(&sa.APIWorkerPoolSize, "apiWorkerPoolSize", "", 1024, "Max number of goroutines in the API worker pool")
	serverCmd.PersistentFlags().IntVarP(&sa.AdapterWorkerPoolSize, "adapterWorkerPoolSize", "", 1024, "Max number of goroutines in the adapter worker pool")
	// TODO: what is the right default value for expressionEvalCacheSize.
	serverCmd.PersistentFlags().IntVarP(&sa.ExpressionEvalCacheSize, "expressionEvalCacheSize", "", evaluator.DefaultCacheSize,
		"Number of entries in the expression cache")
	serverCmd.PersistentFlags().BoolVarP(&sa.SingleThreaded, "singleThreaded", "", false,
		"If true, each request to Mixer will be executed in a single go routine (useful for debugging)")

	serverCmd.PersistentFlags().StringVarP(&sa.ConfigStoreURL, "configStoreURL", "", "",
		"URL of the config store. Use k8s://path_to_kubeconfig or fs:// for file system. If path_to_kubeconfig is empty, in-cluster kubeconfig is used.")

	serverCmd.PersistentFlags().StringVarP(&sa.ConfigDefaultNamespace, "configDefaultNamespace", "", mixerRuntime.DefaultConfigNamespace,
		"Namespace used to store mesh wide configuration.")

	// Hide configIdentityAttribute and configIdentityAttributeDomain until we have a need to expose them.
	// These parameters ensure that rest of Mixer makes no assumptions about specific identity attribute.
	// Rules selection is based on scopes.
	serverCmd.PersistentFlags().StringVarP(&sa.ConfigIdentityAttribute, "configIdentityAttribute", "", "destination.service",
		"Attribute that is used to identify applicable scopes.")
	if err := serverCmd.PersistentFlags().MarkHidden("configIdentityAttribute"); err != nil {
		fatalf("unable to hide: %v", err)
	}
	serverCmd.PersistentFlags().StringVarP(&sa.ConfigIdentityAttributeDomain, "configIdentityAttributeDomain", "", "svc.cluster.local",
		"The domain to which all values of the configIdentityAttribute belong. For kubernetes services it is svc.cluster.local")
	if err := serverCmd.PersistentFlags().MarkHidden("configIdentityAttributeDomain"); err != nil {
		fatalf("unable to hide: %v", err)
	}
	serverCmd.PersistentFlags().StringVar(&sa.LivenessProbeOptions.Path, "livenessProbePath", "",
		"Path to the file for the liveness probe.")
	serverCmd.PersistentFlags().DurationVar(&sa.LivenessProbeOptions.UpdateInterval, "livenessProbeInterval", 0,
		"Interval of updating file for the liveness probe.")
	serverCmd.PersistentFlags().StringVar(&sa.ReadinessProbeOptions.Path, "readinessProbePath", "",
		"Path to the file for the readiness probe.")
	serverCmd.PersistentFlags().DurationVar(&sa.ReadinessProbeOptions.UpdateInterval, "readinessProbeInterval", 0,
		"Interval of updating file for the readiness probe.")

	// TODO: Remove all this stuff by the 0.5 release (don't forget all associated YAML templates and any other uses of these options in the code
	// base & docs)
	var dummy string
	var dummy2 uint16
	var dummy3 uint
	serverCmd.PersistentFlags().StringVarP(&sa.ConfigStoreURL, "configStore2URL", "", "", "deprecated")
	serverCmd.PersistentFlags().StringVarP(&dummy, "serviceConfigFile", "", "", "deprecated")
	serverCmd.PersistentFlags().StringVarP(&dummy, "globalConfigFile", "", "", "deprecated")
	serverCmd.PersistentFlags().Uint16VarP(&dummy2, "configAPIPort", "", 0, "deprecated")
	serverCmd.PersistentFlags().UintVarP(&dummy3, "configFetchInterval", "", 0, "deprecated")
	_ = serverCmd.PersistentFlags().MarkDeprecated("configStore2URL", "")
	_ = serverCmd.PersistentFlags().MarkDeprecated("serviceConfigFile", "")
	_ = serverCmd.PersistentFlags().MarkDeprecated("globalConfigFile", "")
	_ = serverCmd.PersistentFlags().MarkDeprecated("configAPIPort", "")
	_ = serverCmd.PersistentFlags().MarkDeprecated("configFetchInterval", "")
	_ = serverCmd.PersistentFlags().MarkHidden("configStore2URL")
	_ = serverCmd.PersistentFlags().MarkHidden("serviceConfigFile")
	_ = serverCmd.PersistentFlags().MarkHidden("globalConfigFile")
	_ = serverCmd.PersistentFlags().MarkHidden("configAPIPort")
	_ = serverCmd.PersistentFlags().MarkHidden("configFetchInterval")

	sa.LoggingOptions.AttachCobraFlags(serverCmd)
	sa.TracingOptions.AttachCobraFlags(serverCmd)

	return serverCmd
}

func runServer(sa *server.Args, printf, fatalf shared.FormatFn) {
	printf("Mixer started with\n%s", sa)

	s, err := server.New(sa)
	if err != nil {
		fatalf("Unable to initialize Mixer: %v", err)
	}

	printf("Istio Mixer: %s", version.Info)
	printf("Starting gRPC server on port %v", sa.APIPort)

	s.Run()
	err = s.Wait()
	if err != nil {
		fatalf("Mixer unexpectedly terminated: %v", err)
	}

	_ = s.Close()
}
<commit_msg>Add command-line flags for controlling the use of the new runtime. (#3454)<commit_after>// Copyright 2017 Istio 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 cmd

import (
	"github.com/spf13/cobra"

	"istio.io/istio/mixer/cmd/shared"
	"istio.io/istio/mixer/pkg/adapter"
	"istio.io/istio/mixer/pkg/il/evaluator"
	mixerRuntime "istio.io/istio/mixer/pkg/runtime"
	"istio.io/istio/mixer/pkg/server"
	"istio.io/istio/mixer/pkg/template"
	"istio.io/istio/pkg/version"
)

func serverCmd(info map[string]template.Info, adapters []adapter.InfoFn, printf, fatalf shared.FormatFn) *cobra.Command {
	sa := server.NewArgs()
	sa.Templates = info
	sa.Adapters = adapters

	serverCmd := &cobra.Command{
		Use:   "server",
		Short: "Starts Mixer as a server",
		Run: func(cmd *cobra.Command, args []string) {
			runServer(sa, printf, fatalf)
		},
	}

	// TODO: need to pick appropriate defaults for all these settings below

	serverCmd.PersistentFlags().Uint16VarP(&sa.APIPort, "port", "p", 9091, "TCP port to use for Mixer's gRPC API")
	serverCmd.PersistentFlags().Uint16Var(&sa.MonitoringPort, "monitoringPort", 9093, "HTTP port to use for the exposing mixer self-monitoring information")
	serverCmd.PersistentFlags().UintVarP(&sa.MaxMessageSize, "maxMessageSize", "", 1024*1024, "Maximum size of individual gRPC messages")
	serverCmd.PersistentFlags().UintVarP(&sa.MaxConcurrentStreams, "maxConcurrentStreams", "", 1024, "Maximum number of outstanding RPCs per connection")
	serverCmd.PersistentFlags().IntVarP(&sa.APIWorkerPoolSize, "apiWorkerPoolSize", "", 1024, "Max number of goroutines in the API worker pool")
	serverCmd.PersistentFlags().IntVarP(&sa.AdapterWorkerPoolSize, "adapterWorkerPoolSize", "", 1024, "Max number of goroutines in the adapter worker pool")
	// TODO: what is the right default value for expressionEvalCacheSize.
	serverCmd.PersistentFlags().IntVarP(&sa.ExpressionEvalCacheSize, "expressionEvalCacheSize", "", evaluator.DefaultCacheSize,
		"Number of entries in the expression cache")
	serverCmd.PersistentFlags().BoolVarP(&sa.UseNewRuntime, "useNewRuntime", "", false, "Use the new runtime code for processing requests.")
	serverCmd.PersistentFlags().BoolVarP(&sa.SingleThreaded, "singleThreaded", "", false,
		"If true, each request to Mixer will be executed in a single go routine (useful for debugging)")

	serverCmd.PersistentFlags().StringVarP(&sa.ConfigStoreURL, "configStoreURL", "", "",
		"URL of the config store. Use k8s://path_to_kubeconfig or fs:// for file system. If path_to_kubeconfig is empty, in-cluster kubeconfig is used.")

	serverCmd.PersistentFlags().StringVarP(&sa.ConfigDefaultNamespace, "configDefaultNamespace", "", mixerRuntime.DefaultConfigNamespace,
		"Namespace used to store mesh wide configuration.")

	// Hide configIdentityAttribute and configIdentityAttributeDomain until we have a need to expose them.
	// These parameters ensure that rest of Mixer makes no assumptions about specific identity attribute.
	// Rules selection is based on scopes.
	serverCmd.PersistentFlags().StringVarP(&sa.ConfigIdentityAttribute, "configIdentityAttribute", "", "destination.service",
		"Attribute that is used to identify applicable scopes.")
	if err := serverCmd.PersistentFlags().MarkHidden("configIdentityAttribute"); err != nil {
		fatalf("unable to hide: %v", err)
	}
	serverCmd.PersistentFlags().StringVarP(&sa.ConfigIdentityAttributeDomain, "configIdentityAttributeDomain", "", "svc.cluster.local",
		"The domain to which all values of the configIdentityAttribute belong. For kubernetes services it is svc.cluster.local")
	if err := serverCmd.PersistentFlags().MarkHidden("configIdentityAttributeDomain"); err != nil {
		fatalf("unable to hide: %v", err)
	}
	serverCmd.PersistentFlags().StringVar(&sa.LivenessProbeOptions.Path, "livenessProbePath", "",
		"Path to the file for the liveness probe.")
	serverCmd.PersistentFlags().DurationVar(&sa.LivenessProbeOptions.UpdateInterval, "livenessProbeInterval", 0,
		"Interval of updating file for the liveness probe.")
	serverCmd.PersistentFlags().StringVar(&sa.ReadinessProbeOptions.Path, "readinessProbePath", "",
		"Path to the file for the readiness probe.")
	serverCmd.PersistentFlags().DurationVar(&sa.ReadinessProbeOptions.UpdateInterval, "readinessProbeInterval", 0,
		"Interval of updating file for the readiness probe.")

	// TODO: Remove all this stuff by the 0.5 release (don't forget all associated YAML templates and any other uses of these options in the code
	// base & docs)
	var dummy string
	var dummy2 uint16
	var dummy3 uint
	serverCmd.PersistentFlags().StringVarP(&sa.ConfigStoreURL, "configStore2URL", "", "", "deprecated")
	serverCmd.PersistentFlags().StringVarP(&dummy, "serviceConfigFile", "", "", "deprecated")
	serverCmd.PersistentFlags().StringVarP(&dummy, "globalConfigFile", "", "", "deprecated")
	serverCmd.PersistentFlags().Uint16VarP(&dummy2, "configAPIPort", "", 0, "deprecated")
	serverCmd.PersistentFlags().UintVarP(&dummy3, "configFetchInterval", "", 0, "deprecated")
	_ = serverCmd.PersistentFlags().MarkDeprecated("configStore2URL", "")
	_ = serverCmd.PersistentFlags().MarkDeprecated("serviceConfigFile", "")
	_ = serverCmd.PersistentFlags().MarkDeprecated("globalConfigFile", "")
	_ = serverCmd.PersistentFlags().MarkDeprecated("configAPIPort", "")
	_ = serverCmd.PersistentFlags().MarkDeprecated("configFetchInterval", "")
	_ = serverCmd.PersistentFlags().MarkHidden("configStore2URL")
	_ = serverCmd.PersistentFlags().MarkHidden("serviceConfigFile")
	_ = serverCmd.PersistentFlags().MarkHidden("globalConfigFile")
	_ = serverCmd.PersistentFlags().MarkHidden("configAPIPort")
	_ = serverCmd.PersistentFlags().MarkHidden("configFetchInterval")

	sa.LoggingOptions.AttachCobraFlags(serverCmd)
	sa.TracingOptions.AttachCobraFlags(serverCmd)

	return serverCmd
}

func runServer(sa *server.Args, printf, fatalf shared.FormatFn) {
	printf("Mixer started with\n%s", sa)

	s, err := server.New(sa)
	if err != nil {
		fatalf("Unable to initialize Mixer: %v", err)
	}

	printf("Istio Mixer: %s", version.Info)
	printf("Starting gRPC server on port %v", sa.APIPort)

	s.Run()
	err = s.Wait()
	if err != nil {
		fatalf("Mixer unexpectedly terminated: %v", err)
	}

	_ = s.Close()
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"strings"
)

func main() {
	stat, err := os.Stdin.Stat()
	if err != nil {
		log.Fatal(err)
	}
	if stat.Mode()&os.ModeCharDevice != 0 {
		log.Fatal("please pipe in some data")
	}

	s := bufio.NewScanner(os.Stdin)
	for s.Scan() {
		t := s.Text()
		line := strings.TrimSpace(s.Text())
		if strings.HasPrefix(line, "nnf:") {
			printNotNilFatal(t)
		} else if strings.HasPrefix(line, "lpf(") {
			printLogPrintf(t)
		} else if strings.HasPrefix(line, "fpf(") {
			fPrintf(t)
		} else if strings.HasPrefix(line, "fpl(") {
			fPrintln(t)
		} else if strings.HasPrefix(line, "hfunc") {
			httpHandlerFunc(t)
		} else if strings.HasPrefix(line, "lpl(") {
			lPrintln(t)
		} else if line == "gomain" {
			goMain()
		} else if line == "pymain" {
			pyMain()
		} else if line == "wo:" {
			pyOpenWrite(t)
		} else if line == "ubb" {
			fmt.Println("#!/usr/bin/env bash")
		} else if line == "ubp" {
			fmt.Println("#!/usr/bin/env python")
		} else if strings.Contains(t, "(t.t)") {
			fmt.Println(strings.Replace(t, "(t.t)", "(t *testing.T)", 1))
		} else {
			fmt.Println(t)
		}
	}
}

func printNotNilFatal(line string) {
	l := len(line) - len(strings.TrimLeft(line, " "))
	pad := strings.Repeat(" ", l)
	msg := strings.SplitN(line, ":", 2)[1]

	// print error block
	fmt.Printf("%sif err != nil{\n", pad)
	fmt.Printf("%s%slog.Fatal(%q, err)\n", pad, pad, msg+": ")
	fmt.Printf("%s}\n", pad)
}

func printLogPrintf(line string) {
	fmt.Println(strings.Replace(line, "lpf(", "log.Printf(", 1))
}

func fPrintf(line string) {
	fmt.Println(strings.Replace(line, "fpf(", "fmt.Printf(", 1))
}

func lPrintln(line string) {
	fmt.Println(strings.Replace(line, "lpl(", "log.Println(", 1))
}

func fPrintln(line string) {
	fmt.Println(strings.Replace(line, "fpl(", "fmt.Println(", 1))
}

func goMain() {
	fmt.Println(`package main

import (
    "fmt"
)

func main() {
    fmt.Println("gopher")
}
`)
}

func pyMain() {
	fmt.Println(`#!/usr/bin/env python
"""
You should probably write something here.
"""

from __future__ import unicode_literals

def main():
    """
    Do the thing.
    """
    print "python"

if __name__ == '__main__':
    main()
`)
}

func httpHandlerFunc(line string) {
	name := strings.Split(line, " ")[1]
	fmt.Printf("func %s(w http.ResponseWriter, r *http.Request){\n", name)
}

func pyOpenWrite(line string) {
	l := len(line) - len(strings.TrimLeft(line, " "))
	pad := strings.Repeat(" ", l)
	lines := []string{
		`with open("out.txt", "wb") as raw:`,
		`    raw.write("{0}\n".format(msg))`,
	}

	for _, line = range lines {
		fmt.Printf("%s%s\n", pad, line)
	}

}
<commit_msg>various additions<commit_after>package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"strings"
)

func main() {
	stat, err := os.Stdin.Stat()
	if err != nil {
		log.Fatal(err)
	}
	if stat.Mode()&os.ModeCharDevice != 0 {
		log.Fatal("please pipe in some data")
	}

	s := bufio.NewScanner(os.Stdin)
	for s.Scan() {
		t := s.Text()
		line := strings.TrimSpace(s.Text())
		if strings.HasPrefix(line, "nnf") {
			printNotNilFatal(t)
		} else if strings.HasPrefix(line, "lpf(") {
			printLogPrintf(t)
		} else if strings.HasPrefix(line, "fpf(") {
			fPrintf(t)
		} else if strings.HasPrefix(line, "fpl(") {
			fPrintln(t)
		} else if strings.HasPrefix(line, "hfunc") {
			httpHandlerFunc(t)
		} else if strings.HasPrefix(line, "lpl(") {
			lPrintln(t)
		} else if strings.HasPrefix(line, "clog(") {
			consoleLog(t)
		} else if strings.HasPrefix(line, "clogVar") {
			consoleLogVar(line)
		} else if line == "gomain" {
			goMain()
		} else if line == "gows" {
			goWebserver()
		} else if line == "pymain" {
			pyMain()
		} else if line == "ul" {
			unorderedList()
		} else if line == "html5" {
			html5()
		} else if line == "wo:" {
			pyOpenWrite(t)
		} else if line == "ubb" {
			fmt.Println("#!/usr/bin/env bash")
		} else if line == "ubp" {
			fmt.Println("#!/usr/bin/env python")
		} else if strings.Contains(t, "(t.t)") {
			fmt.Println(strings.Replace(t, "(t.t)", "(t *testing.T)", 1))
		} else {
			fmt.Println(t)
		}
	}
}

func printNotNilFatal(line string) {
	l := len(line) - len(strings.TrimLeft(line, " "))
	pad := strings.Repeat(" ", l)
	msg := strings.SplitN(line, ":", 2)[1]

	// print error block
	fmt.Printf("%sif err != nil{\n", pad)
	fmt.Printf("%s%slog.Fatal(%q, err)\n", pad, pad, msg+": ")
	fmt.Printf("%s}\n", pad)
}

func printLogPrintf(line string) {
	fmt.Println(strings.Replace(line, "lpf(", "log.Printf(", 1))
}

func fPrintf(line string) {
	fmt.Println(strings.Replace(line, "fpf(", "fmt.Printf(", 1))
}

func lPrintln(line string) {
	fmt.Println(strings.Replace(line, "lpl(", "log.Println(", 1))
}

func consoleLog(line string) {
	fmt.Println(strings.Replace(line, "clog(", "console.log(", 1))
}

func consoleLogVar(line string) {
	name := strings.Split(line, " ")[1]
	fmt.Printf("console.Log(\"%s: \" + %s);\n", name, name)
}

func fPrintln(line string) {
	fmt.Println(strings.Replace(line, "fpl(", "fmt.Println(", 1))
}

func goMain() {
	fmt.Println(`package main

import (
    "fmt"
)

func main() {
    fmt.Println("gopher")
}
`)
}

func goWebserver() {
	fmt.Println(`package main

import (
    "fmt"
	"net/http"
)

func main() {
    http.HandleFunc("/", index)
	http.ListenAndServe(":8080", nil)
}

func index(w http.ResponseWriter, r *http.Request){
	fmt.Fprintf(w, "hello")
}
`)
}

func pyMain() {
	fmt.Println(`#!/usr/bin/env python
"""
You should probably write something here.
"""

from __future__ import unicode_literals

def main():
    """
    Do the thing.
    """
    print "python"

if __name__ == '__main__':
    main()
`)
}

func html5() {
	fmt.Println(`<!DOCTYPE html>

		<meta charset="UTF-8">
		<title>title</title>
		<link rel="stylesheet" href="./css/style.css" type="text/css">
		<meta name="viewport" content="width-device-width, initial-scale=1">

content

`)
}

func httpHandlerFunc(line string) {
	name := strings.Split(line, " ")[1]
	fmt.Printf("func %s(w http.ResponseWriter, r *http.Request){\n", name)
}

func pyOpenWrite(line string) {
	l := len(line) - len(strings.TrimLeft(line, " "))
	pad := strings.Repeat(" ", l)
	lines := []string{
		`with open("out.txt", "wb") as raw:`,
		`    raw.write("{0}\n".format(msg))`,
	}

	for _, line = range lines {
		fmt.Printf("%s%s\n", pad, line)
	}

}

func unorderedList() {
	fmt.Println("
")
	for i := 0; i < 3; i++ {
		fmt.Println("\t
")
		fmt.Println("\t\tthing")
		fmt.Println("\t
")
	}
	fmt.Println("
")

}
<|endoftext|>


<commit_before>// Copyright 2016 Liam Stanley <me@liamstanley.io>. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

// Package girc provides a high level, yet flexible IRC library for use
// with interacting with IRC servers. girc has support for user/channel
// tracking, as well as a few other neat features (like auto-reconnect).
//
// Much of what girc can do, can also be disabled. The goal is to
// provide a solid API that you don't necessarily have to work with out
// of the box if you don't want to.
//
// See "example/main.go" for a brief and very useful example taking
// advantage of girc, that should give you a general idea of how the API
// works.
package girc

import (
	"crypto/tls"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net"
	"time"
)

// TODO's:
//   * ClearCallbacks(CODE)?
//   * Should Client.Message() an other similar methods support errors?
//     * along with this, should we forcefully check to ensure that the target
//       of the events are valid?
//   * track connection time (conntime? in state)
//   * with conntime, find lag. Client.Lag() would be useful
//   * would be cool to track things like SERVERNAME, VERSION, UMODES,
//     CMODES, etc. also see Config.DisableCapTracking.
//       -- https://github.com/Liamraystanley/Code/blob/master/core/triggers.py#L40-L67
//   * client should support ping tracking (sending PING's to the server)
//   * users need to be exposed in state somehow (other than GetChannels())
//   * ip/host binding?
//   * IsValidNick?
//   * User.Age()? (FirstActive()?) (time since first seen)
//   * cleanup docs in conn.go & event.go.

// Client contains all of the information necessary to run a single IRC
// client.
type Client struct {
	// Config represents the configuration
	Config Config
	// Events is a buffer of events waiting to be processed.
	Events chan *Event
	// Sender is a Sender{} interface implementation.
	Sender Sender

	// state represents the internal state
	state *state
	// initTime represents the creation time of the client.
	initTime time.Time
	// callbacks is an internal mapping of COMMAND -> callback.
	callbacks map[string][]Callback
	// reader is the socket buffer reader from the IRC server.
	reader *Decoder
	// reader is the socket buffer write to the IRC server.
	writer *Encoder
	// conn is a net.Conn reference to the IRC server.
	conn net.Conn
	// tries represents the internal reconnect count to the IRC server.
	tries int
	// log is used if a writer is supplied for Client.Config.Logger.
	log *log.Logger
	// quitChan is used to close the connection to the IRC server.
	quitChan chan struct{}
	// hasQuit is used to determine if we've finished quitting/cleaning up.
	hasQuit bool
}

// Config contains configuration options for an IRC client
type Config struct {
	// Server is a host/ip of the server you want to connect to.
	Server string
	// Port is the port that will be used during server connection.
	Port int
	// Password is the server password used to authenticate.
	Password string
	// Nick is an rfc-valid nickname used during connect.
	Nick string
	// User is the username/ident to use on connect. Ignored if identd server
	// is used.
	User string
	// Name is the "realname" that's used during connect.
	Name string
	// TLSConfig is an optional user-supplied tls configuration, used during
	// socket creation to the server.
	TLSConfig *tls.Config
	// MaxRetries is the number of times the client will attempt to reconnect
	// to the server after the last disconnect.
	MaxRetries int
	// Logger is an optional, user supplied logger to log the raw lines sent
	// from the server. Useful for debugging. Defaults to ioutil.Discard.
	Logger io.Writer
	// ReconnectDelay is the a duration of time to delay before attempting a
	// reconnection. Defaults to 10s (minimum of 10s).
	ReconnectDelay time.Duration
	// DisableTracking disables all channel and user-level tracking. Useful
	// for highly embedded scripts with single purposes.
	DisableTracking bool
	// DisableCapTracking disables all network/server capability tracking.
	// This includes determining what feature the IRC server supports, what
	// the "NETWORK=" variables are, and other useful stuff.
	DisableCapTracking bool
	// DisableNickCollision disables the clients auto-response to nickname
	// collisions. For example, if "test" is already in use, or is blocked by
	// the network/a service, the client will try and use "test_", then it
	// will attempt "test__", "test___", and so on.
	DisableNickCollision bool
}

// New creates a new IRC client with the specified server, name and
// config.
func New(config Config) *Client {
	client := &Client{
		Config:    config,
		Events:    make(chan *Event, 40), // buffer 40 events
		quitChan:  make(chan struct{}),
		callbacks: make(map[string][]Callback),
		tries:     0,
		initTime:  time.Now(),
	}

	// Register builtin helpers.
	client.registerHelpers()

	return client
}

// Quit disconnects from the server.s
func (c *Client) Quit(message string) {
	c.Send(&Event{Command: QUIT, Trailing: message})

	c.hasQuit = true

	if c.conn != nil {
		c.conn.Close()
	}

	c.quitChan <- struct{}{}
}

// Uptime returns the amount of time that has passed since the
// client was created.
func (c *Client) Uptime() time.Duration {
	return time.Since(c.initTime)
}

// Server returns the string representation of host+port pair for net.Conn
func (c *Client) Server() string {
	return fmt.Sprintf("%s:%d", c.Config.Server, c.Config.Port)
}

// Send sends an event to the server. Use Client.RunCallback() if you are
// are simply looking to trigger callbacks with an event.
func (c *Client) Send(event *Event) error {
	// log the event
	if !event.Sensitive {
		c.log.Print("--> ", event.String())
	}

	return c.Sender.Send(event)
}

// Connect attempts to connect to the given IRC server
func (c *Client) Connect() error {
	var conn net.Conn
	var err error

	// Sanity check a few options.
	if c.Config.Server == "" || c.Config.Port == 0 || c.Config.Nick == "" || c.Config.User == "" {
		return errors.New("invalid configuration (server/port/nick/user)")
	}

	// Reset the state.
	c.state = newState()

	if c.Config.Logger == nil {
		c.Config.Logger = ioutil.Discard
	}

	c.log = log.New(c.Config.Logger, "", log.Ldate|log.Ltime|log.Lshortfile)

	if c.Config.TLSConfig == nil {
		conn, err = net.Dial("tcp", c.Server())
	} else {
		conn, err = tls.Dial("tcp", c.Server(), c.Config.TLSConfig)
	}
	if err != nil {
		return err
	}

	c.conn = conn
	c.reader = NewDecoder(conn)
	c.writer = NewEncoder(conn)
	c.Sender = serverSender{writer: c.writer}
	for _, event := range c.connectMessages() {
		if err := c.Send(event); err != nil {
			return err
		}
	}

	c.tries = 0
	go c.ReadLoop()

	// Consider the connection a success at this point.
	c.state.connected = true

	return nil
}

// connectMessages is a list of IRC messages to send when attempting
// to connect to the IRC server.
func (c *Client) connectMessages() (events []*Event) {
	// Passwords first.
	if c.Config.Password != "" {
		events = append(events, &Event{Command: PASS, Params: []string{c.Config.Password}})
	}

	// Then nickname.
	events = append(events, &Event{Command: NICK, Params: []string{c.Config.Nick}})

	// Then username and realname.
	if c.Config.Name == "" {
		c.Config.Name = c.Config.User
	}

	events = append(events, &Event{
		Command:  USER,
		Params:   []string{c.Config.User, "+iw", "*"},
		Trailing: c.Config.Name,
	})

	return events
}

// Reconnect checks to make sure we want to, and then attempts to
// reconnect to the server.
func (c *Client) Reconnect() (err error) {
	if c.hasQuit {
		return nil
	}

	if c.Config.ReconnectDelay < (10 * time.Second) {
		c.Config.ReconnectDelay = 10 * time.Second
	}

	if c.Config.MaxRetries > 0 {
		var err error
		c.conn.Close()

		// Re-setup events.
		c.Events = make(chan *Event, 40)

		// Delay so we're not slaughtering the server with a bunch of
		// connections.
		c.log.Printf("reconnecting to %s in %s", c.Server(), c.Config.ReconnectDelay)
		time.Sleep(c.Config.ReconnectDelay)

		for err = c.Connect(); err != nil && c.tries < c.Config.MaxRetries; c.tries++ {
			c.log.Printf("reconnecting to %s in %s (%d tries)", c.Server(), c.Config.ReconnectDelay, c.tries)
			time.Sleep(c.Config.ReconnectDelay)
		}

		return err
	}

	close(c.Events)
	return nil
}

// ReadLoop sets a timeout of 300 seconds, and then attempts to read
// from the IRC server. If there is an error, it calls Reconnect.
func (c *Client) ReadLoop() error {
	for {
		c.conn.SetDeadline(time.Now().Add(300 * time.Second))
		event, err := c.reader.Decode()
		if err != nil {
			return c.Reconnect()
		}

		c.Events <- event
	}
}

// Loop reads from the events channel and sends the events to be
// handled for every message it receives.
func (c *Client) Loop() {
	for {
		select {
		case event := <-c.Events:
			c.handleEvent(event)
		case <-c.quitChan:
			return
		}
	}
}

// IsConnected returns true if the client is connected to the server.
func (c *Client) IsConnected() bool {
	c.state.m.RLock()
	defer c.state.m.RUnlock()

	return c.state.connected
}

// GetNick returns the current nickname of the active connection.
//
// Returns empty string if tracking is disabled.
func (c *Client) GetNick() string {
	if c.Config.DisableTracking {
		return ""
	}

	c.state.m.RLock()
	defer c.state.m.RUnlock()

	if c.state.nick == "" {
		return c.Config.Nick
	}

	return c.state.nick
}

// SetNick changes the client nickname.
func (c *Client) SetNick(name string) {
	c.state.m.Lock()
	defer c.state.m.Unlock()

	c.state.nick = name
	c.Send(&Event{Command: NICK, Params: []string{name}})
}

// GetChannels returns the active list of channels that the client
// is in.
//
// Returns nil if tracking is disabled.
func (c *Client) GetChannels() map[string]*Channel {
	if c.Config.DisableTracking {
		return nil
	}

	c.state.m.RLock()
	defer c.state.m.RUnlock()

	return c.state.channels
}

// Who tells the client to update it's channel/user records.
//
// Does not update internal state if tracking is disabled.
func (c *Client) Who(target string) {
	c.Send(&Event{Command: WHO, Params: []string{target, "%tcuhn,1"}})
}

// Join attempts to enter an IRC channel with an optional password.
func (c *Client) Join(channel, password string) {
	if password != "" {
		c.Send(&Event{Command: JOIN, Params: []string{channel, password}})
		return
	}

	c.Send(&Event{Command: JOIN, Params: []string{channel}})
}

// Part leaves an IRC channel with an optional leave message.
func (c *Client) Part(channel, message string) {
	if message != "" {
		c.Send(&Event{Command: JOIN, Params: []string{channel}, Trailing: message})
		return
	}

	c.Send(&Event{Command: JOIN, Params: []string{channel}})
}

// Message sends a PRIVMSG to target (either channel, service, or
// user).
func (c *Client) Message(target, message string) {
	c.Send(&Event{Command: PRIVMSG, Params: []string{target}, Trailing: message})
}

// Messagef sends a formated PRIVMSG to target (either channel,
// service, or user).
func (c *Client) Messagef(target, format string, a ...interface{}) {
	c.Message(target, fmt.Sprintf(format, a...))
}

// Action sends a PRIVMSG ACTION (/me) to target (either channel,
// service, or user).
func (c *Client) Action(target, message string) {
	c.Send(&Event{Command: PRIVMSG, Params: []string{target}, Trailing: fmt.Sprintf("\001ACTION %s\001", message)})
}

// Actionf sends a formated PRIVMSG ACTION (/me) to target (either
// channel, service, or user).
func (c *Client) Actionf(target, format string, a ...interface{}) {
	c.Action(target, fmt.Sprintf(format, a...))
}

// Notice sends a NOTICE to target (either channel, service, or user).
func (c *Client) Notice(target, message string) {
	c.Send(&Event{Command: NOTICE, Params: []string{target}, Trailing: message})
}

// Noticef sends a formated NOTICE to target (either channel, service, or user).
func (c *Client) Noticef(target, format string, a ...interface{}) {
	c.Notice(target, fmt.Sprintf(format, a...))
}

// SendRaw sends a raw string back to the server, without carriage returns or
// newlines.
func (c *Client) SendRaw(raw string) {
	e := ParseEvent(raw)
	if e == nil {
		c.log.Printf("invalid event: %q", raw)
		return
	}

	c.Send(e)
}

// SendRawf sends a formated string back to the server, without carriage
// returns or newlines.
func (c *Client) SendRawf(format string, a ...interface{}) {
	c.SendRaw(fmt.Sprintf(format, a...))
}
<commit_msg>remove TODOs from main.go<commit_after>// Copyright 2016 Liam Stanley <me@liamstanley.io>. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

// Package girc provides a high level, yet flexible IRC library for use
// with interacting with IRC servers. girc has support for user/channel
// tracking, as well as a few other neat features (like auto-reconnect).
//
// Much of what girc can do, can also be disabled. The goal is to
// provide a solid API that you don't necessarily have to work with out
// of the box if you don't want to.
//
// See "example/main.go" for a brief and very useful example taking
// advantage of girc, that should give you a general idea of how the API
// works.
package girc

import (
	"crypto/tls"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net"
	"time"
)

// Client contains all of the information necessary to run a single IRC
// client.
type Client struct {
	// Config represents the configuration
	Config Config
	// Events is a buffer of events waiting to be processed.
	Events chan *Event
	// Sender is a Sender{} interface implementation.
	Sender Sender

	// state represents the internal state
	state *state
	// initTime represents the creation time of the client.
	initTime time.Time
	// callbacks is an internal mapping of COMMAND -> callback.
	callbacks map[string][]Callback
	// reader is the socket buffer reader from the IRC server.
	reader *Decoder
	// reader is the socket buffer write to the IRC server.
	writer *Encoder
	// conn is a net.Conn reference to the IRC server.
	conn net.Conn
	// tries represents the internal reconnect count to the IRC server.
	tries int
	// log is used if a writer is supplied for Client.Config.Logger.
	log *log.Logger
	// quitChan is used to close the connection to the IRC server.
	quitChan chan struct{}
	// hasQuit is used to determine if we've finished quitting/cleaning up.
	hasQuit bool
}

// Config contains configuration options for an IRC client
type Config struct {
	// Server is a host/ip of the server you want to connect to.
	Server string
	// Port is the port that will be used during server connection.
	Port int
	// Password is the server password used to authenticate.
	Password string
	// Nick is an rfc-valid nickname used during connect.
	Nick string
	// User is the username/ident to use on connect. Ignored if identd server
	// is used.
	User string
	// Name is the "realname" that's used during connect.
	Name string
	// TLSConfig is an optional user-supplied tls configuration, used during
	// socket creation to the server.
	TLSConfig *tls.Config
	// MaxRetries is the number of times the client will attempt to reconnect
	// to the server after the last disconnect.
	MaxRetries int
	// Logger is an optional, user supplied logger to log the raw lines sent
	// from the server. Useful for debugging. Defaults to ioutil.Discard.
	Logger io.Writer
	// ReconnectDelay is the a duration of time to delay before attempting a
	// reconnection. Defaults to 10s (minimum of 10s).
	ReconnectDelay time.Duration
	// DisableTracking disables all channel and user-level tracking. Useful
	// for highly embedded scripts with single purposes.
	DisableTracking bool
	// DisableCapTracking disables all network/server capability tracking.
	// This includes determining what feature the IRC server supports, what
	// the "NETWORK=" variables are, and other useful stuff.
	DisableCapTracking bool
	// DisableNickCollision disables the clients auto-response to nickname
	// collisions. For example, if "test" is already in use, or is blocked by
	// the network/a service, the client will try and use "test_", then it
	// will attempt "test__", "test___", and so on.
	DisableNickCollision bool
}

// New creates a new IRC client with the specified server, name and
// config.
func New(config Config) *Client {
	client := &Client{
		Config:    config,
		Events:    make(chan *Event, 40), // buffer 40 events
		quitChan:  make(chan struct{}),
		callbacks: make(map[string][]Callback),
		tries:     0,
		initTime:  time.Now(),
	}

	// Register builtin helpers.
	client.registerHelpers()

	return client
}

// Quit disconnects from the server.s
func (c *Client) Quit(message string) {
	c.Send(&Event{Command: QUIT, Trailing: message})

	c.hasQuit = true

	if c.conn != nil {
		c.conn.Close()
	}

	c.quitChan <- struct{}{}
}

// Uptime returns the amount of time that has passed since the
// client was created.
func (c *Client) Uptime() time.Duration {
	return time.Since(c.initTime)
}

// Server returns the string representation of host+port pair for net.Conn
func (c *Client) Server() string {
	return fmt.Sprintf("%s:%d", c.Config.Server, c.Config.Port)
}

// Send sends an event to the server. Use Client.RunCallback() if you are
// are simply looking to trigger callbacks with an event.
func (c *Client) Send(event *Event) error {
	// log the event
	if !event.Sensitive {
		c.log.Print("--> ", event.String())
	}

	return c.Sender.Send(event)
}

// Connect attempts to connect to the given IRC server
func (c *Client) Connect() error {
	var conn net.Conn
	var err error

	// Sanity check a few options.
	if c.Config.Server == "" || c.Config.Port == 0 || c.Config.Nick == "" || c.Config.User == "" {
		return errors.New("invalid configuration (server/port/nick/user)")
	}

	// Reset the state.
	c.state = newState()

	if c.Config.Logger == nil {
		c.Config.Logger = ioutil.Discard
	}

	c.log = log.New(c.Config.Logger, "", log.Ldate|log.Ltime|log.Lshortfile)

	if c.Config.TLSConfig == nil {
		conn, err = net.Dial("tcp", c.Server())
	} else {
		conn, err = tls.Dial("tcp", c.Server(), c.Config.TLSConfig)
	}
	if err != nil {
		return err
	}

	c.conn = conn
	c.reader = NewDecoder(conn)
	c.writer = NewEncoder(conn)
	c.Sender = serverSender{writer: c.writer}
	for _, event := range c.connectMessages() {
		if err := c.Send(event); err != nil {
			return err
		}
	}

	c.tries = 0
	go c.ReadLoop()

	// Consider the connection a success at this point.
	c.state.connected = true

	return nil
}

// connectMessages is a list of IRC messages to send when attempting
// to connect to the IRC server.
func (c *Client) connectMessages() (events []*Event) {
	// Passwords first.
	if c.Config.Password != "" {
		events = append(events, &Event{Command: PASS, Params: []string{c.Config.Password}})
	}

	// Then nickname.
	events = append(events, &Event{Command: NICK, Params: []string{c.Config.Nick}})

	// Then username and realname.
	if c.Config.Name == "" {
		c.Config.Name = c.Config.User
	}

	events = append(events, &Event{
		Command:  USER,
		Params:   []string{c.Config.User, "+iw", "*"},
		Trailing: c.Config.Name,
	})

	return events
}

// Reconnect checks to make sure we want to, and then attempts to
// reconnect to the server.
func (c *Client) Reconnect() (err error) {
	if c.hasQuit {
		return nil
	}

	if c.Config.ReconnectDelay < (10 * time.Second) {
		c.Config.ReconnectDelay = 10 * time.Second
	}

	if c.Config.MaxRetries > 0 {
		var err error
		c.conn.Close()

		// Re-setup events.
		c.Events = make(chan *Event, 40)

		// Delay so we're not slaughtering the server with a bunch of
		// connections.
		c.log.Printf("reconnecting to %s in %s", c.Server(), c.Config.ReconnectDelay)
		time.Sleep(c.Config.ReconnectDelay)

		for err = c.Connect(); err != nil && c.tries < c.Config.MaxRetries; c.tries++ {
			c.log.Printf("reconnecting to %s in %s (%d tries)", c.Server(), c.Config.ReconnectDelay, c.tries)
			time.Sleep(c.Config.ReconnectDelay)
		}

		return err
	}

	close(c.Events)
	return nil
}

// ReadLoop sets a timeout of 300 seconds, and then attempts to read
// from the IRC server. If there is an error, it calls Reconnect.
func (c *Client) ReadLoop() error {
	for {
		c.conn.SetDeadline(time.Now().Add(300 * time.Second))
		event, err := c.reader.Decode()
		if err != nil {
			return c.Reconnect()
		}

		c.Events <- event
	}
}

// Loop reads from the events channel and sends the events to be
// handled for every message it receives.
func (c *Client) Loop() {
	for {
		select {
		case event := <-c.Events:
			c.handleEvent(event)
		case <-c.quitChan:
			return
		}
	}
}

// IsConnected returns true if the client is connected to the server.
func (c *Client) IsConnected() bool {
	c.state.m.RLock()
	defer c.state.m.RUnlock()

	return c.state.connected
}

// GetNick returns the current nickname of the active connection.
//
// Returns empty string if tracking is disabled.
func (c *Client) GetNick() string {
	if c.Config.DisableTracking {
		return ""
	}

	c.state.m.RLock()
	defer c.state.m.RUnlock()

	if c.state.nick == "" {
		return c.Config.Nick
	}

	return c.state.nick
}

// SetNick changes the client nickname.
func (c *Client) SetNick(name string) {
	c.state.m.Lock()
	defer c.state.m.Unlock()

	c.state.nick = name
	c.Send(&Event{Command: NICK, Params: []string{name}})
}

// GetChannels returns the active list of channels that the client
// is in.
//
// Returns nil if tracking is disabled.
func (c *Client) GetChannels() map[string]*Channel {
	if c.Config.DisableTracking {
		return nil
	}

	c.state.m.RLock()
	defer c.state.m.RUnlock()

	return c.state.channels
}

// Who tells the client to update it's channel/user records.
//
// Does not update internal state if tracking is disabled.
func (c *Client) Who(target string) {
	c.Send(&Event{Command: WHO, Params: []string{target, "%tcuhn,1"}})
}

// Join attempts to enter an IRC channel with an optional password.
func (c *Client) Join(channel, password string) {
	if password != "" {
		c.Send(&Event{Command: JOIN, Params: []string{channel, password}})
		return
	}

	c.Send(&Event{Command: JOIN, Params: []string{channel}})
}

// Part leaves an IRC channel with an optional leave message.
func (c *Client) Part(channel, message string) {
	if message != "" {
		c.Send(&Event{Command: JOIN, Params: []string{channel}, Trailing: message})
		return
	}

	c.Send(&Event{Command: JOIN, Params: []string{channel}})
}

// Message sends a PRIVMSG to target (either channel, service, or
// user).
func (c *Client) Message(target, message string) {
	c.Send(&Event{Command: PRIVMSG, Params: []string{target}, Trailing: message})
}

// Messagef sends a formated PRIVMSG to target (either channel,
// service, or user).
func (c *Client) Messagef(target, format string, a ...interface{}) {
	c.Message(target, fmt.Sprintf(format, a...))
}

// Action sends a PRIVMSG ACTION (/me) to target (either channel,
// service, or user).
func (c *Client) Action(target, message string) {
	c.Send(&Event{Command: PRIVMSG, Params: []string{target}, Trailing: fmt.Sprintf("\001ACTION %s\001", message)})
}

// Actionf sends a formated PRIVMSG ACTION (/me) to target (either
// channel, service, or user).
func (c *Client) Actionf(target, format string, a ...interface{}) {
	c.Action(target, fmt.Sprintf(format, a...))
}

// Notice sends a NOTICE to target (either channel, service, or user).
func (c *Client) Notice(target, message string) {
	c.Send(&Event{Command: NOTICE, Params: []string{target}, Trailing: message})
}

// Noticef sends a formated NOTICE to target (either channel, service, or user).
func (c *Client) Noticef(target, format string, a ...interface{}) {
	c.Notice(target, fmt.Sprintf(format, a...))
}

// SendRaw sends a raw string back to the server, without carriage returns or
// newlines.
func (c *Client) SendRaw(raw string) {
	e := ParseEvent(raw)
	if e == nil {
		c.log.Printf("invalid event: %q", raw)
		return
	}

	c.Send(e)
}

// SendRawf sends a formated string back to the server, without carriage
// returns or newlines.
func (c *Client) SendRawf(format string, a ...interface{}) {
	c.SendRaw(fmt.Sprintf(format, a...))
}
<|endoftext|>


<commit_before>// Copyright (c) 2012-2014 José Carlos Nieto, https://menteslibres.net/xiam
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

package main

import (
	"log"
	"os"

	"menteslibres.net/gosexy/cli"
)

// Handy path separator.
const pathSeparator = string(os.PathSeparator)

// Version holds the software version.
const Version = "0.9"

func main() {
	// Software properties.
	cli.Name = "Luminos Markdown Server"
	cli.Homepage = "https://menteslibres.net/luminos"
	cli.Author = "Carlos Reventlov"
	cli.Version = Version
	cli.AuthorEmail = "carlos@reventlov.com"

	// Shows banner
	cli.Banner()

	// Dispatches the command.
	if err := cli.Dispatch(); err != nil {
		log.Fatal("Could not start Luminos: ", err)
	}

}
<commit_msg>Using my real name.<commit_after>// Copyright (c) 2012-2014 José Carlos Nieto, https://menteslibres.net/xiam
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

package main

import (
	"log"
	"os"

	"menteslibres.net/gosexy/cli"
)

// Handy path separator.
const pathSeparator = string(os.PathSeparator)

// Version holds the software version.
const Version = "0.9"

func main() {
	// Software properties.
	cli.Name = "Luminos Markdown Server"
	cli.Homepage = "https://menteslibres.net/luminos"
	cli.Author = "J. Carlos Nieto"
	cli.Version = Version
	cli.AuthorEmail = "jose.carlos@menteslibres.net"

	// Shows banner
	cli.Banner()

	// Dispatches the command.
	if err := cli.Dispatch(); err != nil {
		log.Fatal("Could not start Luminos: ", err)
	}

}
<|endoftext|>