<commit_before>// Tables
// Uses the pgf packages
// to render nice charts in various formats.
// Also uses tables for data, in various formats
package main

import (
	//"fmt"
	"fmt"
	"gotex/MWE"
	"gotex/enviro"
	"gotex/tabular"
)

func main() {
	t := new(tabular.Tabular)
	t.HasRules = true
	t.HasHead = true
	t.Specification = "l l r r p{3.5cm}"
	t.SpecificationList = []string{"l", "l", "r", "r", "r"}
	t.Insert("Qty", "Apr", "May", "Jun", "Jul")
	t.Insert("Qty", "100", "200", "300.2", "-256.00")
	t.Insert("Usage", "100", "200", "300.2", "-256.00")
	t.Insert("Usage", "100", "200", "300.2", "-256.00")
	t.Insert("Usage", "100", "200", "300.2", "-256.00\\footnotemark\\footnotetext{This is a footnote}")
	t.Caption.Text = "This is the caption of the table."
	t.Caption.Index = false
	t.ToTeX()
	t1 := new(mwe.MWE)

	// Wrap the table body in a MWE
	t1.CreateMWE("MWE1.tex", t.Rendered)
	// TODO better method for data definition maybe from a plain string which get split?
	//  Qty Apr May Jun Jul
	//  100 200 300 400 500

	z := enviro.NewEnvironment()
	y := z.Wrap("enumerate", "\\item This is first item")
	fmt.Println(y)

	tex := new(enviro.TeXEnviro)
	y1 := tex.Wrap("enumerate", "\\item This is first item\n")
	fmt.Println(y1)

	t3 := new(mwe.Sty)
	t3.CreateLaTeXStyle("test.sty", "")

	mwe.Parse3()
}
<commit_msg>minor changes to main<commit_after>// Tables
// Uses the pgf packages
// to render nice charts in various formats.
// Also uses tables for data, in various formats
package main

import (
	//"fmt"
	"fmt"
	"github.com/yannisl/gotex/MWE"
	"github.com/yannisl/gotex/enviro"
	"github.com/gotex/tabular"
)

func main() {
	t := new(tabular.Tabular)
	t.HasRules = true
	t.HasHead = true
	t.Specification = "l l r r p{3.5cm}"
	t.SpecificationList = []string{"l", "l", "r", "r", "r"}
	t.Insert("Qty", "Apr", "May", "Jun", "Jul")
	t.Insert("Qty", "100", "200", "300.2", "-256.00")
	t.Insert("Usage", "100", "200", "300.2", "-256.00")
	t.Insert("Usage", "100", "200", "300.2", "-256.00")
	t.Insert("Usage", "100", "200", "300.2", "-256.00\\footnotemark\\footnotetext{This is a footnote}")
	t.Caption.Text = "This is the caption of the table."
	t.Caption.Index = false
	t.ToTeX()
	t1 := new(mwe.MWE)

	// Wrap the table body in a MWE
	t1.CreateMWE("MWE1.tex", t.Rendered)
	// TODO better method for data definition maybe from a plain string which get split?
	//  Qty Apr May Jun Jul
	//  100 200 300 400 500

	z := enviro.NewEnvironment()
	y := z.Wrap("enumerate", "\\item This is first item")
	fmt.Println(y)

	tex := new(enviro.TeXEnviro)
	y1 := tex.Wrap("enumerate", "\\item This is first item\n")
	fmt.Println(y1)

	t3 := new(mwe.Sty)
	t3.CreateLaTeXStyle("test.sty", "")

	mwe.Parse3()
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
)

type Message struct {
	Text  string `json:"text"`
	Error bool   `json:"error"`
}

func main() {
	jsonData := &Message{"Hello, world!", false}
	b, _ := json.Marshal(jsonData)
	fmt.Println(string(b))
}
<commit_msg>no newline<commit_after>package main

import (
	"encoding/json"
	"fmt"
)

type Message struct {
	Text  string `json:"text"`
	Error bool   `json:"error"`
}

func main() {
	jsonData := &Message{"Hello, world!", false}
	b, _ := json.Marshal(jsonData)
	fmt.Print(string(b))
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"encoding/json"
	"fmt"
	"net"
	"os"
	"strings"
	"sync"
	"time"

	"github.com/alienth/fastlyctl/util"
	"github.com/alienth/go-fastly"
	"github.com/juju/ratelimit"
	"github.com/urfave/cli"
	"gopkg.in/mcuadros/go-syslog.v2"
)

// getIPs takes in an haproxy log line and returns the client IP and the CDN
// connecting IP which is in the captured request header. For us, the CDN
// connecting IP happens to be the 8th captured request header.
func getIPs(logLine string) (*net.IP, *net.IP) {
	if logLine == "" {
		return nil, nil
	}
	// This string parsing stuff was lifted from TPS
	var a, b int
	if a = strings.Index(logLine, "]:") + 3; a == -1 {
		return nil, nil
	}
	if b = strings.Index(logLine[a:], ":"); b == -1 {
		return nil, nil
	}
	clientIPString := logLine[a : a+b]
	clientIP := net.ParseIP(clientIPString)
	if clientIP == nil {
		return nil, nil
	}

	logLine = logLine[a+b:]
	// The first curly-braced block contains our request headers
	if a = strings.Index(logLine, "{"); a == -1 {
		return &clientIP, nil
	}
	if b = strings.Index(logLine[a:], "}"); b == -1 {
		return &clientIP, nil
	}
	bracketedHeaders := logLine[a : a+b]
	headers := strings.Split(bracketedHeaders, "|")
	if len(headers) < 7 {
		return &clientIP, nil
	}
	ipString := headers[7]
	cdnIP := net.ParseIP(ipString)
	if cdnIP == nil {
		return &clientIP, nil
	}
	return &clientIP, &cdnIP
}

func getLogTimestamp(logLine string) int64 {
	timestampStr := strings.Split(logLine, " ")[6]
	ts, _ := time.Parse("[02/Jan/2006:15:04:05.999]", timestampStr)

	return (ts.Unix())
}

type ipList struct {
	ips  []net.IP
	nets []net.IPNet
}

func readIPList(filename string) (*ipList, error) {
	var list ipList
	f, err := os.Open(filename)
	if err != nil {
		return nil, err
	}
	scanner := bufio.NewScanner(f)
	for scanner.Scan() {
		line := scanner.Text()
		if strings.Index(strings.TrimSpace(line), "#") == 0 {
			continue
		}
		if strings.TrimSpace(line) == "" {
			continue
		}
		if strings.Contains(line, "/") {
			_, n, err := net.ParseCIDR(line)
			if err != nil {
				return nil, fmt.Errorf("Unable to parse CIDR.\nLine:\n%s\nError:\n%s\n", line, err)
			}
			if n != nil {
				list.nets = append(list.nets, *n)
			}
		} else {
			ip := net.ParseIP(line)
			if ip != nil {
				list.ips = append(list.ips, ip)
			} else {
				return nil, fmt.Errorf("Unable to parse IP address in list: %s\n", line)
			}
		}

	}
	return &list, nil
}

func (l *ipList) contains(checkIP *net.IP) bool {
	if l == nil {
		return false
	}
	for _, ip := range l.ips {
		if ip.Equal(*checkIP) {
			return true
		}
	}
	for _, net := range l.nets {
		if net.Contains(*checkIP) {
			return true
		}
	}

	return false
}

type ipRate struct {
	ip      *net.IP
	bucket  *ratelimit.Bucket
	entries []*util.ACLEntry
	limited bool

	FirstHit    int64 `json:"first_hit,omitempty"`
	LastHit     int64 `json:"last_hit,omitempty"`
	LastLimit   int64 `json:"last_limit,omitempty"`
	Hits        int   `json:"hits,omitempty"`
	Strikes     int   `json:"strikes,omitempty"`
	Expire      int64 `json:"-"`
	LimitExpire int64 `json:"limit_expire,omitempty"`
}

func (ipr *ipRate) New(ip *net.IP) {
	ipr.ip = ip
	ipr.bucket = ratelimit.NewBucket(time.Duration(3)*time.Minute, 180)
	ipr.Expire = time.Now().Add(time.Duration(1) * time.Hour).Unix()
}

// Records a hit and returns true if it is over limit.
func (ipr *ipRate) Hit() bool {
	// Here we pretend that the IP performed no hits before the limit was removed,
	// since in testing the IP is not actually limited.
	if ipr.limited {
		return false
	}

	_, isSoonerThanMaxWait := ipr.bucket.TakeMaxDuration(1, 0)
	if ipr.FirstHit == 0 {
		ipr.FirstHit = time.Now().Unix()
	}
	ipr.LastHit = time.Now().Unix()
	ipr.Hits++
	ipr.Expire = time.Now().Add(time.Duration(1) * time.Hour).Unix()
	return !isSoonerThanMaxWait
}

// Limit adds an IP to a fastly edge ACL
func (ipr *ipRate) Limit() error {

	service, err := util.GetServiceByNameOrID(client, "teststackoverflow.com")
	if err != nil {
		return err
	}

	acl, err := util.NewACL(client, service.ID, "ratelimit")
	if err != nil {
		return err
	}

	// TODO this is heavy.. cache? do we even need?(see below)
	entries, err := acl.ListEntries()
	if err != nil {
		return err
	}

	var entry *util.ACLEntry

	for _, e := range entries {
		if ipr.ip.String() == e.IP {
			fmt.Printf("IP %s is already limited.\n", e.IP)
			// Not all ACL entries were necessarily created by this script, so silently ignore unmarshal errors.
			if err := json.Unmarshal([]byte(e.Comment), ipr); err != nil {
				break
			}
			entry = &util.ACLEntry{Client: client, ID: e.ID, ACLID: e.ACLID, ServiceID: service.ID}
			break
		}
	}

	ipr.LastLimit = time.Now().Unix()
	ipr.Strikes++
	ipr.LimitExpire = time.Now().Add(time.Duration(5) * time.Minute).Unix()
	ipr.Expire = time.Now().Add(time.Duration(24) * time.Hour).Unix()
	comment, err := json.Marshal(ipr)
	if err != nil {
		return err
	}
	if entry == nil {
		entry, err = util.NewACLEntry(client, service.ID, "ratelimit", ipr.ip.String(), 0, string(comment), false)
		if err != nil {
			return err
		}
		fmt.Printf("Limiting IP %s\n", ipr.ip.String())
		entry.Add()
	} else {
		entry.Comment = string(comment)
		//		entry.Update()
	}

	ipr.limited = true
	ipr.entries = append(ipr.entries, entry)
	return nil
}

// Removes an IP from ratelimits
func (ipr *ipRate) RemoveLimit() error {
	if len(ipr.entries) > 0 {
		fmt.Printf("Unlimiting IP %s\n", ipr.ip.String())
		for i, entry := range ipr.entries {
			if err := entry.Remove(); err != nil {
				return fmt.Errorf("Error removing limit for IP %s: %s", ipr.ip.String(), err)
			}
			ipr.entries[i] = nil
		}
		ipr.entries = ipr.entries[:0]
		ipr.limited = false
	}
	return nil
}

type hitMap struct {
	sync.RWMutex
	m map[string]*ipRate
}

func (hits *hitMap) expireRecords() {
	for {
		hits.Lock()
		for ip, ipr := range hits.m {
			if ipr.Expire < time.Now().Unix() {
				if err := ipr.RemoveLimit(); err != nil {
					fmt.Println(err)
				} else {
					delete(hits.m, ip)
				}
			}
		}
		hits.Unlock()
		time.Sleep(time.Duration(60) * time.Second)
	}
}

func (hits *hitMap) expireLimits() {
	for {
		hits.Lock()
		for _, ipr := range hits.m {
			if ipr.LimitExpire < time.Now().Unix() {
				if err := ipr.RemoveLimit(); err != nil {
					fmt.Println(err)
				}
			}
		}
		hits.Unlock()
		time.Sleep(time.Duration(15) * time.Second)
	}
}

// Fetches down remote ACLs and populates local hitMap with previously stored data.
func (hits *hitMap) importIPRates() error {
	service, err := util.GetServiceByNameOrID(client, "teststackoverflow.com")
	if err != nil {
		return err
	}

	acl, err := util.NewACL(client, service.ID, "ratelimit")
	if err != nil {
		return err
	}

	entries, err := acl.ListEntries()
	if err != nil {
		return err
	}

	// TODO: work with IPs existing in multiple services.
	for _, e := range entries {
		var ipr *ipRate
		var found bool
		hits.Lock()
		if ipr, found = hits.m[e.IP]; !found {
			ipr = &ipRate{}
			ip := net.ParseIP(e.IP)
			if ip == nil {
				return fmt.Errorf("Unable to parse IP %s in ACL.")
			}
			ipr.New(&ip)
			hits.m[ip.String()] = ipr
		}
		hits.Unlock()
		if err := json.Unmarshal([]byte(e.Comment), ipr); err != nil {
			break
		}
		entry := &util.ACLEntry{Client: client, ID: e.ID, ACLID: e.ACLID, ServiceID: service.ID}
		ipr.limited = true
		ipr.entries = append(ipr.entries, entry)
	}

	return nil
}

var client *fastly.Client

func main() {
	app := cli.NewApp()
	app.Name = "fastly-ratelimit"

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "whitelist, w",
			Usage: "Read `FILE` containing addresses which should whitelisted from any bans.",
		},
		cli.StringFlag{
			Name:  "listen, l",
			Usage: "Specify listen `ADDRESS:PORT`.",
			Value: "0.0.0.0:514",
		},
		cli.StringFlag{
			Name:   "fastly-key, K",
			Usage:  "Fastly API Key. Can be read from 'fastly_key' file in CWD.",
			EnvVar: "FASTLY_KEY",
			Value:  util.GetFastlyKey(),
		},
	}
	app.Action = func(c *cli.Context) error {
		client, _ = fastly.NewClient(c.GlobalString("fastly-key"))
		channel := make(syslog.LogPartsChannel)
		handler := syslog.NewChannelHandler(channel)

		server := syslog.NewServer()
		server.SetFormat(syslog.RFC3164)
		server.SetHandler(handler)
		if err := server.ListenUDP(c.GlobalString("listen")); err != nil {
			return cli.NewExitError(fmt.Sprintf("Unable to listen: %s\n", err), -1)
		}
		if err := server.Boot(); err != nil {
			return cli.NewExitError(fmt.Sprintf("Unable to start server: %s\n", err), -1)
		}

		var whitelist *ipList
		var err error
		whitelistFile := c.GlobalString("whitelist")
		if whitelistFile != "" {
			if whitelist, err = readIPList(whitelistFile); err != nil {
				return cli.NewExitError(fmt.Sprintf("Error reading whitelist file: %s", err), -1)
			}
		}

		var hits = hitMap{m: make(map[string]*ipRate)}
		if err := hits.importIPRates(); err != nil {
			return cli.NewExitError(fmt.Sprintf("Error importing existing IP rates: %s", err), -1)
		}
		go hits.expireRecords()
		go hits.expireLimits()
		go func(channel syslog.LogPartsChannel) {
			for logParts := range channel {
				var line string
				var ok bool
				if line, ok = logParts["content"].(string); !ok || line == "" {
					continue
				}
				clientIP, cdnIP := getIPs(line)
				if cdnIP == nil || clientIP == nil {
					continue
				}
				var ipr *ipRate
				var found bool
				hits.Lock()
				if ipr, found = hits.m[cdnIP.String()]; !found {
					ipr = &ipRate{}
					ipr.New(cdnIP)
					hits.m[cdnIP.String()] = ipr
				}
				hits.Unlock()
				overLimit := ipr.Hit()
				if overLimit {
					if whitelist.contains(cdnIP) {
						//fmt.Println("but is whitelisted so we don't care.")
					} else {
						if err := ipr.Limit(); err != nil {
							fmt.Printf("Error limiting IP: %s", err)
						}
					}
				}
			}
		}(channel)

		server.Wait()

		return nil
	}
	app.Run(os.Args)
}
<commit_msg>Initial work to read from a config file.<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net"
	"os"
	"strings"
	"sync"
	"time"

	"github.com/BurntSushi/toml"
	"github.com/alienth/fastlyctl/util"
	"github.com/alienth/go-fastly"
	"github.com/juju/ratelimit"
	"github.com/urfave/cli"
	"gopkg.in/mcuadros/go-syslog.v2"
)

// getIPs takes in an haproxy log line and returns the client IP and the CDN
// connecting IP which is in the captured request header. For us, the CDN
// connecting IP happens to be the 8th captured request header.
func getIPs(logLine string) (*net.IP, *net.IP) {
	if logLine == "" {
		return nil, nil
	}
	// This string parsing stuff was lifted from TPS
	var a, b int
	if a = strings.Index(logLine, "]:") + 3; a == -1 {
		return nil, nil
	}
	if b = strings.Index(logLine[a:], ":"); b == -1 {
		return nil, nil
	}
	clientIPString := logLine[a : a+b]
	clientIP := net.ParseIP(clientIPString)
	if clientIP == nil {
		return nil, nil
	}

	logLine = logLine[a+b:]
	// The first curly-braced block contains our request headers
	if a = strings.Index(logLine, "{"); a == -1 {
		return &clientIP, nil
	}
	if b = strings.Index(logLine[a:], "}"); b == -1 {
		return &clientIP, nil
	}
	bracketedHeaders := logLine[a : a+b]
	headers := strings.Split(bracketedHeaders, "|")
	if len(headers) < 7 {
		return &clientIP, nil
	}
	ipString := headers[7]
	cdnIP := net.ParseIP(ipString)
	if cdnIP == nil {
		return &clientIP, nil
	}
	return &clientIP, &cdnIP
}

func getLogTimestamp(logLine string) int64 {
	timestampStr := strings.Split(logLine, " ")[6]
	ts, _ := time.Parse("[02/Jan/2006:15:04:05.999]", timestampStr)

	return (ts.Unix())
}

type IPList struct {
	IPs  []net.IP
	Nets []IPNet

	Limit    bool
	Requests int
	Time     int
}

//type IP net.IP
//type IPNet net.IPNet
//
//var ipLists map[string]IPList
//
//func (ip *IP) UnmarshalTOML(b []byte) error {
//	ipAddr := net.ParseIP(string(b))
//	if ipAddr != nil {
//		return fmt.Errorf("Unable to unmarshal %s to IP.", string(b))
//	}
//
//	ipAddr.UnmarshalText()
//
//}

type IPNet struct {
	net.IPNet
}

func (ipNet *IPNet) UnmarshalTOML(b []byte) error {
	_, n, err := net.ParseCIDR(string(b))
	if err != nil {
		return fmt.Errorf("Unable to parse CIDR.\nEntry:\n%s\nError:\n%s\n", string(b), err)
	}
	ipNet.IP = n.IP
	ipNet.Mask = n.Mask

	return nil
}

func readConfig(filename string) (map[string]*IPList, error) {
	ipLists := make(map[string]*IPList)
	body, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}

	if err := toml.Unmarshal(body, &ipLists); err != nil {
		return nil, fmt.Errorf("toml parsing error: %s", err)
	}

	return ipLists, nil
}

func (l *IPList) contains(checkIP *net.IP) bool {
	if l == nil {
		return false
	}
	for _, ip := range l.IPs {
		if ip.Equal(*checkIP) {
			return true
		}
	}
	for _, net := range l.Nets {
		if net.Contains(*checkIP) {
			return true
		}
	}

	return false
}

type ipRate struct {
	ip      *net.IP
	bucket  *ratelimit.Bucket
	entries []*util.ACLEntry
	limited bool

	FirstHit    int64 `json:"first_hit,omitempty"`
	LastHit     int64 `json:"last_hit,omitempty"`
	LastLimit   int64 `json:"last_limit,omitempty"`
	Hits        int   `json:"hits,omitempty"`
	Strikes     int   `json:"strikes,omitempty"`
	Expire      int64 `json:"-"`
	LimitExpire int64 `json:"limit_expire,omitempty"`
}

func (ipr *ipRate) New(ip *net.IP) {
	ipr.ip = ip
	ipr.bucket = ratelimit.NewBucket(time.Duration(3)*time.Minute, 180)
	ipr.Expire = time.Now().Add(time.Duration(1) * time.Hour).Unix()
}

// Records a hit and returns true if it is over limit.
func (ipr *ipRate) Hit() bool {
	// Here we pretend that the IP performed no hits before the limit was removed,
	// since in testing the IP is not actually limited.
	if ipr.limited {
		return false
	}

	_, isSoonerThanMaxWait := ipr.bucket.TakeMaxDuration(1, 0)
	if ipr.FirstHit == 0 {
		ipr.FirstHit = time.Now().Unix()
	}
	ipr.LastHit = time.Now().Unix()
	ipr.Hits++
	ipr.Expire = time.Now().Add(time.Duration(1) * time.Hour).Unix()
	return !isSoonerThanMaxWait
}

// Limit adds an IP to a fastly edge ACL
func (ipr *ipRate) Limit() error {

	service, err := util.GetServiceByNameOrID(client, "teststackoverflow.com")
	if err != nil {
		return err
	}

	acl, err := util.NewACL(client, service.ID, "ratelimit")
	if err != nil {
		return err
	}

	// TODO this is heavy.. cache? do we even need?(see below)
	entries, err := acl.ListEntries()
	if err != nil {
		return err
	}

	var entry *util.ACLEntry

	for _, e := range entries {
		if ipr.ip.String() == e.IP {
			fmt.Printf("IP %s is already limited.\n", e.IP)
			// Not all ACL entries were necessarily created by this script, so silently ignore unmarshal errors.
			if err := json.Unmarshal([]byte(e.Comment), ipr); err != nil {
				break
			}
			entry = &util.ACLEntry{Client: client, ID: e.ID, ACLID: e.ACLID, ServiceID: service.ID}
			break
		}
	}

	ipr.LastLimit = time.Now().Unix()
	ipr.Strikes++
	ipr.LimitExpire = time.Now().Add(time.Duration(45) * time.Minute).Unix()
	ipr.Expire = time.Now().Add(time.Duration(24) * time.Hour).Unix()
	comment, err := json.Marshal(ipr)
	if err != nil {
		return err
	}
	if entry == nil {
		entry, err = util.NewACLEntry(client, service.ID, "ratelimit", ipr.ip.String(), 0, string(comment), false)
		if err != nil {
			return err
		}
		fmt.Printf("Limiting IP %s\n", ipr.ip.String())
		entry.Add()
	} else {
		entry.Comment = string(comment)
		//		entry.Update()
	}

	ipr.limited = true
	ipr.entries = append(ipr.entries, entry)
	return nil
}

// Removes an IP from ratelimits
func (ipr *ipRate) RemoveLimit() error {
	if len(ipr.entries) > 0 {
		fmt.Printf("Unlimiting IP %s\n", ipr.ip.String())
		for i, entry := range ipr.entries {
			if err := entry.Remove(); err != nil {
				return fmt.Errorf("Error removing limit for IP %s: %s", ipr.ip.String(), err)
			}
			ipr.entries[i] = nil
		}
		ipr.entries = ipr.entries[:0]
		ipr.limited = false
	}
	return nil
}

type hitMap struct {
	sync.RWMutex
	m map[string]*ipRate
}

func (hits *hitMap) expireRecords() {
	for {
		hits.Lock()
		for ip, ipr := range hits.m {
			if ipr.Expire < time.Now().Unix() {
				if err := ipr.RemoveLimit(); err != nil {
					fmt.Println(err)
				} else {
					delete(hits.m, ip)
				}
			}
		}
		hits.Unlock()
		time.Sleep(time.Duration(60) * time.Second)
	}
}

func (hits *hitMap) expireLimits() {
	for {
		hits.Lock()
		for _, ipr := range hits.m {
			if ipr.LimitExpire < time.Now().Unix() {
				if err := ipr.RemoveLimit(); err != nil {
					fmt.Println(err)
				}
			}
		}
		hits.Unlock()
		time.Sleep(time.Duration(15) * time.Second)
	}
}

// Fetches down remote ACLs and populates local hitMap with previously stored data.
func (hits *hitMap) importIPRates() error {
	service, err := util.GetServiceByNameOrID(client, "teststackoverflow.com")
	if err != nil {
		return err
	}

	acl, err := util.NewACL(client, service.ID, "ratelimit")
	if err != nil {
		return err
	}

	entries, err := acl.ListEntries()
	if err != nil {
		return err
	}

	// TODO: work with IPs existing in multiple services.
	for _, e := range entries {
		var ipr *ipRate
		var found bool
		hits.Lock()
		if ipr, found = hits.m[e.IP]; !found {
			ipr = &ipRate{}
			ip := net.ParseIP(e.IP)
			if ip == nil {
				return fmt.Errorf("Unable to parse IP %s in ACL.")
			}
			ipr.New(&ip)
			hits.m[ip.String()] = ipr
		}
		hits.Unlock()
		if err := json.Unmarshal([]byte(e.Comment), ipr); err != nil {
			break
		}
		entry := &util.ACLEntry{Client: client, ID: e.ID, ACLID: e.ACLID, ServiceID: service.ID}
		ipr.limited = true
		ipr.entries = append(ipr.entries, entry)
	}

	return nil
}

var client *fastly.Client

func main() {
	app := cli.NewApp()
	app.Name = "fastly-ratelimit"

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "whitelist, w",
			Usage: "Read `FILE` containing addresses which should whitelisted from any bans.",
		},
		cli.StringFlag{
			Name:  "listen, l",
			Usage: "Specify listen `ADDRESS:PORT`.",
			Value: "0.0.0.0:514",
		},
		cli.StringFlag{
			Name:   "fastly-key, K",
			Usage:  "Fastly API Key. Can be read from 'fastly_key' file in CWD.",
			EnvVar: "FASTLY_KEY",
			Value:  util.GetFastlyKey(),
		},
	}
	app.Action = func(c *cli.Context) error {
		client, _ = fastly.NewClient(c.GlobalString("fastly-key"))
		channel := make(syslog.LogPartsChannel)
		handler := syslog.NewChannelHandler(channel)

		ipLists, err := readConfig("config.toml")
		if err != nil {
			return cli.NewExitError(fmt.Sprintf("Error reading config file:\n%s\n", err), -1)
		}

		server := syslog.NewServer()
		server.SetFormat(syslog.RFC3164)
		server.SetHandler(handler)
		if err := server.ListenUDP(c.GlobalString("listen")); err != nil {
			return cli.NewExitError(fmt.Sprintf("Unable to listen: %s\n", err), -1)
		}
		if err := server.Boot(); err != nil {
			return cli.NewExitError(fmt.Sprintf("Unable to start server: %s\n", err), -1)
		}

		var hits = hitMap{m: make(map[string]*ipRate)}
		if err := hits.importIPRates(); err != nil {
			return cli.NewExitError(fmt.Sprintf("Error importing existing IP rates: %s", err), -1)
		}
		go hits.expireRecords()
		go hits.expireLimits()
		go func(channel syslog.LogPartsChannel) {
			for logParts := range channel {
				var line string
				var ok bool
				if line, ok = logParts["content"].(string); !ok || line == "" {
					continue
				}
				clientIP, cdnIP := getIPs(line)
				if cdnIP == nil || clientIP == nil {
					continue
				}
				var ipr *ipRate
				var found bool
				hits.Lock()
				if ipr, found = hits.m[cdnIP.String()]; !found {
					ipr = &ipRate{}
					ipr.New(cdnIP)
					hits.m[cdnIP.String()] = ipr
				}
				hits.Unlock()
				overLimit := ipr.Hit()
				if overLimit {
					if ipLists["_default_"].contains(cdnIP) {
						//fmt.Println("but is whitelisted so we don't care.")
					} else {
						if err := ipr.Limit(); err != nil {
							fmt.Printf("Error limiting IP: %s", err)
						}
					}
				}
			}
		}(channel)

		server.Wait()

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


<commit_before>// Dependency Manager for Golang Projects
// Author: Nicholas Capo <nicholas@vubeology.com>
//
//
// Installation: `go get github.com/vube/depman`
//
// For help run 'depman help'
//
package main

// Copyright 2013 Vubeology, Inc.

//===============================================

import (
	"flag"
	"fmt"
	"github.com/vube/depman/add"
	"github.com/vube/depman/colors"
	"github.com/vube/depman/create"
	"github.com/vube/depman/dep"
	"github.com/vube/depman/install"
	"github.com/vube/depman/showfrozen"
	"github.com/vube/depman/timelock"
	"github.com/vube/depman/update"
	"github.com/vube/depman/upgrade"
	"github.com/vube/depman/util"
	"log"
	"strings"
)

// Version number
const VERSION string = "2.6.0"

//===============================================

func main() {
	var result int
	var help bool
	var path string
	var command string
	var arguments []string
	var deps dep.DependencyMap
	var err error

	log.SetFlags(0)

	flag.BoolVar(&help, "help", false, "Display help")
	flag.StringVar(&path, "path", ".", "Directory or full path to deps.json")
	util.Parse()

	util.Version(VERSION)

	timelock.Read()

	path = dep.GetPath(path)

	if flag.NArg() > 0 {
		command = strings.ToLower(flag.Arg(0))
	}

	if flag.NArg() > 1 {
		arguments = flag.Args()[1:]
	}

	if help {
		command = "help"
	}

	// switch to check for deps.json
	switch command {
	case "init", "create", "help", "self-upgrade":
		// don't check for deps.json
	default:
		util.CheckPath(path)
		deps, err = dep.Read(path)
		if err != nil {
			util.Fatal(colors.Red("Error Reading deps.json: " + err.Error()))
		}
	}

	// switch to exec the sub command
	switch command {
	case "init", "create":
		result = create.Create(path)
	case "add":
		if len(arguments) < 1 {
			util.Print(colors.Red("Add command requires 1 argument: Add [nickname]"))
			Help()
		} else {
			add.Add(deps, arguments[0])
		}

	case "update":
		if len(arguments) < 2 {
			util.Print(colors.Red("Update command requires 2 arguments: Update [nickname] [branch]"))
			Help()
		} else {
			update.Update(deps, arguments[0], arguments[1])
		}
	case "install", "":
		result = install.Install(deps)
	case "self-upgrade":
		upgrade.Self()
	case "show-frozen":
		var recursive bool
		flagset := flag.NewFlagSet("show-frozen", flag.ExitOnError)
		flagset.BoolVar(&recursive, "recursive", false, "descend recursively (depth-first) into dependencies")
		flagset.Parse(flag.Args()[1:])

		if recursive {
			fmt.Println(showfrozen.ReadRecursively(deps, nil))
		} else {
			fmt.Print(showfrozen.Read(deps))
		}
	default:
		result = 1
		log.Println(colors.Red("Unknown Command: " + command))
		fallthrough
	case "help":
		Help()
	}

	if result == 0 {
		util.Print("Success")
	}

	timelock.Write()

	util.OsExit(result)
}

//===============================================

// Help prints the help message for depman
func Help() {
	log.Println("")
	log.Println("Commands:")
	log.Println("   Init                        : Create an empty deps.json")
	log.Println("   Add [nickname]              : Add a dependency (interactive)")
	log.Println("   Install                     : Install all the dependencies listed in deps.json (default)")
	log.Println("   Update [nickname] [branch]  : Update [nickname] to use the latest commit in [branch]")
	log.Println("   Self-Upgrade                : Upgrade depman to the latest version on the master branch")
	log.Println("   Help                        : Display this help")
	log.Println("   Show-Frozen                 : Show dependencies as resolved to commit IDs")
	log.Println("")
	log.Println("Example: depman --verbose install")
	log.Println("")
	//log.Println("   freeze                      : For each dependency change tag and branch versions to commits (not yet implemented)")
	log.Println("Options:")
	flag.PrintDefaults()
}
<commit_msg>Rework switch for readability<commit_after>// Dependency Manager for Golang Projects
// Author: Nicholas Capo <nicholas@vubeology.com>
//
//
// Installation: `go get github.com/vube/depman`
//
// For help run 'depman help'
//
package main

// Copyright 2013 Vubeology, Inc.

//===============================================

import (
	"flag"
	"fmt"
	"github.com/vube/depman/add"
	"github.com/vube/depman/colors"
	"github.com/vube/depman/create"
	"github.com/vube/depman/dep"
	"github.com/vube/depman/install"
	"github.com/vube/depman/showfrozen"
	"github.com/vube/depman/timelock"
	"github.com/vube/depman/update"
	"github.com/vube/depman/upgrade"
	"github.com/vube/depman/util"
	"log"
	"strings"
)

// Version number
const VERSION string = "2.6.0"

//===============================================

func main() {
	var result int
	var help bool
	var path string
	var command string
	var arguments []string
	var deps dep.DependencyMap
	var err error

	log.SetFlags(0)

	flag.BoolVar(&help, "help", false, "Display help")
	flag.StringVar(&path, "path", ".", "Directory or full path to deps.json")
	util.Parse()

	util.Version(VERSION)

	timelock.Read()

	path = dep.GetPath(path)

	if flag.NArg() > 0 {
		command = strings.ToLower(flag.Arg(0))
	}

	if flag.NArg() > 1 {
		arguments = flag.Args()[1:]
	}

	if help {
		command = "help"
	}

	// switch to check for deps.json
	switch command {
	case "add", "", "install", "update", "show-frozen":
		// check for deps.json
		util.CheckPath(path)
		deps, err = dep.Read(path)
		if err != nil {
			util.Fatal(colors.Red("Error Reading deps.json: " + err.Error()))
		}
	}

	// switch to exec the sub command
	switch command {
	case "init", "create":
		result = create.Create(path)
	case "add":
		if len(arguments) < 1 {
			util.Print(colors.Red("Add command requires 1 argument: Add [nickname]"))
			Help()
		} else {
			add.Add(deps, arguments[0])
		}

	case "update":
		if len(arguments) < 2 {
			util.Print(colors.Red("Update command requires 2 arguments: Update [nickname] [branch]"))
			Help()
		} else {
			update.Update(deps, arguments[0], arguments[1])
		}
	case "install", "":
		result = install.Install(deps)
	case "self-upgrade":
		upgrade.Self()
	case "show-frozen":
		var recursive bool
		flagset := flag.NewFlagSet("show-frozen", flag.ExitOnError)
		flagset.BoolVar(&recursive, "recursive", false, "descend recursively (depth-first) into dependencies")
		flagset.Parse(flag.Args()[1:])

		if recursive {
			fmt.Println(showfrozen.ReadRecursively(deps, nil))
		} else {
			fmt.Print(showfrozen.Read(deps))
		}
	default:
		result = 1
		log.Println(colors.Red("Unknown Command: " + command))
		fallthrough
	case "help":
		Help()
	}

	if result == 0 {
		util.Print("Success")
	}

	timelock.Write()

	util.OsExit(result)
}

//===============================================

// Help prints the help message for depman
func Help() {
	log.Println("")
	log.Println("Commands:")
	log.Println("   Init                        : Create an empty deps.json")
	log.Println("   Add [nickname]              : Add a dependency (interactive)")
	log.Println("   Install                     : Install all the dependencies listed in deps.json (default)")
	log.Println("   Update [nickname] [branch]  : Update [nickname] to use the latest commit in [branch]")
	log.Println("   Self-Upgrade                : Upgrade depman to the latest version on the master branch")
	log.Println("   Help                        : Display this help")
	log.Println("   Show-Frozen                 : Show dependencies as resolved to commit IDs")
	log.Println("")
	log.Println("Example: depman --verbose install")
	log.Println("")
	//log.Println("   freeze                      : For each dependency change tag and branch versions to commits (not yet implemented)")
	log.Println("Options:")
	flag.PrintDefaults()
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"os"
	"os/user"
	// "os/exec"
	"log"
	"time"
)

func main() {
	// Get Users home directory
	user, err := user.Current()
	if err != nil {
		log.Fatalln(err)
	}

	//Check for our command line configuration flags
	var (
		appNameUsage = "*REQUIRED* Name of application to snapshot."
		appNamePtr   = flag.String("appName", "", appNameUsage)

		backupPathPtr = flag.String("backupPath", user.HomeDir, "The base directory where the openshift backups will be stored.")
		folderNamePtr = flag.String("folderName", "OpenShiftBackUps", "Name of folder that backups will be stored in.")
	)

	// Set up short hand flags
	flag.StringVar(appNamePtr, "a", "", appNameUsage+" (shorthand)")

	flag.Parse()

	// If an appName isn't set then return
	if *appNamePtr == "" {
		log.Fatalln("Must set --appName (-a) flag")
	}

	fmt.Println("Running openshift-backup with backup path set to ", *backupPathPtr)

	// Set Path
	path := *backupPathPtr + "/" + *folderNamePtr

	// Create OpenShiftBackUps directory
	createDir(path, 0700)

	//Get the name of the directory where we want to save this backup
	weekdays := []string{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}
	directory := weekdays[time.Now().Weekday()]

	dirPath := path + "/" + directory

	//Create the backup directory if it does not exist
	createDir(dirPath, 0600)

	//Define our openshift command
	fmt.Println("App name: ", *appNamePtr)

	// rhc snapshot save -a {appName}

}

func createDir(name string, perm os.FileMode) error {
	fi, err := os.Stat(name)
	if err != nil {
		fmt.Println("Creating directory named", name)

		// Create folder
		err = os.Mkdir(name, perm)
		if err != nil {
			fmt.Println("Couldn't create directory: ", err)

			return err
		}

	} else {
		fmt.Println("Folder exists!: ", fi.Name())

	}

	return nil
}
<commit_msg>Stubbing out exec.Command for rhc snapshot save<commit_after>package main

import (
	"errors"
	"flag"
	"fmt"
	"log"
	"os"
	"os/exec"
	"os/user"
	"time"
)

func main() {
	// Get Users home directory
	user, err := user.Current()
	if err != nil {
		log.Fatalln(err)
	}

	//Check for our command line configuration flags
	var (
		appNameUsage = "*REQUIRED* Name of application to snapshot."
		appNamePtr   = flag.String("appName", "", appNameUsage)

		backupPathPtr = flag.String("backupPath", user.HomeDir, "The base directory where the openshift backups will be stored.")
		folderNamePtr = flag.String("folderName", "OpenShiftBackUps", "Name of folder that backups will be stored in.")
	)

	// Set up short hand flags
	flag.StringVar(appNamePtr, "a", "", appNameUsage+" (shorthand)")

	flag.Parse()

	// If an appName isn't set then return
	if *appNamePtr == "" {
		log.Fatalln("Must set --appName (-a) flag")
	}

	fmt.Println("Running openshift-backup with backup path set to ", *backupPathPtr)

	// Set Path
	path := *backupPathPtr + "/" + *folderNamePtr

	// Create OpenShiftBackUps directory
	createDir(path, 0700)

	//Get the name of the directory where we want to save this backup
	weekdays := []string{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}
	directory := weekdays[time.Now().Weekday()]

	dirPath := path + "/" + directory

	//Create the backup directory if it does not exist
	createDir(dirPath, 0700)

	//Define our openshift command //fmt.Println("App name: ", *appNamePtr)
	fmt.Println("App name: ", *appNamePtr)

	// TODO: change directory into dirPath first

	// cmd := exec.Command("rhc", "snapshot-save", "-a", *appNamePtr)
	// output, err := cmd.CombinedOutput()

	// if err != nil {
	// 	log.Fatalln(errors.New(err.Error() + ": " + fmt.Sprint(output)))
	// }

	// fmt.Println(output)

}

func createDir(name string, perm os.FileMode) error {
	fi, err := os.Stat(name)
	if err != nil {
		fmt.Println("Creating directory named", name)

		// Create folder
		err = os.Mkdir(name, perm)
		if err != nil {
			fmt.Println("Couldn't create directory: ", err)

			return err
		}

	} else {
		fmt.Println("Folder exists!: ", fi.Name())

	}

	return nil
}
<|endoftext|>


<commit_before>// GoTest project main.go
package main

import (
	"encoding/base64"
	"fmt"
	_ "github.com/BorisWilhelms/GoUtils/Unmarshal"
	"github.com/BorisWilhelms/SubstitutionMailer/Substitution"
	"io/ioutil"
)

func main() {
	source, err := ioutil.ReadFile("source.htm")
	if err != nil {
		fmt.Println("Source could not be read... :%s", err.Error())
	}
	s, err := Substitution.Parse(string(source), "6b")
	if err != nil {
		fmt.Println("Source could not be parsed... :%s", err.Error())
	}
	fmt.Printf("%#v\n", s)
}
<commit_msg>CHANGED: Fixed build issues<commit_after>// GoTest project main.go
package main

import (
	"fmt"
	_ "github.com/BorisWilhelms/GoUtils/Unmarshal"
	"github.com/BorisWilhelms/SubstitutionMailer/Substitution"
	"io/ioutil"
)

func main() {
	source, err := ioutil.ReadFile("source.htm")
	if err != nil {
		fmt.Println("Source could not be read... :%s", err.Error())
	}
	s, err := SubstitutionPlan.Parse(string(source), "6b")
	if err != nil {
		fmt.Println("Source could not be parsed... :%s", err.Error())
	}
	fmt.Printf("%#v\n", s)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"

	"gopkg.in/qml.v1"
	"gopkg.in/qml.v1/gl/2.0"

	"github.com/peterhellberg/wavefront"
)

var (
	modelFn = "model.obj"
	width   = 800
	height  = 600
)

func main() {
	if len(os.Args) == 2 {
		modelFn = os.Args[1]
	}

	if err := qml.Run(run); err != nil {
		fmt.Fprintf(os.Stderr, "error: %v\n", err)
		os.Exit(1)
	}
}

func run() error {
	engine := qml.NewEngine()

	engine.On("quit", func() {
		os.Exit(0)
	})

	model, err := wavefront.Read(modelFn)
	if err != nil {
		return err
	}

	qml.RegisterTypes("ObjView", 0, 1, []qml.TypeSpec{{
		Init: func(m *Model, obj qml.Object) {
			m.Object = obj
			m.model = model
		},
	}})

	component, err := engine.LoadString("objview.qml", qmlString)
	if err != nil {
		return err
	}

	win := component.CreateWindow(nil)

	win.On("widthChanged", func(w int) {
		width = w
	})

	win.On("heightChanged", func(h int) {
		height = h
	})

	win.Show()
	win.Wait()

	return nil
}

type Model struct {
	qml.Object

	model map[string]*wavefront.Object

	Rotation int
}

func (m *Model) SetRotation(rotation int) {
	m.Rotation = rotation

	m.Call("update")
}

func (m *Model) Paint(p *qml.Painter) {
	gl := GL.API(p)

	gl.Enable(GL.BLEND)
	gl.BlendFunc(GL.SRC_ALPHA, GL.ONE_MINUS_SRC_ALPHA)

	gl.ShadeModel(GL.SMOOTH)
	gl.Enable(GL.DEPTH_TEST)
	gl.DepthMask(true)
	gl.Enable(GL.NORMALIZE)

	gl.Clear(GL.DEPTH_BUFFER_BIT)

	w := float32(width)
	gl.Scalef(w/6, w/6, w/6)

	lka := []float32{0.3, 0.3, 0.3, 1.0}
	lkd := []float32{1.0, 1.0, 1.0, 0.0}
	lks := []float32{1.0, 1.0, 1.0, 1.0}
	lpos := []float32{-2, 6, 3, 1.0}

	gl.Enable(GL.LIGHTING)
	gl.Lightfv(GL.LIGHT0, GL.AMBIENT, lka)
	gl.Lightfv(GL.LIGHT0, GL.DIFFUSE, lkd)
	gl.Lightfv(GL.LIGHT0, GL.SPECULAR, lks)
	gl.Lightfv(GL.LIGHT0, GL.POSITION, lpos)
	gl.Enable(GL.LIGHT0)

	gl.EnableClientState(GL.NORMAL_ARRAY)
	gl.EnableClientState(GL.VERTEX_ARRAY)

	gl.Translatef(2, 2.5, 0)
	gl.Rotatef(260, 190, -135, 85)
	gl.Rotatef(float32(90+((36000+m.Rotation)%360)), 1, 0, 0)

	gl.Disable(GL.COLOR_MATERIAL)

	for _, obj := range m.model {
		for _, group := range obj.Groups {
			gl.Materialfv(GL.FRONT, GL.AMBIENT, group.Material.Ambient)
			gl.Materialfv(GL.FRONT, GL.DIFFUSE, group.Material.Diffuse)
			gl.Materialfv(GL.FRONT, GL.SPECULAR, group.Material.Specular)
			gl.Materialf(GL.FRONT, GL.SHININESS, group.Material.Shininess)
			gl.VertexPointer(3, GL.FLOAT, 0, group.Vertexes)
			gl.NormalPointer(GL.FLOAT, 0, group.Normals)
			gl.DrawArrays(GL.TRIANGLES, 0, len(group.Vertexes)/3)
		}
	}

	gl.Enable(GL.COLOR_MATERIAL)

	gl.DisableClientState(GL.NORMAL_ARRAY)
	gl.DisableClientState(GL.VERTEX_ARRAY)
}

const qmlString = `
// Start of the QML string
import QtQuick 2.0
import ObjView 0.1

Rectangle {
	id: root

	width: 800
	height: 600

	gradient: Gradient {
		GradientStop { position: 0.0; color: "#003E5F" }
		GradientStop { position: 0.1; color: "#00334E" }
		GradientStop { position: 0.2; color: "#002033" }
		GradientStop { position: 0.3; color: "#001521" }
		GradientStop { position: 0.7; color: "#00080E" }
	}

	Model {
		id: model

		x: 0
		y: 0

		width: parent.width
		height: parent.height

		NumberAnimation on rotation {
			id: anim
			from: 360
			to: 0
			duration: 8000
			loops: Animation.Infinite
		}

		MouseArea {
			anchors.fill: parent

			property real startX
			property real startR

			onPressed: {
				startX = mouse.x
				startR = model.rotation
				anim.running = false
			}
			onReleased: {
				anim.from = model.rotation + 360
				anim.to = model.rotation
				anim.running = true
			}
			onPositionChanged: {
				model.rotation = (36000 + (startR - (mouse.x - startX))) % 360
			}
		}
	}
}

// End of the QML string`

// vim: ft=qml.go
<commit_msg>Added missing comments<commit_after>package main

import (
	"fmt"
	"os"

	"gopkg.in/qml.v1"
	"gopkg.in/qml.v1/gl/2.0"

	"github.com/peterhellberg/wavefront"
)

var (
	modelFn = "model.obj"
	width   = 800
	height  = 600
)

func main() {
	if len(os.Args) == 2 {
		modelFn = os.Args[1]
	}

	if err := qml.Run(run); err != nil {
		fmt.Fprintf(os.Stderr, "error: %v\n", err)
		os.Exit(1)
	}
}

func run() error {
	engine := qml.NewEngine()

	engine.On("quit", func() {
		os.Exit(0)
	})

	model, err := wavefront.Read(modelFn)
	if err != nil {
		return err
	}

	qml.RegisterTypes("ObjView", 0, 1, []qml.TypeSpec{{
		Init: func(m *Model, obj qml.Object) {
			m.Object = obj
			m.model = model
		},
	}})

	component, err := engine.LoadString("objview.qml", qmlString)
	if err != nil {
		return err
	}

	win := component.CreateWindow(nil)

	win.On("widthChanged", func(w int) {
		width = w
	})

	win.On("heightChanged", func(h int) {
		height = h
	})

	win.Show()
	win.Wait()

	return nil
}

// A Model wraps a QML Object and contains the wavefront model and rotation
type Model struct {
	qml.Object

	model map[string]*wavefront.Object

	Rotation int
}

// SetRotation sets the rotation and calls update
func (m *Model) SetRotation(rotation int) {
	m.Rotation = rotation

	m.Call("update")
}

// Paint paints the model using the given painter
func (m *Model) Paint(p *qml.Painter) {
	gl := GL.API(p)

	gl.Enable(GL.BLEND)
	gl.BlendFunc(GL.SRC_ALPHA, GL.ONE_MINUS_SRC_ALPHA)

	gl.ShadeModel(GL.SMOOTH)
	gl.Enable(GL.DEPTH_TEST)
	gl.DepthMask(true)
	gl.Enable(GL.NORMALIZE)

	gl.Clear(GL.DEPTH_BUFFER_BIT)

	w := float32(width)
	gl.Scalef(w/6, w/6, w/6)

	lka := []float32{0.3, 0.3, 0.3, 1.0}
	lkd := []float32{1.0, 1.0, 1.0, 0.0}
	lks := []float32{1.0, 1.0, 1.0, 1.0}
	lpos := []float32{-2, 6, 3, 1.0}

	gl.Enable(GL.LIGHTING)
	gl.Lightfv(GL.LIGHT0, GL.AMBIENT, lka)
	gl.Lightfv(GL.LIGHT0, GL.DIFFUSE, lkd)
	gl.Lightfv(GL.LIGHT0, GL.SPECULAR, lks)
	gl.Lightfv(GL.LIGHT0, GL.POSITION, lpos)
	gl.Enable(GL.LIGHT0)

	gl.EnableClientState(GL.NORMAL_ARRAY)
	gl.EnableClientState(GL.VERTEX_ARRAY)

	gl.Translatef(2, 2.5, 0)
	gl.Rotatef(260, 190, -135, 85)
	gl.Rotatef(float32(90+((36000+m.Rotation)%360)), 1, 0, 0)

	gl.Disable(GL.COLOR_MATERIAL)

	for _, obj := range m.model {
		for _, group := range obj.Groups {
			gl.Materialfv(GL.FRONT, GL.AMBIENT, group.Material.Ambient)
			gl.Materialfv(GL.FRONT, GL.DIFFUSE, group.Material.Diffuse)
			gl.Materialfv(GL.FRONT, GL.SPECULAR, group.Material.Specular)
			gl.Materialf(GL.FRONT, GL.SHININESS, group.Material.Shininess)
			gl.VertexPointer(3, GL.FLOAT, 0, group.Vertexes)
			gl.NormalPointer(GL.FLOAT, 0, group.Normals)
			gl.DrawArrays(GL.TRIANGLES, 0, len(group.Vertexes)/3)
		}
	}

	gl.Enable(GL.COLOR_MATERIAL)

	gl.DisableClientState(GL.NORMAL_ARRAY)
	gl.DisableClientState(GL.VERTEX_ARRAY)
}

const qmlString = `
// Start of the QML string
import QtQuick 2.0
import ObjView 0.1

Rectangle {
	id: root

	width: 800
	height: 600

	gradient: Gradient {
		GradientStop { position: 0.0; color: "#003E5F" }
		GradientStop { position: 0.1; color: "#00334E" }
		GradientStop { position: 0.2; color: "#002033" }
		GradientStop { position: 0.3; color: "#001521" }
		GradientStop { position: 0.7; color: "#00080E" }
	}

	Model {
		id: model

		x: 0
		y: 0

		width: parent.width
		height: parent.height

		NumberAnimation on rotation {
			id: anim
			from: 360
			to: 0
			duration: 8000
			loops: Animation.Infinite
		}

		MouseArea {
			anchors.fill: parent

			property real startX
			property real startR

			onPressed: {
				startX = mouse.x
				startR = model.rotation
				anim.running = false
			}
			onReleased: {
				anim.from = model.rotation + 360
				anim.to = model.rotation
				anim.running = true
			}
			onPositionChanged: {
				model.rotation = (36000 + (startR - (mouse.x - startX))) % 360
			}
		}
	}
}

// End of the QML string`

// vim: ft=qml.go
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"net/http"
	"os"
	"os/signal"
	"syscall"

	"github.com/go-kit/kit/log"
	"github.com/go-kit/kit/log/level"
)

const (
	ChunkSeconds = 20
	BufferChunks = 2

	BucketName = "radiotimemachine"
)

var (
	logger log.Logger
)

// Configure and return the radio
func configure() *Radio {
	// Parse flags
	var (
		driver        string
		dbhost        string
		dbport        int
		storagedriver string
		record        bool
		broadcast     bool
		addr          string
		loglevel      string
	)

	flag.StringVar(&driver, "driver", "redis", "Database driver: etcd|redis|ssdb")
	flag.StringVar(&dbhost, "dbhost", "localhost", "Database host")
	flag.IntVar(&dbport, "dbport", 6379, "Database port")
	flag.StringVar(&storagedriver, "storagedriver", "", "Override storage driver: gcb")
	flag.BoolVar(&record, "record", true, "Record presets")
	flag.BoolVar(&broadcast, "broadcast", true, "Broadcast to users")
	flag.StringVar(&addr, "addr", ":8080", "Broadcast address")
	flag.StringVar(&loglevel, "loglevel", "info", "Logging level: debug|info|warn|error")

	flag.Parse()

	// Initialize logging
	logger = log.NewLogfmtLogger(os.Stdout)
	switch loglevel {
	case "debug":
		logger = level.NewFilter(logger, level.AllowDebug())
	case "info":
		logger = level.NewFilter(logger, level.AllowInfo())
	case "warn":
		logger = level.NewFilter(logger, level.AllowWarn())
	case "error":
		logger = level.NewFilter(logger, level.AllowError())
	default:
		level.Error(logger).Log("msg", fmt.Sprintf("No %q loglevel found", loglevel))
		os.Exit(1)
	}
	logger = log.With(logger, "caller", log.DefaultCaller)
	logger.Log(
		"msg", "Logging initialized",
		"level", loglevel)

	// Initialize the backend
	var backend Backend
	switch driver {
	case "etcd":
		backend = &EtcdBackend{host: dbhost, port: dbport}
	case "redis":
		backend = &RedisBackend{host: dbhost, port: dbport}
	case "ssdb":
		backend = &RedisBackend{ssdb: true, host: dbhost, port: dbport}
	default:
		level.Error(logger).Log("msg", fmt.Sprintf("No %q driver found", driver))
		os.Exit(1)
	}

	if err := backend.Init(); err != nil {
		level.Error(logger).Log(
			"msg", fmt.Sprintf("Cannot init backend with driver %s", driver),
			"err", err)
		os.Exit(1)
	}
	level.Info(logger).Log(
		"msg", "Backend initialized",
		"driver", driver,
		"dbaddr", fmt.Sprintf("%s:%d", dbhost, dbport))

	// Use separate storage driver
	var storageBackend Backend = backend
	if storagedriver == "gcs" {
		// GOOGLE_CLOUD_PROJECT env var needed if not in GCE
		gcs := &GCSBackend{bucket: BucketName}
		if err := gcs.Init(); err != nil {
			level.Error(logger).Log(
				"msg", "Cannot init GCS backend",
				"err", err)
			os.Exit(1)
		}
		storageBackend = gcs
	}

	// Construct the radio
	return &Radio{
		Server: &http.Server{Addr: addr},
		TapeDeck: &TapeDeck{
			backend: storageBackend.(TapeBackend),
		},
		Presets: &Presets{
			backend: backend.(PresetBackend),
		},
		Options: RadioOptions{
			Broadcast: broadcast,
			Record:    record,
		},
		PathBroadcast: "/listen/",
		PathPreset:    "/preset/",
		//RecordingEngineer: RecordingEngineer{
		//	ch: make(chan StatusMessage, 1),
		//	s:  make(map[string]Status),
		//},
	}
}

func main() {
	radio := configure()
	radio.On()

	sigs := make(chan os.Signal, 1)
	done := make(chan bool, 1)
	signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)

	go func() {
		sig := <-sigs
		level.Info(logger).Log("msg", fmt.Sprintf("Received signal %s", sig))
		radio.Off()
		done <- true
	}()

	<-done
	level.Info(logger).Log("msg", "done")
}
<commit_msg>Log storage backend init<commit_after>package main

import (
	"flag"
	"fmt"
	"net/http"
	"os"
	"os/signal"
	"syscall"

	"github.com/go-kit/kit/log"
	"github.com/go-kit/kit/log/level"
)

const (
	ChunkSeconds = 20
	BufferChunks = 2

	BucketName = "radiotimemachine"
)

var (
	logger log.Logger
)

// Configure and return the radio
func configure() *Radio {
	// Parse flags
	var (
		driver        string
		dbhost        string
		dbport        int
		storagedriver string
		record        bool
		broadcast     bool
		addr          string
		loglevel      string
	)

	flag.StringVar(&driver, "driver", "redis", "Database driver: etcd|redis|ssdb")
	flag.StringVar(&dbhost, "dbhost", "localhost", "Database host")
	flag.IntVar(&dbport, "dbport", 6379, "Database port")
	flag.StringVar(&storagedriver, "storagedriver", "", "Override storage driver: gcb")
	flag.BoolVar(&record, "record", true, "Record presets")
	flag.BoolVar(&broadcast, "broadcast", true, "Broadcast to users")
	flag.StringVar(&addr, "addr", ":8080", "Broadcast address")
	flag.StringVar(&loglevel, "loglevel", "info", "Logging level: debug|info|warn|error")

	flag.Parse()

	// Initialize logging
	logger = log.NewLogfmtLogger(os.Stdout)
	switch loglevel {
	case "debug":
		logger = level.NewFilter(logger, level.AllowDebug())
	case "info":
		logger = level.NewFilter(logger, level.AllowInfo())
	case "warn":
		logger = level.NewFilter(logger, level.AllowWarn())
	case "error":
		logger = level.NewFilter(logger, level.AllowError())
	default:
		level.Error(logger).Log("msg", fmt.Sprintf("No %q loglevel found", loglevel))
		os.Exit(1)
	}
	logger = log.With(logger, "caller", log.DefaultCaller)
	logger.Log(
		"msg", "Logging initialized",
		"level", loglevel)

	// Initialize the backend
	var backend Backend
	switch driver {
	case "etcd":
		backend = &EtcdBackend{host: dbhost, port: dbport}
	case "redis":
		backend = &RedisBackend{host: dbhost, port: dbport}
	case "ssdb":
		backend = &RedisBackend{ssdb: true, host: dbhost, port: dbport}
	default:
		level.Error(logger).Log("msg", fmt.Sprintf("No %q driver found", driver))
		os.Exit(1)
	}

	if err := backend.Init(); err != nil {
		level.Error(logger).Log(
			"msg", fmt.Sprintf("Cannot init backend with driver %s", driver),
			"err", err)
		os.Exit(1)
	}
	level.Info(logger).Log(
		"msg", "Backend initialized",
		"driver", driver,
		"dbaddr", fmt.Sprintf("%s:%d", dbhost, dbport))

	// Use separate storage driver
	var storageBackend Backend = backend
	if storagedriver == "gcs" {
		// GOOGLE_CLOUD_PROJECT env var needed if not in GCE
		gcs := &GCSBackend{bucket: BucketName}
		if err := gcs.Init(); err != nil {
			level.Error(logger).Log(
				"msg", "Cannot init GCS backend",
				"err", err)
			os.Exit(1)
		}
		level.Info(logger).Log(
			"msg", "Storage backend initialized",
			"driver", "gcs")
		storageBackend = gcs
	}

	// Construct the radio
	return &Radio{
		Server: &http.Server{Addr: addr},
		TapeDeck: &TapeDeck{
			backend: storageBackend.(TapeBackend),
		},
		Presets: &Presets{
			backend: backend.(PresetBackend),
		},
		Options: RadioOptions{
			Broadcast: broadcast,
			Record:    record,
		},
		PathBroadcast: "/listen/",
		PathPreset:    "/preset/",
		//RecordingEngineer: RecordingEngineer{
		//	ch: make(chan StatusMessage, 1),
		//	s:  make(map[string]Status),
		//},
	}
}

func main() {
	radio := configure()
	radio.On()

	sigs := make(chan os.Signal, 1)
	done := make(chan bool, 1)
	signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)

	go func() {
		sig := <-sigs
		level.Info(logger).Log("msg", fmt.Sprintf("Received signal %s", sig))
		radio.Off()
		done <- true
	}()

	<-done
	level.Info(logger).Log("msg", "done")
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"log"
	"time"

	"kubernetes-cloudwatch-exporter/settings"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/cloudwatch"
	"github.com/aws/aws-sdk-go/service/elb"
)

var settingsFile = flag.String("settings-file", "./settings.json", "Path to load as the settings file")

func main() {
	settings, err := settings.NewSettings(*settingsFile)

	if err != nil {
		log.Fatalf("settings.NewSettings %v", err)
	}

	sess := session.Must(session.NewSession(&aws.Config{
		Region: aws.String(settings.AWSRegion),
	}))

	// get load balancer
	elbClient := elb.New(sess)

	loadBalancers, err := elbClient.DescribeLoadBalancers(nil)

	if err != nil {
		log.Fatalf("describeLoadBalancers %v", err)
	}

	elbNames := make([]*string, 0)
	elbNamesInCluster := make([]*string, 0)

	for _, elbDesc := range loadBalancers.LoadBalancerDescriptions {
		elbNames = append(elbNames, elbDesc.LoadBalancerName)
	}

	var tagName = settings.TagName
	var tagValue = settings.TagValue

	for i := 0; i < (len(elbNames)/20)+1; i++ {

		startSlice := i * 20
		endSlice := (i + 1) * 20

		if endSlice > len(elbNames) {
			endSlice = len(elbNames)
		}

		// get tags
		loadBalancerTags, err := elbClient.DescribeTags(&elb.DescribeTagsInput{
			LoadBalancerNames: elbNames[startSlice:endSlice],
		})

		if err != nil {
			log.Fatalf("describeTags %v", err)
		}

		// filter to only names that belong to the cluster
		fmt.Println("In Cluster:")

		for _, elbTags := range loadBalancerTags.TagDescriptions {
			inCluster := false

			for _, kvp := range elbTags.Tags {
				if *kvp.Key == tagName && *kvp.Value == tagValue {
					inCluster = true
					break
				}
			}

			if inCluster {
				fmt.Printf("%v\n", *elbTags.LoadBalancerName)
				elbNamesInCluster = append(elbNamesInCluster, elbTags.LoadBalancerName)
			}
		}
	}

	fmt.Printf("Found %d load balancers\n", len(elbNamesInCluster))

	// query metrics
	cwClient := cloudwatch.New(sess)

	now := time.Now()
	then := now.Add(-60 * time.Second)
	metricName := "RequestCount"
	period := int64(60)
	statistic := "Sum"
	namespace := "AWS/ELB"
	dimension := "LoadBalancerName"

	for _, elbName := range elbNamesInCluster {
		log.Printf("Getting stats for %v", *elbName)

		metricStats, err := cwClient.GetMetricStatistics(&cloudwatch.GetMetricStatisticsInput{
			Dimensions: []*cloudwatch.Dimension{&cloudwatch.Dimension{
				Name:  &dimension,
				Value: elbName,
			}},
			StartTime:          &then,
			EndTime:            &now,
			ExtendedStatistics: nil,
			MetricName:         &metricName,
			Namespace:          &namespace,
			Period:             &period,
			Statistics:         []*string{&statistic},
			Unit:               nil,
		})

		if err != nil {
			log.Fatalf("getMetricStatistics %v", err)
		}

		fmt.Printf("metricStats %v", *metricStats)
	}
}
<commit_msg>Use statistics on query<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"time"

	"kubernetes-cloudwatch-exporter/settings"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/cloudwatch"
	"github.com/aws/aws-sdk-go/service/elb"
)

var settingsFile = flag.String("settings-file", "./settings.json", "Path to load as the settings file")

func main() {
	settings, err := settings.NewSettings(*settingsFile)

	if err != nil {
		log.Fatalf("settings.NewSettings %v", err)
	}

	sess := session.Must(session.NewSession(&aws.Config{
		Region: aws.String(settings.AWSRegion),
	}))

	// get load balancer
	elbClient := elb.New(sess)

	loadBalancers, err := elbClient.DescribeLoadBalancers(nil)

	if err != nil {
		log.Fatalf("describeLoadBalancers %v", err)
	}

	elbNames := make([]*string, 0)
	elbNamesInCluster := make([]*string, 0)

	for _, elbDesc := range loadBalancers.LoadBalancerDescriptions {
		elbNames = append(elbNames, elbDesc.LoadBalancerName)
	}

	var tagName = settings.TagName
	var tagValue = settings.TagValue

	for i := 0; i < (len(elbNames)/20)+1; i++ {

		startSlice := i * 20
		endSlice := (i + 1) * 20

		if endSlice > len(elbNames) {
			endSlice = len(elbNames)
		}

		// get tags
		loadBalancerTags, err := elbClient.DescribeTags(&elb.DescribeTagsInput{
			LoadBalancerNames: elbNames[startSlice:endSlice],
		})

		if err != nil {
			log.Fatalf("describeTags %v", err)
		}

		// filter to only names that belong to the cluster
		fmt.Println("In Cluster:")

		for _, elbTags := range loadBalancerTags.TagDescriptions {
			inCluster := false

			for _, kvp := range elbTags.Tags {
				if *kvp.Key == tagName && *kvp.Value == tagValue {
					inCluster = true
					break
				}
			}

			if inCluster {
				fmt.Printf("%v\n", *elbTags.LoadBalancerName)
				elbNamesInCluster = append(elbNamesInCluster, elbTags.LoadBalancerName)
			}
		}
	}

	fmt.Printf("Found %d load balancers\n", len(elbNamesInCluster))

	// query metrics
	cwClient := cloudwatch.New(sess)

	start := time.Now().Add(-settings.Delay + -settings.QueryRange)
	end := start.Add(settings.QueryRange)
	period := int64(settings.Period.Seconds())
	namespace := "AWS/ELB"
	dimension := "LoadBalancerName"

	for _, elbMetric := range settings.Metrics {

		log.Printf("Requesting Metrics %v", elbMetric)

		metricName := elbMetric.Name
		statistic := elbMetric.Statistic

		for _, elbName := range elbNamesInCluster {
			log.Printf("Requesting for ELB %v", *elbName)

			metricStats, err := cwClient.GetMetricStatistics(&cloudwatch.GetMetricStatisticsInput{
				Dimensions: []*cloudwatch.Dimension{&cloudwatch.Dimension{
					Name:  &dimension,
					Value: elbName,
				}},
				StartTime:          &start,
				EndTime:            &end,
				ExtendedStatistics: nil,
				MetricName:         &metricName,
				Namespace:          &namespace,
				Period:             &period,
				Statistics:         []*string{&statistic},
				Unit:               nil,
			})

			if err != nil {
				log.Fatalf("getMetricStatistics %v", err)
			}

			fmt.Printf("metricStats %v", *metricStats)
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"os"

	"github.com/op/go-logging"
	"github.com/urfave/cli"
)

// logger
var log *logging.Logger

func init() {
	log = logging.MustGetLogger("hod")
	var format = "%{color}%{level} %{shortfile} %{time:Jan 02 15:04:05} %{color:reset} ▶ %{message}"
	var logBackend = logging.NewLogBackend(os.Stderr, "", 0)
	logBackendLeveled := logging.AddModuleLevel(logBackend)
	logging.SetBackend(logBackendLeveled)
	logging.SetFormatter(logging.MustStringFormatter(format))
}

func main() {
	app := cli.NewApp()
	app.Name = "hod"
	app.Version = "0.1"
	app.Usage = "BRICK database and query engine"

	app.Commands = []cli.Command{
		{
			Name:   "benchload",
			Usage:  "Benchmark loading a turtle file",
			Action: benchLoad,
		},
		{
			Name:   "dump",
			Usage:  "Dump contents of turtle file",
			Action: dump,
		},
		{
			Name:   "viewclass",
			Usage:  "PDF visualization of class structure of file",
			Action: classGraph,
		},
		{
			Name:   "dumpgraph",
			Usage:  "PDF visualization of TTL file. WARNING this can get really big",
			Action: dumpGraph,
		},
		{
			Name:   "load",
			Usage:  "Load dataset into hoddb",
			Action: load,
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "config, c",
					Usage: "Path to hoddb config file",
				},
			},
		},
		{
			Name:   "loadLinks",
			Usage:  "Load link json file into hoddb",
			Action: loadLinks,
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "config, c",
					Usage: "Path to hoddb config file",
				},
			},
		},
		{
			Name:   "cli",
			Usage:  "Start hoddb from existing database",
			Action: startCLI,
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "config, c",
					Usage: "Path to hoddb config file",
				},
			},
		},
		{
			Name:   "http",
			Usage:  "Start hoddb HTTP server from existing database",
			Action: startHTTP,
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "config, c",
					Usage: "Path to hoddb config file",
				},
			},
		},
	}
	app.Run(os.Args)
}
<commit_msg>version bump<commit_after>package main

import (
	"os"

	"github.com/op/go-logging"
	"github.com/urfave/cli"
)

// logger
var log *logging.Logger

func init() {
	log = logging.MustGetLogger("hod")
	var format = "%{color}%{level} %{shortfile} %{time:Jan 02 15:04:05} %{color:reset} ▶ %{message}"
	var logBackend = logging.NewLogBackend(os.Stderr, "", 0)
	logBackendLeveled := logging.AddModuleLevel(logBackend)
	logging.SetBackend(logBackendLeveled)
	logging.SetFormatter(logging.MustStringFormatter(format))
}

func main() {
	app := cli.NewApp()
	app.Name = "hod"
	app.Version = "0.2"
	app.Usage = "BRICK database and query engine"

	app.Commands = []cli.Command{
		{
			Name:   "benchload",
			Usage:  "Benchmark loading a turtle file",
			Action: benchLoad,
		},
		{
			Name:   "dump",
			Usage:  "Dump contents of turtle file",
			Action: dump,
		},
		{
			Name:   "viewclass",
			Usage:  "PDF visualization of class structure of file",
			Action: classGraph,
		},
		{
			Name:   "dumpgraph",
			Usage:  "PDF visualization of TTL file. WARNING this can get really big",
			Action: dumpGraph,
		},
		{
			Name:   "load",
			Usage:  "Load dataset into hoddb",
			Action: load,
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "config, c",
					Usage: "Path to hoddb config file",
				},
			},
		},
		{
			Name:   "loadLinks",
			Usage:  "Load link json file into hoddb",
			Action: loadLinks,
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "config, c",
					Usage: "Path to hoddb config file",
				},
			},
		},
		{
			Name:   "cli",
			Usage:  "Start hoddb from existing database",
			Action: startCLI,
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "config, c",
					Usage: "Path to hoddb config file",
				},
			},
		},
		{
			Name:   "http",
			Usage:  "Start hoddb HTTP server from existing database",
			Action: startHTTP,
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "config, c",
					Usage: "Path to hoddb config file",
				},
			},
		},
	}
	app.Run(os.Args)
}
<|endoftext|>


<commit_before>package main

import (
	"crypto/sha1"
	"database/sql"
	"encoding/base64"
	"encoding/json"
	"encoding/xml"
	"fmt"
	"html"
	"html/template"
	"io"
	"io/ioutil"
	"log"
	"net/http"

	"github.com/dchest/uniuri"
	"github.com/ewhal/pygments"
	_ "github.com/go-sql-driver/mysql"
	"github.com/gorilla/mux"
)

const (
	ADDRESS  = "http://localhost:9900"
	LENGTH   = 6
	PORT     = ":9900"
	USERNAME = ""
	PASS     = ""
	NAME     = ""
	DATABASE = USERNAME + ":" + PASS + "@/" + NAME + "?charset=utf8"
)

type Response struct {
	ID     string `json:"id"`
	TITLE  string `json:"title"`
	HASH   string `json:"hash"`
	URL    string `json:"url"`
	SIZE   int    `json:"size"`
	DELKEY string `json:"delkey"`
}

type Page struct {
	Title    string
	Body     []byte
	Raw      string
	Home     string
	Download string
	Clone    string
}

func check(err error) {
	if err != nil {
		fmt.Println(err)
	}
}

func generateName() string {
	s := uniuri.NewLen(LENGTH)
	db, err := sql.Open("mysql", DATABASE)
	check(err)

	query, err := db.Query("select id from pastebin")
	for query.Next() {
		var id string
		err := query.Scan(&id)
		if err != nil {

		}
		if id == s {
			generateName()
		}
	}
	db.Close()

	return s

}
func hash(paste string) string {
	hasher := sha1.New()

	hasher.Write([]byte(paste))
	sha := base64.URLEncoding.EncodeToString(hasher.Sum(nil))
	return sha
}

func save(raw string, lang string, title string) []string {
	db, err := sql.Open("mysql", DATABASE)
	check(err)

	sha := hash(raw)
	query, err := db.Query("select id, title hash, data, delkey from pastebin")
	for query.Next() {
		var id, title, hash, paste, delkey string
		err := query.Scan(&id, &title, &hash, &paste, &delkey)
		check(err)
		if hash == sha {
			url := ADDRESS + "/p/" + id
			if title == "" {
				return []string{id, title, hash, url, paste, delkey}
			}
		}
	}
	id := generateName()
	var url string
	if lang == "" {
		url = ADDRESS + "/p/" + id
	} else {
		url = ADDRESS + "/p/" + id + "/" + lang
	}
	delKey := uniuri.NewLen(40)
	paste := html.EscapeString(raw)

	stmt, err := db.Prepare("INSERT INTO pastebin(id, title, hash, data, delkey) values(?,?,?,?,?)")
	check(err)
	if title == "" {
		_, err = stmt.Exec(id, id, sha, paste, delKey)
		check(err)
	} else {
		_, err = stmt.Exec(id, html.EscapeString(title), sha, paste, delKey)
		check(err)
	}
	db.Close()
	return []string{id, title, sha, url, paste, delKey}
}

func delHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	paste := vars["pasteId"]
	delkey := vars["delKey"]

	db, err := sql.Open("mysql", DATABASE)
	check(err)

	stmt, err := db.Prepare("delete from pastebin where delkey=?")
	check(err)

	res, err := stmt.Exec(html.EscapeString(delkey))
	check(err)

	_, err = res.RowsAffected()
	if err == sql.ErrNoRows {
		io.WriteString(w, "Error invalid paste")
	} else {
		io.WriteString(w, paste+" deleted")
	}
	db.Close()

}
func saveHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	output := vars["output"]
	switch r.Method {
	case "POST":
		paste := r.FormValue("p")
		lang := r.FormValue("lang")
		title := r.FormValue("title")
		if paste == "" {
			http.Error(w, "Empty paste", 500)
			return
		}
		values := save(paste, lang, title)
		b := &Response{
			ID:     values[0],
			TITLE:  values[1],
			HASH:   values[2],
			URL:    values[3],
			SIZE:   len(values[4]),
			DELKEY: values[5],
		}

		switch output {
		case "json":

			w.Header().Set("Content-Type", "application/json")
			err := json.NewEncoder(w).Encode(b)

			if err != nil {
				http.Error(w, err.Error(), http.StatusInternalServerError)
				return
			}
		case "xml":
			x, err := xml.MarshalIndent(b, "", "  ")
			if err != nil {
				http.Error(w, err.Error(), http.StatusInternalServerError)
				return
			}

			w.Header().Set("Content-Type", "application/xml")
			w.Write(x)

		case "html":
			w.Header().Set("Content-Type", "text/html")
			io.WriteString(w, "
URL: "+b.URL+"
")
			io.WriteString(w, "
Delete Key: "+b.DELKEY+"
")

		case "redirect":
			http.Redirect(w, r, b.URL, 301)

		default:
			w.Header().Set("Content-Type", "plain/text")
			io.WriteString(w, b.URL+"\n")
			io.WriteString(w, "delete key: "+b.DELKEY+"\n")
		}
	}

}

func highlight(s string, lang string) (string, error) {

	highlight, err := pygments.Highlight(html.UnescapeString(s), html.EscapeString(lang), "html", "style=autumn,linenos=True, lineanchors=True,anchorlinenos=True,noclasses=True,", "utf-8")
	if err != nil {
		return "", err
	}
	return highlight, nil

}

func getPaste(paste string, lang string) (string, string) {
	param1 := html.EscapeString(paste)
	db, err := sql.Open("mysql", DATABASE)
	var title, s string
	err = db.QueryRow("select title, data from pastebin where id=?", param1).Scan(&title, &s)
	db.Close()
	check(err)

	if err == sql.ErrNoRows {
		return "Error invalid paste", ""
	} else {
		if lang == "" {
			return html.UnescapeString(s), html.UnescapeString(title)
		} else {
			high, err := highlight(s, lang)
			check(err)
			return high, html.UnescapeString(title)

		}
	}

}

var templates = template.Must(template.ParseFiles("assets/paste.html", "assets/index.html", "assets/clone.html"))
var syntax, _ = ioutil.ReadFile("assets/syntax.html")

func pasteHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	paste := vars["pasteId"]
	lang := vars["lang"]
	s, title := getPaste(paste, lang)
	link := ADDRESS + "/raw/" + paste
	download := ADDRESS + "/download/" + paste
	clone := ADDRESS + "/clone/" + paste
	if lang == "" {
		p := &Page{
			Title:    title,
			Body:     []byte(s),
			Raw:      link,
			Home:     ADDRESS,
			Download: download,
			Clone:    clone,
		}
		err := templates.ExecuteTemplate(w, "paste.html", p)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
		}

	} else {
		fmt.Fprintf(w, string(syntax), paste, paste, s, ADDRESS, download, link, clone)

	}
}

func cloneHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	paste := vars["pasteId"]
	s, title := getPaste(paste, "")
	link := ADDRESS + "/raw/" + paste
	download := ADDRESS + "/download/" + paste
	clone := ADDRESS + "/clone/" + paste
	p := &Page{
		Title:    title,
		Body:     []byte(s),
		Raw:      link,
		Home:     ADDRESS,
		Download: download,
		Clone:    clone,
	}
	err := templates.ExecuteTemplate(w, "clone.html", p)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

}
func downloadHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	paste := vars["pasteId"]
	s, _ := getPaste(paste, "")
	w.Header().Set("Content-Disposition", "attachment; filename="+paste)
	w.Header().Set("Content-Type", r.Header.Get("Content-Type"))
	io.WriteString(w, s)

}
func rawHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	paste := vars["pasteId"]
	s, _ := getPaste(paste, "")
	io.WriteString(w, s)

}

func main() {
	router := mux.NewRouter()
	router.HandleFunc("/p/{pasteId}", pasteHandler)
	router.HandleFunc("/raw/{pasteId}", rawHandler)
	router.HandleFunc("/p/{pasteId}/{lang}", pasteHandler)
	router.HandleFunc("/clone/{pasteId}", cloneHandler)
	router.HandleFunc("/download/{pasteId}", downloadHandler)
	router.HandleFunc("/save", saveHandler)
	router.HandleFunc("/save/{output}", saveHandler)
	router.HandleFunc("/del/{pasteId}/{delKey}", delHandler)
	router.PathPrefix("/").Handler(http.StripPrefix("/", http.FileServer(http.Dir("assets/"))))
	err := http.ListenAndServe(PORT, router)
	if err != nil {
		log.Fatal(err)
	}

}
<commit_msg>Add missing comma<commit_after>package main

import (
	"crypto/sha1"
	"database/sql"
	"encoding/base64"
	"encoding/json"
	"encoding/xml"
	"fmt"
	"html"
	"html/template"
	"io"
	"io/ioutil"
	"log"
	"net/http"

	"github.com/dchest/uniuri"
	"github.com/ewhal/pygments"
	_ "github.com/go-sql-driver/mysql"
	"github.com/gorilla/mux"
)

const (
	ADDRESS  = "http://localhost:9900"
	LENGTH   = 6
	PORT     = ":9900"
	USERNAME = ""
	PASS     = ""
	NAME     = ""
	DATABASE = USERNAME + ":" + PASS + "@/" + NAME + "?charset=utf8"
)

type Response struct {
	ID     string `json:"id"`
	TITLE  string `json:"title"`
	HASH   string `json:"hash"`
	URL    string `json:"url"`
	SIZE   int    `json:"size"`
	DELKEY string `json:"delkey"`
}

type Page struct {
	Title    string
	Body     []byte
	Raw      string
	Home     string
	Download string
	Clone    string
}

func check(err error) {
	if err != nil {
		fmt.Println(err)
	}
}

func generateName() string {
	s := uniuri.NewLen(LENGTH)
	db, err := sql.Open("mysql", DATABASE)
	check(err)

	query, err := db.Query("select id from pastebin")
	for query.Next() {
		var id string
		err := query.Scan(&id)
		if err != nil {

		}
		if id == s {
			generateName()
		}
	}
	db.Close()

	return s

}
func hash(paste string) string {
	hasher := sha1.New()

	hasher.Write([]byte(paste))
	sha := base64.URLEncoding.EncodeToString(hasher.Sum(nil))
	return sha
}

func save(raw string, lang string, title string) []string {
	db, err := sql.Open("mysql", DATABASE)
	check(err)

	sha := hash(raw)
	query, err := db.Query("select id, title, hash, data, delkey from pastebin")
	for query.Next() {
		var id, title, hash, paste, delkey string
		err := query.Scan(&id, &title, &hash, &paste, &delkey)
		check(err)
		if hash == sha {
			url := ADDRESS + "/p/" + id
			if title == "" {
				return []string{id, title, hash, url, paste, delkey}
			}
		}
	}
	id := generateName()
	var url string
	if lang == "" {
		url = ADDRESS + "/p/" + id
	} else {
		url = ADDRESS + "/p/" + id + "/" + lang
	}
	delKey := uniuri.NewLen(40)
	paste := html.EscapeString(raw)

	stmt, err := db.Prepare("INSERT INTO pastebin(id, title, hash, data, delkey) values(?,?,?,?,?)")
	check(err)
	if title == "" {
		_, err = stmt.Exec(id, id, sha, paste, delKey)
		check(err)
	} else {
		_, err = stmt.Exec(id, html.EscapeString(title), sha, paste, delKey)
		check(err)
	}
	db.Close()
	return []string{id, title, sha, url, paste, delKey}
}

func delHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	paste := vars["pasteId"]
	delkey := vars["delKey"]

	db, err := sql.Open("mysql", DATABASE)
	check(err)

	stmt, err := db.Prepare("delete from pastebin where delkey=?")
	check(err)

	res, err := stmt.Exec(html.EscapeString(delkey))
	check(err)

	_, err = res.RowsAffected()
	if err == sql.ErrNoRows {
		io.WriteString(w, "Error invalid paste")
	} else {
		io.WriteString(w, paste+" deleted")
	}
	db.Close()

}
func saveHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	output := vars["output"]
	switch r.Method {
	case "POST":
		paste := r.FormValue("p")
		lang := r.FormValue("lang")
		title := r.FormValue("title")
		if paste == "" {
			http.Error(w, "Empty paste", 500)
			return
		}
		values := save(paste, lang, title)
		b := &Response{
			ID:     values[0],
			TITLE:  values[1],
			HASH:   values[2],
			URL:    values[3],
			SIZE:   len(values[4]),
			DELKEY: values[5],
		}

		switch output {
		case "json":

			w.Header().Set("Content-Type", "application/json")
			err := json.NewEncoder(w).Encode(b)

			if err != nil {
				http.Error(w, err.Error(), http.StatusInternalServerError)
				return
			}
		case "xml":
			x, err := xml.MarshalIndent(b, "", "  ")
			if err != nil {
				http.Error(w, err.Error(), http.StatusInternalServerError)
				return
			}

			w.Header().Set("Content-Type", "application/xml")
			w.Write(x)

		case "html":
			w.Header().Set("Content-Type", "text/html")
			io.WriteString(w, "
URL: "+b.URL+"
")
			io.WriteString(w, "
Delete Key: "+b.DELKEY+"
")

		case "redirect":
			http.Redirect(w, r, b.URL, 301)

		default:
			w.Header().Set("Content-Type", "plain/text")
			io.WriteString(w, b.URL+"\n")
			io.WriteString(w, "delete key: "+b.DELKEY+"\n")
		}
	}

}

func highlight(s string, lang string) (string, error) {

	highlight, err := pygments.Highlight(html.UnescapeString(s), html.EscapeString(lang), "html", "style=autumn,linenos=True, lineanchors=True,anchorlinenos=True,noclasses=True,", "utf-8")
	if err != nil {
		return "", err
	}
	return highlight, nil

}

func getPaste(paste string, lang string) (string, string) {
	param1 := html.EscapeString(paste)
	db, err := sql.Open("mysql", DATABASE)
	var title, s string
	err = db.QueryRow("select title, data from pastebin where id=?", param1).Scan(&title, &s)
	db.Close()
	check(err)

	if err == sql.ErrNoRows {
		return "Error invalid paste", ""
	} else {
		if lang == "" {
			return html.UnescapeString(s), html.UnescapeString(title)
		} else {
			high, err := highlight(s, lang)
			check(err)
			return high, html.UnescapeString(title)

		}
	}

}

var templates = template.Must(template.ParseFiles("assets/paste.html", "assets/index.html", "assets/clone.html"))
var syntax, _ = ioutil.ReadFile("assets/syntax.html")

func pasteHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	paste := vars["pasteId"]
	lang := vars["lang"]
	s, title := getPaste(paste, lang)
	link := ADDRESS + "/raw/" + paste
	download := ADDRESS + "/download/" + paste
	clone := ADDRESS + "/clone/" + paste
	if lang == "" {
		p := &Page{
			Title:    title,
			Body:     []byte(s),
			Raw:      link,
			Home:     ADDRESS,
			Download: download,
			Clone:    clone,
		}
		err := templates.ExecuteTemplate(w, "paste.html", p)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
		}

	} else {
		fmt.Fprintf(w, string(syntax), paste, paste, s, ADDRESS, download, link, clone)

	}
}

func cloneHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	paste := vars["pasteId"]
	s, title := getPaste(paste, "")
	link := ADDRESS + "/raw/" + paste
	download := ADDRESS + "/download/" + paste
	clone := ADDRESS + "/clone/" + paste
	p := &Page{
		Title:    title,
		Body:     []byte(s),
		Raw:      link,
		Home:     ADDRESS,
		Download: download,
		Clone:    clone,
	}
	err := templates.ExecuteTemplate(w, "clone.html", p)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

}
func downloadHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	paste := vars["pasteId"]
	s, _ := getPaste(paste, "")
	w.Header().Set("Content-Disposition", "attachment; filename="+paste)
	w.Header().Set("Content-Type", r.Header.Get("Content-Type"))
	io.WriteString(w, s)

}
func rawHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	paste := vars["pasteId"]
	s, _ := getPaste(paste, "")
	io.WriteString(w, s)

}

func main() {
	router := mux.NewRouter()
	router.HandleFunc("/p/{pasteId}", pasteHandler)
	router.HandleFunc("/raw/{pasteId}", rawHandler)
	router.HandleFunc("/p/{pasteId}/{lang}", pasteHandler)
	router.HandleFunc("/clone/{pasteId}", cloneHandler)
	router.HandleFunc("/download/{pasteId}", downloadHandler)
	router.HandleFunc("/save", saveHandler)
	router.HandleFunc("/save/{output}", saveHandler)
	router.HandleFunc("/del/{pasteId}/{delKey}", delHandler)
	router.PathPrefix("/").Handler(http.StripPrefix("/", http.FileServer(http.Dir("assets/"))))
	err := http.ListenAndServe(PORT, router)
	if err != nil {
		log.Fatal(err)
	}

}
<|endoftext|>


<commit_before>package main

import (
	"compress/gzip"
	"flag"
	"fmt"
	"io"
	"log"
	"net/http"
	"os/exec"
	"path"
	"regexp"
	"strings"
)

type gitHandler struct {
	method      string
	regexp      *regexp.Regexp
	handle_func func(string, string, http.ResponseWriter, *http.Request)
	rpc         string
}

var repo_root string

var git_handlers = [...]gitHandler{
	gitHandler{"GET", regexp.MustCompile(`\A(/..*)/info/refs\z`), handle_get_info_refs, ""},
	gitHandler{"POST", regexp.MustCompile(`\A(/..*)/git-upload-pack\z`), handle_post_rpc, "git-upload-pack"},
	gitHandler{"POST", regexp.MustCompile(`\A(/..*)/git-receive-pack\z`), handle_post_rpc, "git-receive-pack"},
}

func main() {
	flag.Parse()
	repo_root = flag.Arg(0)
	log.Printf("repo_root: %s", repo_root)
	http.HandleFunc("/", git_handler)
	log.Fatal(http.ListenAndServe(":8080", nil))
}

func git_handler(w http.ResponseWriter, r *http.Request) {
	log.Print(r)
	for _, g := range git_handlers {
		m := g.regexp.FindStringSubmatch(r.URL.Path)
		if r.Method == g.method && m != nil {
			g.handle_func(g.rpc, path.Join(repo_root, m[1]), w, r)
			return
		}
	}
	log.Print("Reached end of dispatch for loop")
	w.WriteHeader(404)
}

func handle_get_info_refs(_ string, path string, w http.ResponseWriter, r *http.Request) {
	rpc := r.URL.Query().Get("service")
	switch rpc {
	case "git-upload-pack", "git-receive-pack":
		cmd := exec.Command("git", strings.TrimPrefix(rpc, "git-"), "--stateless-rpc", "--advertise-refs", path)
		log.Print(cmd.Args)
		stdout, err := cmd.StdoutPipe()
		if err != nil {
			fail_500(w, err)
			return
		}
		if err := cmd.Start(); err != nil {
			fail_500(w, err)
			return
		}
		w.Header().Add("Content-Type", fmt.Sprintf("application/x-%s-advertisement", rpc))
		no_cache(w)
		fmt.Fprintf(w, "%s0000", pkt_line(fmt.Sprintf("# service=%s\n", rpc)))
		if _, err := io.Copy(w, stdout); err != nil {
			fail_500(w, err)
			return
		}
		if err := cmd.Wait(); err != nil {
			fail_500(w, err)
			return
		}
	case "":
		log.Print("dumb info refs")
	}
}

func handle_post_rpc(rpc string, path string, w http.ResponseWriter, r *http.Request) {
	var body io.Reader
	var err error
	if r.Header.Get("Content-Encoding") == "gzip" {
		body, err = gzip.NewReader(r.Body)
		if err != nil {
			fail_500(w, err)
			return
		}
	} else {
		body = r.Body
	}
	cmd := exec.Command("git", strings.TrimPrefix(rpc, "git-"), "--stateless-rpc", path)
	log.Print(cmd.Args)
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		fail_500(w, err)
		return
	}
	stdin, err := cmd.StdinPipe()
	if err != nil {
		fail_500(w, err)
		return
	}
	if err := cmd.Start(); err != nil {
		fail_500(w, err)
		return
	}
	w.Header().Add("Content-Type", fmt.Sprintf("application/x-%s-result", rpc))
	no_cache(w)
	if _, err := io.Copy(stdin, body); err != nil {
		fail_500(w, err)
		return
	}
	stdin.Close()
	if _, err := io.Copy(w, stdout); err != nil {
		fail_500(w, err)
		return
	}
	if err := cmd.Wait(); err != nil {
		fail_500(w, err)
		return
	}
}

func pkt_line(s string) string {
	return fmt.Sprintf("%04x%s", len(s)+4, s)
}

func fail_500(w http.ResponseWriter, err error) {
	w.WriteHeader(500)
	log.Print(err)
}

func no_cache(w http.ResponseWriter) {
	w.Header().Add("Cache-Control", "no-cache")
}
<commit_msg>Auth requests against gitlab<commit_after>package main

import (
	"bytes"
	"compress/gzip"
	"flag"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"os/exec"
	"path"
	"regexp"
	"strings"
)

type gitHandler struct {
	method      string
	regexp      *regexp.Regexp
	handle_func func(string, string, string, http.ResponseWriter, *http.Request)
	rpc         string
}

var http_client = &http.Client{}
var repo_root string
var listen_addr = flag.String("listen_addr", "localhost:8181", "Listen address for HTTP server")

var git_handlers = [...]gitHandler{
	gitHandler{"GET", regexp.MustCompile(`\A(/..*)/info/refs\z`), handle_get_info_refs, ""},
	gitHandler{"POST", regexp.MustCompile(`\A(/..*)/git-upload-pack\z`), handle_post_rpc, "git-upload-pack"},
	gitHandler{"POST", regexp.MustCompile(`\A(/..*)/git-receive-pack\z`), handle_post_rpc, "git-receive-pack"},
}

func main() {
	flag.Parse()
	repo_root = flag.Arg(0)
	log.Printf("repo_root: %s", repo_root)
	http.HandleFunc("/", git_handler)
	log.Fatal(http.ListenAndServe(*listen_addr, nil))
}

func git_handler(w http.ResponseWriter, r *http.Request) {
	log.Print(r.Method, " ", r.URL)
	for _, g := range git_handlers {
		m := g.regexp.FindStringSubmatch(r.URL.Path)
		if r.Method == g.method && m != nil {
			response := validation_request(r)
			if response.StatusCode != 200 {
				w.Header().Set("WWW-Authenticate", response.Header.Get("WWW-Authenticate"))
				w.WriteHeader(response.StatusCode)
				return
			}
			buf := new(bytes.Buffer)
			_, err := buf.ReadFrom(response.Body)
			if err != nil {
				fail_500(w, err)
				return
			}
			user := buf.String()
			g.handle_func(user, g.rpc, path.Join(repo_root, m[1]), w, r)
			return
		}
	}
	log.Print("Reached end of dispatch for loop")
	w.WriteHeader(404)
}

func validation_request(r *http.Request) *http.Response {
	var err error
	result := &http.Response{}
	url := fmt.Sprintf("http://localhost:8080%s", r.URL.RequestURI())
	vreq, err := http.NewRequest(r.Method, url, nil)
	if err != nil {
		result.StatusCode = 500
		return result
	}
	for k, v := range r.Header {
		vreq.Header[k] = v
	}
	user, password, _ := r.BasicAuth()
	vreq.SetBasicAuth(user, password)
	result, err = http_client.Do(vreq)
	if err != nil {
		result.StatusCode = 500
		return result
	}
	return result
}

func handle_get_info_refs(user string, _ string, path string, w http.ResponseWriter, r *http.Request) {
	rpc := r.URL.Query().Get("service")
	switch rpc {
	case "git-upload-pack", "git-receive-pack":
		cmd := exec.Command("git", strings.TrimPrefix(rpc, "git-"), "--stateless-rpc", "--advertise-refs", path)
		cmd.Env = []string{fmt.Sprintf("PATH=%s", os.Getenv("PATH")), fmt.Sprintf("GL_ID=%s", user)}
		stdout, err := cmd.StdoutPipe()
		if err != nil {
			fail_500(w, err)
			return
		}
		if err := cmd.Start(); err != nil {
			fail_500(w, err)
			return
		}
		w.Header().Add("Content-Type", fmt.Sprintf("application/x-%s-advertisement", rpc))
		no_cache(w)
		fmt.Fprintf(w, "%s0000", pkt_line(fmt.Sprintf("# service=%s\n", rpc)))
		if _, err := io.Copy(w, stdout); err != nil {
			fail_500(w, err)
			return
		}
		if err := cmd.Wait(); err != nil {
			fail_500(w, err)
			return
		}
	case "":
		log.Print("dumb info refs")
	}
}

func handle_post_rpc(user string, rpc string, path string, w http.ResponseWriter, r *http.Request) {
	var body io.Reader
	var err error
	if r.Header.Get("Content-Encoding") == "gzip" {
		body, err = gzip.NewReader(r.Body)
		if err != nil {
			fail_500(w, err)
			return
		}
	} else {
		body = r.Body
	}
	cmd := exec.Command("git", strings.TrimPrefix(rpc, "git-"), "--stateless-rpc", path)
	cmd.Env = []string{fmt.Sprintf("PATH=%s", os.Getenv("PATH")), fmt.Sprintf("GL_ID=%s", user)}
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		fail_500(w, err)
		return
	}
	stdin, err := cmd.StdinPipe()
	if err != nil {
		fail_500(w, err)
		return
	}
	if err := cmd.Start(); err != nil {
		fail_500(w, err)
		return
	}
	w.Header().Add("Content-Type", fmt.Sprintf("application/x-%s-result", rpc))
	no_cache(w)
	if _, err := io.Copy(stdin, body); err != nil {
		fail_500(w, err)
		return
	}
	stdin.Close()
	if _, err := io.Copy(w, stdout); err != nil {
		fail_500(w, err)
		return
	}
	if err := cmd.Wait(); err != nil {
		fail_500(w, err)
		return
	}
}

func pkt_line(s string) string {
	return fmt.Sprintf("%04x%s", len(s)+4, s)
}

func fail_500(w http.ResponseWriter, err error) {
	w.WriteHeader(500)
	log.Print(err)
}

func no_cache(w http.ResponseWriter) {
	w.Header().Add("Cache-Control", "no-cache")
}
<|endoftext|>


<commit_before>package main

import (
	"aragnis.com/autousts/db"
	"aragnis.com/autousts/search"
	"fmt"
	"github.com/longnguyen11288/go-transmission/transmission"
	"os"
	"strconv"
	"strings"
	"time"
)

func syncShow(show *db.Show, out chan<- *search.Result, fin chan<- bool) {
	var k search.Kickass

	for {
		pointer, ok := show.NextPointer()
		if !ok {
			break
		}

		query := fmt.Sprintf(show.Query, pointer)

		results, err := k.Search(query, search.Options{})
		if err != nil {
			fmt.Printf("Search error: " + err.Error())
			break
		}

		var chosen *search.Result

		for _, result := range results {
			if result.Seeders < show.SeedersMin {
				continue
			}

			rptr, err := db.PointerFromString(result.Name)
			if err != nil || rptr.String() != pointer.String() {
				continue
			}

			chosen = result
			break
		}

		if chosen == nil {
			break
		}

		out <- chosen
		show.Pointer = pointer
	}

	fin <- true
}

func sync(dbh *db.Database) {
	tc := transmission.New("http://127.0.0.1:9091", "", "")
	if _, err := tc.GetTorrents(); err != nil {
		fmt.Println("Could not connect to Transmission RPC API: " + err.Error())
		return
	}

	var results []*search.Result

	waiting := 0
	fin := make(chan bool)
	rec := make(chan *search.Result)

	for _, show := range dbh.Shows {
		waiting += 1
		go syncShow(show, rec, fin)
	}

	for waiting > 0 {
		select {
		case result := <-rec:
			results = append(results, result)

		case <-fin:
			waiting -= 1
		}
	}

	for _, result := range results {
		fmt.Printf("Found torrent: '%s'\n", result.Name)

		if _, err := tc.AddTorrentByFilename(result.MagnetURL, ""); err != nil {
			fmt.Println("Error adding torrent: " + err.Error())
			fmt.Println("Stopping...")
			return
		}
	}

	fmt.Printf("Found %d torrent(s)\n", len(results))

	if err := dbh.Sync(); err != nil {
		fmt.Println("Error syncing database: " + err.Error())
	}
}

func viewAll(dbh *db.Database) {
	for _, show := range dbh.Shows {
		name := show.Name
		if len(name) > 15 {
			name = name[:15] + "..."
		}

		fmt.Printf("%-20s %s\n", name, show.Pointer)
	}
}

func view(dbh *db.Database, name string) {
	show, ok := dbh.FindShow(name)
	if !ok {
		fmt.Printf("The specified show '%s' not found.\n", name)
		return
	}

	fmt.Printf("Name        : %s\n", show.Name)
	fmt.Printf("Query       : %s\n", show.Query)
	fmt.Printf("Min seeders : %d\n", show.SeedersMin)
	fmt.Printf("Prefer HQ   : %t\n", show.PreferHQ)
	fmt.Printf("Pointer     : %s\n", show.Pointer)

	if len(show.Seasons) > 0 {
		fmt.Println("")
		fmt.Println("Season  Episodes  Begin")

		for _, season := range show.Seasons {
			fmt.Printf("%-7d %-9d %s\n", season.Number, season.EpisodeCount, season.Begin)
		}
	}
}

func set(dbh *db.Database, args []string) {
	if len(args) != 3 {
		fmt.Println(`Usage:
  set SHOW PROP VALUE
  set SHOW:SEASON PROP VALUE

Show properties:
  query       : string, search query, must contain '%s' for pointer
  min-seeders : uint, minimum number of seeders allowed
  prefer-hq   : boolean
  pointer     : last downloaded episode

Season properties:
  epc   : uint, episode count
  begin : date, begin date`)
		return
	}

	split := strings.Split(args[0], ":")
	key := args[1]
	value := args[2]

	var (
		ok bool

		name   string = split[0]
		number uint

		show   *db.Show
		season *db.Season
	)

	if len(split) == 2 {
		v, err := strconv.Atoi(split[1])
		if err != nil || v <= 0 {
			fmt.Println("Invalid season specified")
			return
		}
		number = uint(v)
	}

	show, ok = dbh.FindShow(name)
	if !ok {
		show = &db.Show{
			Name: name,
		}
		dbh.Shows = append(dbh.Shows, show)
	}

	if number != 0 {
		season, ok = show.FindSeason(number)
		if !ok {
			season = &db.Season{
				Number: number,
			}
			show.Seasons = append(show.Seasons, season)
		}
	}

	if season != nil {
		switch key {
		case "epc":
			epc, err := strconv.Atoi(value)
			if err != nil || epc < 0 {
				fmt.Println("Invalid value")
				break
			}
			season.EpisodeCount = uint(epc)

		case "begin":
			begin, err := time.Parse("2006-01-02", value)
			if err != nil {
				fmt.Println("Invalid value: " + err.Error())
				break
			}
			season.Begin = begin

		default:
			fmt.Println("Invalid key")
		}
	} else {
		switch key {
		case "query":
			if strings.Count(value, "%s") != 1 {
				fmt.Println("The value must contain exactly one '%s'")
				break
			}
			show.Query = value

		case "seeders-min":
			v, err := strconv.Atoi(value)
			if err != nil || v < 0 {
				fmt.Println("Invalid value")
				break
			}
			show.SeedersMin = uint(v)

		case "prefer-hq":
			switch value {
			case "true":
				show.PreferHQ = true
			case "false":
				show.PreferHQ = false
			default:
				fmt.Println("Invalid value. Allowed values are: true, false")
			}

		case "pointer":
			pointer, err := db.PointerFromString(value)
			if err != nil {
				fmt.Println("Invalid value")
				break
			}
			show.Pointer = pointer

		default:
			fmt.Println("Invalid key")
		}
	}

	if err := dbh.Sync(); err != nil {
		fmt.Println("Error syncing database: " + err.Error())
	}
}

func main() {
	dbh, err := db.NewDatabase("testdb")
	if err != nil {
		fmt.Println("Could not open the database", err)
		return
	}

	var (
		verb     string
		verbArgs []string
	)

	if len(os.Args) >= 2 {
		verb = os.Args[1]
		verbArgs = os.Args[2:]
	}

	switch verb {
	case "sync":
		sync(dbh)
	case "view":
		if len(verbArgs) == 1 {
			view(dbh, verbArgs[0])
		} else {
			viewAll(dbh)
		}
	case "set":
		set(dbh, verbArgs)
	default:
		fmt.Println("No verb specified: {sync, view, set}")
	}

	dbh.Close()
}
<commit_msg>Include MinSeeders value of 0<commit_after>package main

import (
	"aragnis.com/autousts/db"
	"aragnis.com/autousts/search"
	"fmt"
	"github.com/longnguyen11288/go-transmission/transmission"
	"os"
	"strconv"
	"strings"
	"time"
)

func syncShow(show *db.Show, out chan<- *search.Result, fin chan<- bool) {
	var k search.Kickass

	for {
		pointer, ok := show.NextPointer()
		if !ok {
			break
		}

		query := fmt.Sprintf(show.Query, pointer)

		results, err := k.Search(query, search.Options{})
		if err != nil {
			fmt.Printf("Search error: " + err.Error())
			break
		}

		var chosen *search.Result

		for _, result := range results {
			if show.SeedersMin > 0 && result.Seeders < show.SeedersMin {
				continue
			}

			rptr, err := db.PointerFromString(result.Name)
			if err != nil || rptr.String() != pointer.String() {
				continue
			}

			chosen = result
			break
		}

		if chosen == nil {
			break
		}

		out <- chosen
		show.Pointer = pointer
	}

	fin <- true
}

func sync(dbh *db.Database) {
	tc := transmission.New("http://127.0.0.1:9091", "", "")
	if _, err := tc.GetTorrents(); err != nil {
		fmt.Println("Could not connect to Transmission RPC API: " + err.Error())
		return
	}

	var results []*search.Result

	waiting := 0
	fin := make(chan bool)
	rec := make(chan *search.Result)

	for _, show := range dbh.Shows {
		waiting += 1
		go syncShow(show, rec, fin)
	}

	for waiting > 0 {
		select {
		case result := <-rec:
			results = append(results, result)

		case <-fin:
			waiting -= 1
		}
	}

	for _, result := range results {
		fmt.Printf("Found torrent: '%s'\n", result.Name)

		if _, err := tc.AddTorrentByFilename(result.MagnetURL, ""); err != nil {
			fmt.Println("Error adding torrent: " + err.Error())
			fmt.Println("Stopping...")
			return
		}
	}

	fmt.Printf("Found %d torrent(s)\n", len(results))

	if err := dbh.Sync(); err != nil {
		fmt.Println("Error syncing database: " + err.Error())
	}
}

func viewAll(dbh *db.Database) {
	for _, show := range dbh.Shows {
		name := show.Name
		if len(name) > 15 {
			name = name[:15] + "..."
		}

		fmt.Printf("%-20s %s\n", name, show.Pointer)
	}
}

func view(dbh *db.Database, name string) {
	show, ok := dbh.FindShow(name)
	if !ok {
		fmt.Printf("The specified show '%s' not found.\n", name)
		return
	}

	fmt.Printf("Name        : %s\n", show.Name)
	fmt.Printf("Query       : %s\n", show.Query)
	fmt.Printf("Min seeders : %d\n", show.SeedersMin)
	fmt.Printf("Prefer HQ   : %t\n", show.PreferHQ)
	fmt.Printf("Pointer     : %s\n", show.Pointer)

	if len(show.Seasons) > 0 {
		fmt.Println("")
		fmt.Println("Season  Episodes  Begin")

		for _, season := range show.Seasons {
			fmt.Printf("%-7d %-9d %s\n", season.Number, season.EpisodeCount, season.Begin)
		}
	}
}

func set(dbh *db.Database, args []string) {
	if len(args) != 3 {
		fmt.Println(`Usage:
  set SHOW PROP VALUE
  set SHOW:SEASON PROP VALUE

Show properties:
  query       : string, search query, must contain '%s' for pointer
  min-seeders : uint, minimum number of seeders allowed
  prefer-hq   : boolean
  pointer     : last downloaded episode

Season properties:
  epc   : uint, episode count
  begin : date, begin date`)
		return
	}

	split := strings.Split(args[0], ":")
	key := args[1]
	value := args[2]

	var (
		ok bool

		name   string = split[0]
		number uint

		show   *db.Show
		season *db.Season
	)

	if len(split) == 2 {
		v, err := strconv.Atoi(split[1])
		if err != nil || v <= 0 {
			fmt.Println("Invalid season specified")
			return
		}
		number = uint(v)
	}

	show, ok = dbh.FindShow(name)
	if !ok {
		show = &db.Show{
			Name: name,
		}
		dbh.Shows = append(dbh.Shows, show)
	}

	if number != 0 {
		season, ok = show.FindSeason(number)
		if !ok {
			season = &db.Season{
				Number: number,
			}
			show.Seasons = append(show.Seasons, season)
		}
	}

	if season != nil {
		switch key {
		case "epc":
			epc, err := strconv.Atoi(value)
			if err != nil || epc < 0 {
				fmt.Println("Invalid value")
				break
			}
			season.EpisodeCount = uint(epc)

		case "begin":
			begin, err := time.Parse("2006-01-02", value)
			if err != nil {
				fmt.Println("Invalid value: " + err.Error())
				break
			}
			season.Begin = begin

		default:
			fmt.Println("Invalid key")
		}
	} else {
		switch key {
		case "query":
			if strings.Count(value, "%s") != 1 {
				fmt.Println("The value must contain exactly one '%s'")
				break
			}
			show.Query = value

		case "seeders-min":
			v, err := strconv.Atoi(value)
			if err != nil || v < 0 {
				fmt.Println("Invalid value")
				break
			}
			show.SeedersMin = uint(v)

		case "prefer-hq":
			switch value {
			case "true":
				show.PreferHQ = true
			case "false":
				show.PreferHQ = false
			default:
				fmt.Println("Invalid value. Allowed values are: true, false")
			}

		case "pointer":
			pointer, err := db.PointerFromString(value)
			if err != nil {
				fmt.Println("Invalid value")
				break
			}
			show.Pointer = pointer

		default:
			fmt.Println("Invalid key")
		}
	}

	if err := dbh.Sync(); err != nil {
		fmt.Println("Error syncing database: " + err.Error())
	}
}

func main() {
	dbh, err := db.NewDatabase(fmt.Sprintf("%s/.config/goautousts.zip", os.Getenv("HOME")))
	if err != nil {
		fmt.Println("Could not open the database", err)
		return
	}

	var (
		verb     string
		verbArgs []string
	)

	if len(os.Args) >= 2 {
		verb = os.Args[1]
		verbArgs = os.Args[2:]
	}

	switch verb {
	case "sync":
		sync(dbh)
	case "view":
		if len(verbArgs) == 1 {
			view(dbh, verbArgs[0])
		} else {
			viewAll(dbh)
		}
	case "set":
		set(dbh, verbArgs)
	default:
		fmt.Println("No verb specified: {sync, view, set}")
	}

	dbh.Close()
}
<|endoftext|>


<commit_before>/*
Command git-hound is a Git plugin that helps prevent sensitive data from being committed
into a repository by sniffing potential commits against regular expressions
*/
package main

import (
	"flag"
	"fmt"
	"github.com/ezekg/git-hound/Godeps/_workspace/src/github.com/fatih/color"
	"github.com/ezekg/git-hound/Godeps/_workspace/src/sourcegraph.com/sourcegraph/go-diff/diff"
	"os"
)

var (
	noColor = flag.Bool("no-color", false, "Disable color output")
	config  = flag.String("config", ".githound.yml", "Hound config file")
	bin     = flag.String("bin", "git", "Executable binary to use for git command")
)

func main() {
	flag.Parse()

	if *noColor {
		color.NoColor = true
	}

	hound := &Hound{Config: *config}
	git := &Command{Bin: *bin}

	if ok := hound.New(); ok {
		out, _ := git.Exec("diff", "-U0", "--staged")
		fileDiffs, err := diff.ParseMultiFileDiff([]byte(out))
		if err != nil {
			fmt.Print(err)
			os.Exit(1)
		}

		hunkCount := 0
		errCount := 0

		warnc := make(chan string)
		failc := make(chan error)
		donec := make(chan bool)

		for _, fileDiff := range fileDiffs {
			fileName := fileDiff.NewName
			hunks := fileDiff.GetHunks()

			for _, hunk := range hunks {
				go hound.Sniff(fileName, hunk, warnc, failc, donec)
				hunkCount++
			}
		}

		for c := 0; c < hunkCount; {
			select {
			case msg := <-warnc:
				fmt.Print(msg)
			case err := <-failc:
				fmt.Print(err)
				errCount++
			case <-donec:
				c++
			}
		}

		if errCount > 0 {
			fmt.Printf("%d failures detected. Please fix them before you can commit.\n", errCount)
			os.Exit(1)
		}
	}

	out, code := git.Exec(flag.Args()...)
	fmt.Print(out)
	os.Exit(code)
}
<commit_msg>style fix<commit_after>/*
Command git-hound is a Git plugin that helps prevent sensitive data from being committed
into a repository by sniffing potential commits against regular expressions
*/
package main

import (
	"flag"
	"fmt"
	"github.com/ezekg/git-hound/Godeps/_workspace/src/github.com/fatih/color"
	"github.com/ezekg/git-hound/Godeps/_workspace/src/sourcegraph.com/sourcegraph/go-diff/diff"
	"os"
)

var (
	noColor = flag.Bool("no-color", false, "Disable color output")
	config  = flag.String("config", ".githound.yml", "Hound config file")
	bin     = flag.String("bin", "git", "Executable binary to use for git command")
)

func main() {
	flag.Parse()

	if *noColor {
		color.NoColor = true
	}

	hound := &Hound{Config: *config}
	git := &Command{Bin: *bin}

	if ok := hound.New(); ok {
		out, _ := git.Exec("diff", "-U0", "--staged")
		fileDiffs, err := diff.ParseMultiFileDiff([]byte(out))
		if err != nil {
			fmt.Print(err)
			os.Exit(1)
		}

		hunkCount := 0
		failCount := 0

		warnc := make(chan string)
		failc := make(chan error)
		donec := make(chan bool)

		for _, fileDiff := range fileDiffs {
			fileName := fileDiff.NewName
			hunks := fileDiff.GetHunks()

			for _, hunk := range hunks {
				go hound.Sniff(fileName, hunk, warnc, failc, donec)
				hunkCount++
			}
		}

		for c := 0; c < hunkCount; {
			select {
			case msg := <-warnc:
				fmt.Print(msg)
			case err := <-failc:
				fmt.Print(err)
				failCount++
			case <-donec:
				c++
			}
		}

		if failCount > 0 {
			fmt.Printf("%d failures detected. Please fix them before you can commit.\n", failCount)
			os.Exit(1)
		}
	}

	out, code := git.Exec(flag.Args()...)
	fmt.Print(out)
	os.Exit(code)
}
<|endoftext|>