<commit_before>/*
 * Copyright 2011 Nan Deng
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package main

import (
	"flag"
	"fmt"
	"github.com/VividCortex/godaemon"
	. "github.com/uniqush/uniqush-push/srv"
	"os"
	"runtime"
)

var uniqushPushConfFlags = flag.String("config", "/etc/uniqush/uniqush-push.conf", "Config file path")
var uniqushPushShowVersionFlag = flag.Bool("version", false, "Version info")
var uniqushPushGoDaemon = flag.Bool("d", false, "daemon")

var uniqushPushVersion = "uniqush-push 1.5.0"

func installPushSrvices() {
	InstallGCM()
	InstallC2DM()
	InstallAPNS()
	InstallADM()
}

func main() {
	flag.Parse()
	if *uniqushPushShowVersionFlag {
		fmt.Printf("%v\n", uniqushPushVersion)
		return
	}
	if *uniqushPushGoDaemon {
		godaemon.Daemonize(true)
	}
	runtime.GOMAXPROCS(runtime.NumCPU() + 1)
	installPushSrvices()

	err := Run(*uniqushPushConfFlags, uniqushPushVersion)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Cannot start: %v\n", err)
	}
}
<commit_msg>no daemon support.<commit_after>/*
 * Copyright 2011 Nan Deng
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package main

import (
	"flag"
	"fmt"
	. "github.com/uniqush/uniqush-push/srv"
	"os"
	"runtime"
)

var uniqushPushConfFlags = flag.String("config", "/etc/uniqush/uniqush-push.conf", "Config file path")
var uniqushPushShowVersionFlag = flag.Bool("version", false, "Version info")

var uniqushPushVersion = "uniqush-push 1.5.0"

func installPushSrvices() {
	InstallGCM()
	InstallC2DM()
	InstallAPNS()
	InstallADM()
}

func main() {
	flag.Parse()
	if *uniqushPushShowVersionFlag {
		fmt.Printf("%v\n", uniqushPushVersion)
		return
	}
	runtime.GOMAXPROCS(runtime.NumCPU() + 1)
	installPushSrvices()

	err := Run(*uniqushPushConfFlags, uniqushPushVersion)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Cannot start: %v\n", err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"log"
	"net/http"
	"net/http/httptrace"
	"os"
	"time"

	_ "net/http/pprof"
)

var (
	transport = &http.Transport{DisableKeepAlives: true}
	client    = &http.Client{
		Transport: transport,
		Timeout:   time.Duration(10) * time.Second,
	}

	// CLI flags
	help     bool
	interval int64
	count    int64
)

const (
	usage = `
go-latency [-help] [-i interval] [-c count] url

go-latency will make a GET request to a URL and report on the timings.

`

	helpUsage   = "Display this help message"
	helpDefault = false

	intervalUsage   = "positive number of seconds to wait between making requests"
	intervalDefault = 2

	countUsage   = "positive number of requests to make. If set, then interval is assumed to be set"
	countDefault = -1
)

func main() {
	// parse flags
	debug := flag.Bool("debug", false, "If true, you can debug this process at http://localhost:6060/debug/pprof/")

	flag.BoolVar(&help, "help", helpDefault, helpUsage)
	flag.BoolVar(&help, "h", helpDefault, helpUsage)

	flag.Int64Var(&interval, "interval", intervalDefault, intervalUsage)
	flag.Int64Var(&interval, "i", intervalDefault, intervalUsage)

	flag.Int64Var(&count, "count", countDefault, countUsage)
	flag.Int64Var(&count, "c", countDefault, countUsage)

	flag.Parse()

	if *debug {
		go func() {
			log.Println(http.ListenAndServe("localhost:6060", nil))
		}()
	}

	if help {
		showUsage()
		os.Exit(2)
	}

	// Enforce sensible defaults
	if count < 0 {
		count = countDefault
	}
	if interval < 0 {
		interval = intervalDefault
	}

	URL := flag.Arg(0)

	if URL == "" {
		showUsage()
		os.Exit(2)
	}

	poll(URL)
}

func showUsage() {
	fmt.Fprintf(os.Stderr, usage)
	flag.PrintDefaults()
}

type JSONTimestamp time.Time

func (j *JSONTimestamp) MarshalJSON() ([]byte, error) {
	stamp := fmt.Sprintf("\"%s\"", time.Time(*j).UTC().Format(time.RFC3339Nano))
	return []byte(stamp), nil
}

type TimingContext struct {
	StartTime            JSONTimestamp `json:"timestamp"`
	URL                  string        `json:"url"`
	GetConn              float64       `json:"getConn"`
	GotConn              float64       `json:"gotConn"`
	GotFirstResponseByte float64       `json:"ttfb"`
	DNSStart             float64       `json:"dnsStart"`
	DNSDone              float64       `json:"dnsDone"`
	ConnectStart         float64       `json:"connectStart"`
	ConnectDone          float64       `json:"connectDone"`
	WroteRequest         float64       `json:"wroteRequest"`
	Total                float64       `json:"total"`
}

func New(URL string) *TimingContext {
	t := TimingContext{}
	t.StartTime = JSONTimestamp(time.Now())
	t.URL = URL
	return &t
}

func (tc *TimingContext) Elapsed() float64 {
	return time.Since(time.Time(tc.StartTime)).Seconds()
}

func poll(URL string) {
	encoder := json.NewEncoder(os.Stdout)

	tickInterval := time.Duration(interval) * time.Second

	// channel used to do the initial poll
	start := make(chan struct{})

	// channel used to signal that we've done the required count of polls
	done := make(chan struct{})

	t := time.NewTicker(tickInterval)

	if count != countDefault {
		// stop the timer after count * interval seconds
		go func() {
			<-time.After(time.Duration(count-1) * tickInterval)
			close(done)
		}()
	}

	// This one weird trick to do the initial poll
	go func() {
		start <- struct{}{}
	}()

	for {
		select {
		case <-start:
			doPoll(URL, encoder)
		case <-done:
			t.Stop()
			return
		case <-t.C:
			doPoll(URL, encoder)
		}
	}
}

func doPoll(URL string, encoder *json.Encoder) {
	tc, err := doIt(URL)

	if err != nil {
		loge(err)
	}

	if err := encoder.Encode(tc); err != nil {
		loge(err)
	}
}

func doIt(URL string) (*TimingContext, error) {
	req, err := http.NewRequest("GET", URL, nil)

	if err != nil {
		return nil, err
	}

	timingContext := New(URL)

	req = req.WithContext(httptrace.WithClientTrace(req.Context(), &httptrace.ClientTrace{
		GetConn:              func(hostPort string) { timingContext.GetConn = timingContext.Elapsed() },
		GotConn:              func(ci httptrace.GotConnInfo) { timingContext.GotConn = timingContext.Elapsed() },
		GotFirstResponseByte: func() { timingContext.GotFirstResponseByte = timingContext.Elapsed() },
		DNSStart:             func(e httptrace.DNSStartInfo) { timingContext.DNSStart = timingContext.Elapsed() },
		DNSDone:              func(e httptrace.DNSDoneInfo) { timingContext.DNSDone = timingContext.Elapsed() },
		ConnectStart:         func(network, addr string) { timingContext.ConnectStart = timingContext.Elapsed() },
		ConnectDone:          func(network, addr string, err error) { timingContext.ConnectDone = timingContext.Elapsed() },
		WroteRequest:         func(e httptrace.WroteRequestInfo) { timingContext.WroteRequest = timingContext.Elapsed() },
	}))

	res, err := client.Do(req)

	timingContext.Total = timingContext.Elapsed()

	if err != nil {
		return nil, err
	}

	res.Body.Close()

	return timingContext, nil
}

func loge(err error) {
	fmt.Fprintln(os.Stderr, err.Error())
}
<commit_msg>Use github.com/ogier/pflag for CLI options<commit_after>package main

import (
	"encoding/json"
	flag "github.com/ogier/pflag"
	"fmt"
	"log"
	"net/http"
	"net/http/httptrace"
	"os"
	"time"

	_ "net/http/pprof"
)

var (
	transport = &http.Transport{DisableKeepAlives: true}
	client    = &http.Client{
		Transport: transport,
		Timeout:   time.Duration(10) * time.Second,
	}

	// CLI flags
	help     bool
	interval int64
	count    int64
)

const (
	usage = `
go-latency [options...] url

go-latency will make a GET request to a URL and report on the timings.

`

	helpUsage   = "Display this help message"
	helpDefault = false

	intervalUsage   = "positive number of seconds to wait between making requests"
	intervalDefault = 2

	countUsage   = "positive number of requests to make. If set, then interval is assumed to be set"
	countDefault = -1
)

func main() {
	// parse flags
	debug := flag.Bool("debug", false, "If true, you can debug this process at http://localhost:6060/debug/pprof/")

	flag.BoolVarP(&help, "help", "h", helpDefault, helpUsage)

	flag.Int64VarP(&interval, "interval", "i",  intervalDefault, intervalUsage)

	flag.Int64VarP(&count, "count", "c", countDefault, countUsage)

	flag.Parse()

	if *debug {
		go func() {
			log.Println(http.ListenAndServe("localhost:6060", nil))
		}()
	}

	if help {
		showUsage()
		os.Exit(2)
	}

	// Enforce sensible defaults
	if count < 0 {
		count = countDefault
	}
	if interval < 0 {
		interval = intervalDefault
	}

	URL := flag.Arg(0)

	if URL == "" {
		showUsage()
		os.Exit(2)
	}

	poll(URL)
}

func showUsage() {
	fmt.Fprintf(os.Stderr, usage)
	flag.PrintDefaults()
}

type JSONTimestamp time.Time

func (j *JSONTimestamp) MarshalJSON() ([]byte, error) {
	stamp := fmt.Sprintf("\"%s\"", time.Time(*j).UTC().Format(time.RFC3339Nano))
	return []byte(stamp), nil
}

type TimingContext struct {
	StartTime            JSONTimestamp `json:"timestamp"`
	URL                  string        `json:"url"`
	GetConn              float64       `json:"getConn"`
	GotConn              float64       `json:"gotConn"`
	GotFirstResponseByte float64       `json:"ttfb"`
	DNSStart             float64       `json:"dnsStart"`
	DNSDone              float64       `json:"dnsDone"`
	ConnectStart         float64       `json:"connectStart"`
	ConnectDone          float64       `json:"connectDone"`
	WroteRequest         float64       `json:"wroteRequest"`
	Total                float64       `json:"total"`
}

func New(URL string) *TimingContext {
	t := TimingContext{}
	t.StartTime = JSONTimestamp(time.Now())
	t.URL = URL
	return &t
}

func (tc *TimingContext) Elapsed() float64 {
	return time.Since(time.Time(tc.StartTime)).Seconds()
}

func poll(URL string) {
	encoder := json.NewEncoder(os.Stdout)

	tickInterval := time.Duration(interval) * time.Second

	// channel used to do the initial poll
	start := make(chan struct{})

	// channel used to signal that we've done the required count of polls
	done := make(chan struct{})

	t := time.NewTicker(tickInterval)

	if count != countDefault {
		// stop the timer after count * interval seconds
		go func() {
			<-time.After(time.Duration(count-1) * tickInterval)
			close(done)
		}()
	}

	// This one weird trick to do the initial poll
	go func() {
		start <- struct{}{}
	}()

	for {
		select {
		case <-start:
			doPoll(URL, encoder)
		case <-done:
			t.Stop()
			return
		case <-t.C:
			doPoll(URL, encoder)
		}
	}
}

func doPoll(URL string, encoder *json.Encoder) {
	tc, err := doIt(URL)

	if err != nil {
		loge(err)
	}

	if err := encoder.Encode(tc); err != nil {
		loge(err)
	}
}

func doIt(URL string) (*TimingContext, error) {
	req, err := http.NewRequest("GET", URL, nil)

	if err != nil {
		return nil, err
	}

	timingContext := New(URL)

	req = req.WithContext(httptrace.WithClientTrace(req.Context(), &httptrace.ClientTrace{
		GetConn:              func(hostPort string) { timingContext.GetConn = timingContext.Elapsed() },
		GotConn:              func(ci httptrace.GotConnInfo) { timingContext.GotConn = timingContext.Elapsed() },
		GotFirstResponseByte: func() { timingContext.GotFirstResponseByte = timingContext.Elapsed() },
		DNSStart:             func(e httptrace.DNSStartInfo) { timingContext.DNSStart = timingContext.Elapsed() },
		DNSDone:              func(e httptrace.DNSDoneInfo) { timingContext.DNSDone = timingContext.Elapsed() },
		ConnectStart:         func(network, addr string) { timingContext.ConnectStart = timingContext.Elapsed() },
		ConnectDone:          func(network, addr string, err error) { timingContext.ConnectDone = timingContext.Elapsed() },
		WroteRequest:         func(e httptrace.WroteRequestInfo) { timingContext.WroteRequest = timingContext.Elapsed() },
	}))

	res, err := client.Do(req)

	timingContext.Total = timingContext.Elapsed()

	if err != nil {
		return nil, err
	}

	res.Body.Close()

	return timingContext, nil
}

func loge(err error) {
	fmt.Fprintln(os.Stderr, err.Error())
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"errors"
	"flag"
	"fmt"
	"log"
	"os"
	"os/user"
	"path/filepath"
	"strings"

	"github.com/alyu/configparser"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/iam"
	"github.com/aws/aws-sdk-go/service/sts"
)

func main() {

	sourceProfile := flag.String("i", "default", "Source Profile")
	targetProfile := flag.String("t", "default", "Destination Profile")
	rotateKeys := flag.Bool("rotate-identity-keys", false, "Boolean flag to rotate keys")
	overwrite := flag.Bool("o", false, "Boolean flag to overwrite profile")
	credFile := flag.String("c", filepath.Join(getCredentialPath(), ".aws", "credentials"), "Full path to credentials file")
	duration := flag.Int64("d", 28800, "Token Duration")
	flag.Parse()

	if sourceProfile == targetProfile && !*overwrite {
		fmt.Println("Source equals target and will overwrite it you probably don't want to do this")
		return
	}
	//Get Current Credentials
	exists, err := checkProfileExists(credFile, sourceProfile)
	if err != nil || !exists {
		fmt.Println(err.Error())
		return
	}
	sess := CreateSession(sourceProfile)
	user, err := getUserMFA(sess)
	if err != nil {
		fmt.Println(err.Error())
		return
	}

	//Get MFA Code
	mfa, err := getMFACode()
	if err != nil {
		fmt.Println(err.Error())
		return
	}

	tempCreds := getSTSCredentials(sess, mfa, duration, user)
	if tempCreds != nil {
		writeNewProfile(credFile, targetProfile, sourceProfile, tempCreds)
	}
	if *rotateKeys {
		newKeys, err := rotateCredentialKeys(sess)
		if err != nil {
			fmt.Println(err.Error())
			return
		}
		writeNewKeys(credFile, sourceProfile, newKeys)
	}
}

func getMFACode() (string, error) {
	var mfa string
	fmt.Print("Enter MFA Token: ")
	reader := bufio.NewReader(os.Stdin)
	mfa, err := reader.ReadString('\n')
	if err != nil {
		return mfa, errors.New("failed to get token")
	}
	return strings.TrimSpace(mfa), nil
}

//CreateSession Creates AWS Session with specified profile
func CreateSession(profileName *string) *session.Session {
	profileNameValue := *profileName
	sess := session.Must(session.NewSessionWithOptions(session.Options{
		Profile: profileNameValue,
	}))
	return sess
}

func getUserMFA(sess *session.Session) (*string, error) {
	var newToken *string

	svc := iam.New(sess)

	params := &iam.GetUserInput{}
	resp, err := svc.GetUser(params)

	if err != nil {
		// Print the error, cast err to awserr.Error to get the Code and
		// Message from an error.
		fmt.Println(err.Error())
		return newToken, errors.New("failed to Fetch User")
	}
	userName := *resp.User.UserName
	mfaparams := &iam.ListMFADevicesInput{
		MaxItems: aws.Int64(1),
		UserName: aws.String(userName),
	}
	mfaresp, err := svc.ListMFADevices(mfaparams)

	if err != nil {
		// Print the error, cast err to awserr.Error to get the Code and
		// Message from an error.
		fmt.Println(err.Error())
		return newToken, errors.New("failed to Fetch User")
	}

	if len(mfaresp.MFADevices) == 0 {
		return nil, errors.New("unable to find a MFA device for this identity")
	}

	return mfaresp.MFADevices[0].SerialNumber, nil
}

func getCredentialPath() string {
	usr, err := user.Current()
	if err != nil {
		log.Fatal(err)
	}
	return usr.HomeDir
}

func writeNewProfile(credFile *string, profileName *string, sourceProfile *string, sessionDetails *sts.GetSessionTokenOutput) {
	config, err := configparser.Read(*credFile)
	sourceSection, err := config.Section(*sourceProfile)
	region := sourceSection.ValueOf("region")
	section, err := config.Section(*profileName)
	if err != nil {
		section = config.NewSection(*profileName)
	}

	if region != "" {
		section.Add("region", region)
	}

	section.Add("aws_access_key_id", *sessionDetails.Credentials.AccessKeyId)
	section.Add("aws_secret_access_key", *sessionDetails.Credentials.SecretAccessKey)
	section.Add("aws_session_token", *sessionDetails.Credentials.SessionToken)
	section.Add("awsmfa_expiration", (*sessionDetails.Credentials.Expiration).String())
	err = configparser.Save(config, *credFile)
	if err != nil {
		log.Fatal(err)
	}
}

func writeNewKeys(credFile *string, profileName *string, newKeys *iam.CreateAccessKeyOutput) {
	config, err := configparser.Read(*credFile)
	sourceSection, err := config.Section(*profileName)
	region := sourceSection.ValueOf("region")
	section, err := config.Section(*profileName)
	if err != nil {
		section = config.NewSection(*profileName)
	}
	section.Add("region", region)
	section.Add("aws_access_key_id", *newKeys.AccessKey.AccessKeyId)
	section.Add("aws_secret_access_key", *newKeys.AccessKey.SecretAccessKey)
	err = configparser.Save(config, *credFile)
	if err != nil {
		log.Fatal(err)
	}
}

func checkProfileExists(credFile *string, profileName *string) (bool, error) {
	config, err := configparser.Read(*credFile)
	if err != nil {
		fmt.Println("Could not find credentials file")
		fmt.Println(err.Error())
		return false, err
	}
	section, err := config.Section(*profileName)
	if err != nil {
		fmt.Println("Could not find profile in credentials file")
		return false, nil
	}
	if !section.Exists("aws_access_key_id") {
		fmt.Println("Could not find access key in profile")
		return false, nil
	}

	return true, nil
}

func getSTSCredentials(sess *session.Session, tokenCode string, duration *int64, device *string) *sts.GetSessionTokenOutput {
	svc := sts.New(sess)
	params := &sts.GetSessionTokenInput{
		DurationSeconds: aws.Int64(*duration),
		SerialNumber:    aws.String(*device),
		TokenCode:       aws.String(tokenCode),
	}
	resp, err := svc.GetSessionToken(params)

	if err != nil {
		fmt.Println(err.Error())
		return nil
	}
	return resp
}

func rotateCredentialKeys(sess *session.Session) (*iam.CreateAccessKeyOutput, error) {
	svc := iam.New(sess)
	input := &iam.ListAccessKeysInput{}
	var currentAccessKey *iam.AccessKeyMetadata
	var createResult *iam.CreateAccessKeyOutput
	result, err := svc.ListAccessKeys(input)
	if err != nil {
		fmt.Println(err.Error())
		return nil, err
	}
	currentCreds, err := sess.Config.Credentials.Get()
	for _, accessKey := range result.AccessKeyMetadata {
		if *accessKey.AccessKeyId == currentCreds.AccessKeyID {
			currentAccessKey = accessKey
		}
	}
	if currentAccessKey != nil {
		deleteKeyInput := &iam.DeleteAccessKeyInput{
			AccessKeyId: currentAccessKey.AccessKeyId,
		}
		_, err := svc.DeleteAccessKey(deleteKeyInput)
		if err != nil {
			fmt.Println(err.Error())
			return nil, err
		}
		createKeyInput := &iam.CreateAccessKeyInput{}
		createResult, err = svc.CreateAccessKey(createKeyInput)
		if err != nil {
			fmt.Println(err.Error())
			return nil, err
		}
		fmt.Printf("Replacing %s with %s", currentCreds.AccessKeyID, *createResult.AccessKey.AccessKeyId)
		return createResult, nil
	}
	return nil, errors.New("unable to find a current access key for this Identity")
}
<commit_msg>Add ability to force key rotation via Environment variable<commit_after>package main

import (
	"bufio"
	"errors"
	"flag"
	"fmt"
	"log"
	"os"
	"os/user"
	"path/filepath"
	"strings"

	"github.com/alyu/configparser"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/iam"
	"github.com/aws/aws-sdk-go/service/sts"
)

func main() {

	sourceProfile := flag.String("i", "default", "Source Profile")
	targetProfile := flag.String("t", "default", "Destination Profile")
	rotateKeys := flag.Bool("rotate-identity-keys", false, "Boolean flag to rotate keys")
	overwrite := flag.Bool("o", false, "Boolean flag to overwrite profile")
	credFile := flag.String("c", filepath.Join(getCredentialPath(), ".aws", "credentials"), "Full path to credentials file")
	duration := flag.Int64("d", 28800, "Token Duration")
	flag.Parse()

	// If AWSMFA_ALWAYS_ROTATE is set to true, always rotate the key.
	forceRotate := strings.EqualFold(os.Getenv("AWSMFA_ALWAYS_ROTATE"), "true")

	if sourceProfile == targetProfile && !*overwrite {
		fmt.Println("Source equals target and will overwrite it you probably don't want to do this")
		return
	}

	//Get Current Credentials
	exists, err := checkProfileExists(credFile, sourceProfile)
	if err != nil || !exists {
		fmt.Println(err.Error())
		return
	}
	sess := CreateSession(sourceProfile)
	user, err := getUserMFA(sess)
	if err != nil {
		fmt.Println(err.Error())
		return
	}

	//Get MFA Code
	mfa, err := getMFACode()
	if err != nil {
		fmt.Println(err.Error())
		return
	}

	tempCreds := getSTSCredentials(sess, mfa, duration, user)
	if tempCreds != nil {
		writeNewProfile(credFile, targetProfile, sourceProfile, tempCreds)
	}

	if forceRotate || *rotateKeys {
		fmt.Print("rotateing")
		newKeys, err := rotateCredentialKeys(sess)
		if err != nil {
			fmt.Println(err.Error())
			return
		}
		writeNewKeys(credFile, sourceProfile, newKeys)
	}
}

func getMFACode() (string, error) {
	var mfa string
	fmt.Print("Enter MFA Token: ")
	reader := bufio.NewReader(os.Stdin)
	mfa, err := reader.ReadString('\n')
	if err != nil {
		return mfa, errors.New("failed to get token")
	}
	return strings.TrimSpace(mfa), nil
}

//CreateSession Creates AWS Session with specified profile
func CreateSession(profileName *string) *session.Session {
	profileNameValue := *profileName
	sess := session.Must(session.NewSessionWithOptions(session.Options{
		Profile: profileNameValue,
	}))
	return sess
}

func getUserMFA(sess *session.Session) (*string, error) {
	var newToken *string

	svc := iam.New(sess)

	params := &iam.GetUserInput{}
	resp, err := svc.GetUser(params)

	if err != nil {
		// Print the error, cast err to awserr.Error to get the Code and
		// Message from an error.
		fmt.Println(err.Error())
		return newToken, errors.New("failed to Fetch User")
	}
	userName := *resp.User.UserName
	mfaparams := &iam.ListMFADevicesInput{
		MaxItems: aws.Int64(1),
		UserName: aws.String(userName),
	}
	mfaresp, err := svc.ListMFADevices(mfaparams)

	if err != nil {
		// Print the error, cast err to awserr.Error to get the Code and
		// Message from an error.
		fmt.Println(err.Error())
		return newToken, errors.New("failed to Fetch User")
	}

	if len(mfaresp.MFADevices) == 0 {
		return nil, errors.New("unable to find a MFA device for this identity")
	}

	return mfaresp.MFADevices[0].SerialNumber, nil
}

func getCredentialPath() string {
	usr, err := user.Current()
	if err != nil {
		log.Fatal(err)
	}
	return usr.HomeDir
}

func writeNewProfile(credFile *string, profileName *string, sourceProfile *string, sessionDetails *sts.GetSessionTokenOutput) {
	config, err := configparser.Read(*credFile)
	sourceSection, err := config.Section(*sourceProfile)
	region := sourceSection.ValueOf("region")
	section, err := config.Section(*profileName)
	if err != nil {
		section = config.NewSection(*profileName)
	}

	if region != "" {
		section.Add("region", region)
	}

	section.Add("aws_access_key_id", *sessionDetails.Credentials.AccessKeyId)
	section.Add("aws_secret_access_key", *sessionDetails.Credentials.SecretAccessKey)
	section.Add("aws_session_token", *sessionDetails.Credentials.SessionToken)
	section.Add("awsmfa_expiration", (*sessionDetails.Credentials.Expiration).String())
	err = configparser.Save(config, *credFile)
	if err != nil {
		log.Fatal(err)
	}
}

func writeNewKeys(credFile *string, profileName *string, newKeys *iam.CreateAccessKeyOutput) {
	config, err := configparser.Read(*credFile)
	sourceSection, err := config.Section(*profileName)
	region := sourceSection.ValueOf("region")
	section, err := config.Section(*profileName)
	if err != nil {
		section = config.NewSection(*profileName)
	}
	section.Add("region", region)
	section.Add("aws_access_key_id", *newKeys.AccessKey.AccessKeyId)
	section.Add("aws_secret_access_key", *newKeys.AccessKey.SecretAccessKey)
	err = configparser.Save(config, *credFile)
	if err != nil {
		log.Fatal(err)
	}
}

func checkProfileExists(credFile *string, profileName *string) (bool, error) {
	config, err := configparser.Read(*credFile)
	if err != nil {
		fmt.Println("Could not find credentials file")
		fmt.Println(err.Error())
		return false, err
	}
	section, err := config.Section(*profileName)
	if err != nil {
		fmt.Println("Could not find profile in credentials file")
		return false, nil
	}
	if !section.Exists("aws_access_key_id") {
		fmt.Println("Could not find access key in profile")
		return false, nil
	}

	return true, nil
}

func getSTSCredentials(sess *session.Session, tokenCode string, duration *int64, device *string) *sts.GetSessionTokenOutput {
	svc := sts.New(sess)
	params := &sts.GetSessionTokenInput{
		DurationSeconds: aws.Int64(*duration),
		SerialNumber:    aws.String(*device),
		TokenCode:       aws.String(tokenCode),
	}
	resp, err := svc.GetSessionToken(params)

	if err != nil {
		fmt.Println(err.Error())
		return nil
	}
	return resp
}

func rotateCredentialKeys(sess *session.Session) (*iam.CreateAccessKeyOutput, error) {
	svc := iam.New(sess)
	input := &iam.ListAccessKeysInput{}
	var currentAccessKey *iam.AccessKeyMetadata
	var createResult *iam.CreateAccessKeyOutput
	result, err := svc.ListAccessKeys(input)
	if err != nil {
		fmt.Println(err.Error())
		return nil, err
	}
	currentCreds, err := sess.Config.Credentials.Get()
	for _, accessKey := range result.AccessKeyMetadata {
		if *accessKey.AccessKeyId == currentCreds.AccessKeyID {
			currentAccessKey = accessKey
		}
	}
	if currentAccessKey != nil {
		deleteKeyInput := &iam.DeleteAccessKeyInput{
			AccessKeyId: currentAccessKey.AccessKeyId,
		}
		_, err := svc.DeleteAccessKey(deleteKeyInput)
		if err != nil {
			fmt.Println(err.Error())
			return nil, err
		}
		createKeyInput := &iam.CreateAccessKeyInput{}
		createResult, err = svc.CreateAccessKey(createKeyInput)
		if err != nil {
			fmt.Println(err.Error())
			return nil, err
		}
		fmt.Printf("Replacing %s with %s", currentCreds.AccessKeyID, *createResult.AccessKey.AccessKeyId)
		return createResult, nil
	}
	return nil, errors.New("unable to find a current access key for this Identity")
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/fatih/color"
	"github.com/pkg/errors"
	"log"
	"os"
	"path"
)

var red (func(...interface{}) string) = color.New(color.FgRed).SprintFunc()
var yellow (func(...interface{}) string) = color.New(color.FgYellow).SprintFunc()
var green (func(...interface{}) string) = color.New(color.FgGreen).SprintFunc()
var blue (func(...interface{}) string) = color.New(color.FgCyan).SprintFunc()

func main() {
	pluginDir, err := findNvimPluginDir()
	if err != nil {
		log.Println(red(err))
	}
	fmt.Println(blue(pluginDir.Name()) + " targeted")
	vimDir, err := findVimPluginDir()
	if err != nil {
		log.Println(red(err))
	}
	fmt.Println(blue(vimDir.Name()) + " targeted")
}

// getDirectory returns the directory at the given path if it can be opened
// and confirmed to be a directory.
func getDirectory(directoryPath string) (*os.File, error) {
	directory, err := os.Open(directoryPath)
	if err != nil {
		return nil, errors.Wrapf(err, "Unable to open %s:", directory)
	}
	if fileInfo, err := directory.Stat(); err != nil {
		return nil, errors.Wrapf(err, "Unable to access metadata for %s:", directory)
	} else if !fileInfo.IsDir() {
		return nil, fmt.Errorf("%s is not a directory", directory)
	}
	return directory, nil
}

// findNvimPluginDir returns the directory in which neovim stores its plugins
// or the empty string if it was unable to find the directory.
func findNvimPluginDir() (*os.File, error) {
	xdgHome := os.Getenv("XDG_CONFIG_HOME")
	if len(xdgHome) < 1 {
		fmt.Println(yellow("$XDG_CONFIG_HOME undefined. Inferring default value..."))
		xdgHome = path.Join(os.Getenv("HOME"), ".config")
	}

	bundlePath := path.Join(xdgHome, "nvim", "bundle")
	return getDirectory(bundlePath)
}

// findNvimPluginDir returns the directory in which neovim stores its plugins
// or the empty string if it was unable to find the directory.
func findVimPluginDir() (*os.File, error) {
	home := os.Getenv("HOME")
	bundlePath := path.Join(home, ".vim", "bundle")
	return getDirectory(bundlePath)
}
<commit_msg>Parse command line arguments<commit_after>package main

import (
	"flag"
	"fmt"
	"github.com/fatih/color"
	"github.com/pkg/errors"
	"log"
	"os"
	"path"
)

var red (func(...interface{}) string) = color.New(color.FgRed).SprintFunc()
var yellow (func(...interface{}) string) = color.New(color.FgYellow).SprintFunc()
var green (func(...interface{}) string) = color.New(color.FgGreen).SprintFunc()
var blue (func(...interface{}) string) = color.New(color.FgCyan).SprintFunc()

func main() {
	// Parse command line arguments
	var vimVersion string
	var pluginPath string
	var pluginDirectoryFunction (func() (*os.File, error))
	flag.StringVar(&vimVersion, "vim-version", "neovim", "values are \"vim\" or \"neovim\"")
	flag.StringVar(&pluginPath, "plugin-path", "", "the path to your pathogen plugins")
	flag.Parse()

	// Handle args
	switch vimVersion {
	case "vim":
		pluginDirectoryFunction = findVimPluginDir
	case "neovim":
		pluginDirectoryFunction = findNvimPluginDir
	}
	if pluginPath != "" {
		pluginDirectoryFunction = func() (*os.File, error) {
			return getDirectory(pluginPath)
		}
	}

	// Find plugins
	pluginDir, err := pluginDirectoryFunction()
	if err != nil {
		log.Println(red(err))
	}
	fmt.Println(blue(pluginDir.Name()) + " targeted")
}

// getDirectory returns the directory at the given path if it can be opened
// and confirmed to be a directory.
func getDirectory(directoryPath string) (*os.File, error) {
	directory, err := os.Open(directoryPath)
	if err != nil {
		return nil, errors.Wrapf(err, "Unable to open %s:", directory)
	}
	if fileInfo, err := directory.Stat(); err != nil {
		return nil, errors.Wrapf(err, "Unable to access metadata for %s:", directory)
	} else if !fileInfo.IsDir() {
		return nil, fmt.Errorf("%s is not a directory", directory)
	}
	return directory, nil
}

// findNvimPluginDir returns the directory in which neovim stores its plugins
// or the empty string if it was unable to find the directory.
func findNvimPluginDir() (*os.File, error) {
	xdgHome := os.Getenv("XDG_CONFIG_HOME")
	if len(xdgHome) < 1 {
		fmt.Println(yellow("$XDG_CONFIG_HOME undefined. Inferring default value..."))
		xdgHome = path.Join(os.Getenv("HOME"), ".config")
	}

	bundlePath := path.Join(xdgHome, "nvim", "bundle")
	return getDirectory(bundlePath)
}

// findNvimPluginDir returns the directory in which neovim stores its plugins
// or the empty string if it was unable to find the directory.
func findVimPluginDir() (*os.File, error) {
	home := os.Getenv("HOME")
	bundlePath := path.Join(home, ".vim", "bundle")
	return getDirectory(bundlePath)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"math/rand"
	"sync"
	"time"
)

var wg sync.WaitGroup

type person struct {
	Name    string
	AllDone bool
}

var people []person

func main() {
	Bob := person{"Bob", false}
	Alice := person{"Alice", false}
	people = []person{Bob, Alice}

	wg.Add(2)
	go Bob.dotask("getting ready", 10, 20, false)
	go Alice.dotask("getting ready", 10, 20, false)
	wg.Wait()

	wg.Add(1)
	go setAlarm(60)

	wg.Add(2)
	go Bob.dotask("putting on shoes", 10, 20, true)
	go Alice.dotask("putting on shoes", 10, 20, true)
	fmt.Println("Exiting and locking door.")
	wg.Wait()
}

func setAlarm(delay int) {
	fmt.Println("Arming alarm.")
	fmt.Println("Alarm is counting down.")
	time.Sleep(time.Duration(delay) * time.Second)
	fmt.Println("Alarm armed.")
	for _, v := range people {
		if !v.AllDone {
			panic(fmt.Sprintf("Alarm set before %v was ready.", v.Name))
		}
	}
	defer wg.Done()
}

func (p person) dotask(task string, min int, max int, setdone bool) {
	defer wg.Done()
	s := random(min, max)
	fmt.Println(p.Name, "started", task)
	time.Sleep(time.Duration(s) * time.Second)
	fmt.Println(p.Name, "spent", s, "seconds", task)
	if setdone {
		p.AllDone = true
	}
}

func random(min, max int) int {
	rand.Seed(time.Now().Unix())
	time.Sleep(10 * time.Microsecond)
	return rand.Intn(max-min) + min
}
<commit_msg>this works the way I want it to, but it's not elegant<commit_after>package main

import (
	"fmt"
	"math/rand"
	"sync"
	"time"
)

var wg sync.WaitGroup
var wga sync.WaitGroup

type person struct {
	Name    string
	AllDone bool
}

var people []person
var mtx = &sync.Mutex{}
var alarmset bool

func main() {
	fmt.Println("Let's go for walk!")
	Bob := person{"Bob", false}
	Alice := person{"Alice", false}
	people = []person{Bob, Alice}

	wg.Add(2)
	go people[0].dotask("getting ready", 10, 20, false)
	go people[1].dotask("getting ready", 10, 20, false)
	wg.Wait()

	wga.Add(1)
	go setAlarm(60)

	wg.Add(2)
	go people[0].dotask("putting on shoes", 10, 20, true)
	go people[1].dotask("putting on shoes", 10, 20, true)
	wg.Wait()
	if alarmset {
		fmt.Println("Crap!  The alarm is already set.")
	} else {
		fmt.Println("Exiting and locking door.")
	}
	wga.Wait()
}

func setAlarm(delay int) {
	fmt.Println("Arming alarm.")
	fmt.Println("Alarm is counting down.")
	time.Sleep(time.Duration(delay) * time.Second)
	alarmset = true
	fmt.Println("Alarm armed.")
	mtx.Lock()
	for _, v := range people {
		if v.AllDone == false {
			fmt.Printf("Alarm set before %v was ready.\n", v.Name)
		}
	}
	defer func() {
		mtx.Unlock()
		wga.Done()
	}()
}

func (p *person) dotask(task string, min int, max int, setdone bool) {
	defer wg.Done()
	s := random(min, max)
	fmt.Println(p.Name, "started", task)
	time.Sleep(time.Duration(s) * time.Second)
	fmt.Println(p.Name, "spent", s, "seconds", task)
	if setdone {
		mtx.Lock()
		p.AllDone = true
		mtx.Unlock()
	}
}

func random(min, max int) int {
	rand.Seed(time.Now().Unix())
	time.Sleep(10 * time.Microsecond)
	return rand.Intn(max-min) + min
}
<|endoftext|>


<commit_before>package main

import (
	"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) {
	var user string
	log.Print(r.Method, " ", r.URL)
	for _, g := range git_handlers {
		path_match := g.regexp.FindStringSubmatch(r.URL.Path)
		if r.Method == g.method && path_match != nil {
			auth_response := do_auth_request(r)
			if auth_response.StatusCode != 200 {
				for k, v := range auth_response.Header {
					w.Header()[k] = v
				}
				w.WriteHeader(auth_response.StatusCode)
				io.Copy(w, auth_response.Body)
				return
			}
			if _, err := fmt.Fscan(auth_response.Body, user); err != nil {
				fail_500(w, err)
			}
			g.handle_func(user, g.rpc, path.Join(repo_root, path_match[1]), w, r)
			return
		}
	}
	log.Print("Reached end of dispatch for loop")
	w.WriteHeader(404)
}

func do_auth_request(r *http.Request) *http.Response {
	var err error
	url := fmt.Sprintf("http://localhost:8080%s", r.URL.RequestURI())
	auth_req, err := http.NewRequest(r.Method, url, nil)
	if err != nil {
		return &http.Response{StatusCode: 500}
	}
	for k, v := range r.Header {
		auth_req.Header[k] = v
	}
	result, err := http_client.Do(auth_req)
	if err != nil {
		return &http.Response{StatusCode: 500}
	}
	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")
}
<commit_msg>Make auth backend configurable<commit_after>package main

import (
	"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 auth_backend = flag.String("auth_backend", "http://localhost:8080", "Authentication/authorization backend")

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) {
	var user string
	log.Print(r.Method, " ", r.URL)
	for _, g := range git_handlers {
		path_match := g.regexp.FindStringSubmatch(r.URL.Path)
		if r.Method == g.method && path_match != nil {
			auth_response := do_auth_request(r)
			if auth_response.StatusCode != 200 {
				for k, v := range auth_response.Header {
					w.Header()[k] = v
				}
				w.WriteHeader(auth_response.StatusCode)
				io.Copy(w, auth_response.Body)
				return
			}
			if _, err := fmt.Fscan(auth_response.Body, user); err != nil {
				fail_500(w, err)
			}
			g.handle_func(user, g.rpc, path.Join(repo_root, path_match[1]), w, r)
			return
		}
	}
	log.Print("Reached end of dispatch for loop")
	w.WriteHeader(404)
}

func do_auth_request(r *http.Request) *http.Response {
	var err error
	url := fmt.Sprintf("%s%s", *auth_backend, r.URL.RequestURI())
	auth_req, err := http.NewRequest(r.Method, url, nil)
	if err != nil {
		return &http.Response{StatusCode: 500}
	}
	for k, v := range r.Header {
		auth_req.Header[k] = v
	}
	result, err := http_client.Do(auth_req)
	if err != nil {
		return &http.Response{StatusCode: 500}
	}
	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 (
	"encoding/xml"
	"flag"
	"fmt"
	"github.com/crackcomm/go-clitable"
	"github.com/parnurzeal/gorequest"
	"net"
	"os"
	"regexp"
	"sort"
	"strings"
	"time"
)

type RIMP struct {
	XMLName xml.Name `xml:"RIMP"`
	SBSN    string   `xml:"HSI>SBSN"`
	SPN     string   `xml:"HSI>SPN"`
	PN      string   `xml:"MP>PN"`
	FWRI    string   `xml:"MP>FWRI"`
	HWRI    string   `xml:"MP>HWRI"`
}

func (r *RIMP) GetHW() string {
	var iloRevision = regexp.MustCompile(`\((.*)\)`)
	if len(r.PN) == 0 {
		return "N/A"
	}
	return iloRevision.FindAllStringSubmatch(r.PN, 1)[0][1]
}
func (r *RIMP) GetModel() string {
	if len(r.SPN) == 0 {
		return "N/A"
	}
	return strings.TrimSpace(r.SPN)
}
func (r *RIMP) GetFW() string {
	if len(r.FWRI) == 0 {
		return "N/A"
	}
	return strings.TrimSpace(r.FWRI)
}

const (
	ILO_PORT = 17988
)

var (
	IP_NETWORK   = ""
	IP_NETPARSED []string
)

func inc(ip net.IP) {
	for j := len(ip) - 1; j >= 0; j-- {
		ip[j]++
		if ip[j] > 0 {
			break
		}
	}
}

func IsOpen(host string, port int) bool {

	tcpAddr, err := net.ResolveTCPAddr("tcp4", fmt.Sprintf("%s:%d", host, port))
	if err != nil {
		return false
	}
	conn, err := net.DialTimeout("tcp", tcpAddr.String(), 250*time.Millisecond)

	if err != nil {
		return false
	}
	defer conn.Close()
	return true
}

func init() {
	flag.StringVar(&IP_NETWORK, "net", "", "Scan network, format 10.0.0.0/24")
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
		flag.PrintDefaults()
	}
	flag.Parse()
	if len(IP_NETWORK) == 0 {
		flag.Usage()
		os.Exit(1)
	}

	ip, ipnet, err := net.ParseCIDR(IP_NETWORK)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	var ips []string
	for ip := ip.Mask(ipnet.Mask); ipnet.Contains(ip); inc(ip) {
		ips = append(ips, ip.String())
	}
	IP_NETPARSED = ips
}

func scan(in chan string, out chan string) {
	host := <-in
	for host != "" {
		if IsOpen(host, ILO_PORT) {
			out <- host
		}
		host = <-in
	}
	out <- "done"
}
func main() {

	fmt.Printf("Scaning %d hosts...\n\n", len(IP_NETPARSED))
	c := make(chan string, 50)
	in := make(chan string, 50)

	//Запуск воркеров
	for i := 0; i < 50; i++ {
		go scan(in, c)
	}

	for _, ip := range IP_NETPARSED {
		in <- ip
	}

	for i := 0; i < 50; i++ {
		in <- ""
	}

	var iloip = make([]string, 0)
	donecnt := 0
	for donecnt <= 49 {
		ip := <-c
		if ip != "done" {
			iloip = append(iloip, ip)
		} else {
			donecnt++
		}
	}

	request := gorequest.New()
	table := clitable.New([]string{"iLO IP Address", "iLO HW", "iLO FW", "Server S/N", "Server Model"})
	sort.Strings(iloip)

	for _, ipilo := range iloip {
		var info RIMP
		_, body, errs := request.Get(fmt.Sprintf("http://%s/xmldata?item=all", ipilo)).End()

		if errs != nil {
			panic(errs)
		}
		xml.Unmarshal([]byte(body), &info)
		table.AddRow(map[string]interface{}{
			"iLO IP Address": strings.TrimSpace(ipilo),
			"iLO HW":         info.GetHW(),
			"iLO FW":         info.GetFW(),
			"Server S/N":     strings.TrimSpace(info.SBSN),
			"Server Model":   info.GetModel(),
		})
	}

	table.Markdown = true
	table.Print()
	fmt.Println("")
	fmt.Printf("%d iLOs found on network target %s.\n", len(iloip), IP_NETWORK)
}
<commit_msg>Для разбора аргументов перешел на kingpin<commit_after>package main

import (
	"encoding/xml"
	"fmt"
	"github.com/crackcomm/go-clitable"
	"github.com/parnurzeal/gorequest"
	"gopkg.in/alecthomas/kingpin.v2"
	"net"
	"os"
	"regexp"
	"sort"
	"strings"
	"time"
)

type RIMP struct {
	XMLName xml.Name `xml:"RIMP"`
	SBSN    string   `xml:"HSI>SBSN"`
	SPN     string   `xml:"HSI>SPN"`
	PN      string   `xml:"MP>PN"`
	FWRI    string   `xml:"MP>FWRI"`
	HWRI    string   `xml:"MP>HWRI"`
}

func (r *RIMP) GetHW() string {
	var iloRevision = regexp.MustCompile(`\((.*)\)`)
	if len(r.PN) == 0 {
		return "N/A"
	}
	return iloRevision.FindAllStringSubmatch(r.PN, 1)[0][1]
}
func (r *RIMP) GetModel() string {
	if len(r.SPN) == 0 {
		return "N/A"
	}
	return strings.TrimSpace(r.SPN)
}
func (r *RIMP) GetFW() string {
	if len(r.FWRI) == 0 {
		return "N/A"
	}
	return strings.TrimSpace(r.FWRI)
}

const (
	ILO_PORT = 17988
)

var (
	IP_NETWORK   = kingpin.Arg("network", "Scan network, format 10.0.0.0/24").Required().String()
	IP_NETPARSED []string
)

func inc(ip net.IP) {
	for j := len(ip) - 1; j >= 0; j-- {
		ip[j]++
		if ip[j] > 0 {
			break
		}
	}
}

func IsOpen(host string, port int) bool {

	tcpAddr, err := net.ResolveTCPAddr("tcp4", fmt.Sprintf("%s:%d", host, port))
	if err != nil {
		return false
	}
	conn, err := net.DialTimeout("tcp", tcpAddr.String(), 250*time.Millisecond)

	if err != nil {
		return false
	}
	defer conn.Close()
	return true
}

func init() {
	//flag.StringVar(&IP_NETWORK, "net", "", "Scan network, format 10.0.0.0/24")
	//flag.Usage = func() {
	//fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
	//flag.PrintDefaults()
	//}
	//flag.Parse()
	kingpin.Parse()

	ip, ipnet, err := net.ParseCIDR(*IP_NETWORK)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	var ips []string
	for ip := ip.Mask(ipnet.Mask); ipnet.Contains(ip); inc(ip) {
		ips = append(ips, ip.String())
	}
	IP_NETPARSED = ips
}

func scan(in chan string, out chan string) {
	host := <-in
	for host != "" {
		if IsOpen(host, ILO_PORT) {
			out <- host
		}
		host = <-in
	}
	out <- "done"
}
func main() {

	fmt.Printf("Scaning %d hosts...\n\n", len(IP_NETPARSED))
	c := make(chan string, 50)
	in := make(chan string, 50)

	//Запуск воркеров
	for i := 0; i < 50; i++ {
		go scan(in, c)
	}

	for _, ip := range IP_NETPARSED {
		in <- ip
	}

	for i := 0; i < 50; i++ {
		in <- ""
	}

	var iloip = make([]string, 0)
	donecnt := 0
	for donecnt <= 49 {
		ip := <-c
		if ip != "done" {
			iloip = append(iloip, ip)
		} else {
			donecnt++
		}
	}

	request := gorequest.New()
	table := clitable.New([]string{"iLO IP Address", "iLO HW", "iLO FW", "Server S/N", "Server Model"})
	sort.Strings(iloip)

	for _, ipilo := range iloip {
		var info RIMP
		_, body, errs := request.Get(fmt.Sprintf("http://%s/xmldata?item=all", ipilo)).End()

		if errs != nil {
			panic(errs)
		}
		xml.Unmarshal([]byte(body), &info)
		table.AddRow(map[string]interface{}{
			"iLO IP Address": strings.TrimSpace(ipilo),
			"iLO HW":         info.GetHW(),
			"iLO FW":         info.GetFW(),
			"Server S/N":     strings.TrimSpace(info.SBSN),
			"Server Model":   info.GetModel(),
		})
	}

	table.Markdown = true
	table.Print()
	fmt.Println("")
	fmt.Printf("%d iLOs found on network target %s.\n", len(iloip), *IP_NETWORK)
}
<|endoftext|>


<commit_before>package adapter

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

	"github.com/lestrrat/go-server-starter/listener"
	"github.com/sirupsen/logrus"
)

// Version is the version of go-nginx-oauth2-adapter.
const Version = "0.2.1"

// Main starts the go-nginx-oauth2-adapter server.
func Main(args []string) int {

	flagSet := flag.NewFlagSet(args[0], flag.ContinueOnError)
	var configFile string
	var configtest bool
	var showVersion bool
	var showHelp bool
	flagSet.StringVar(&configFile, "c", "", "configuration file")
	flagSet.StringVar(&configFile, "config", "", "configuration file")
	flagSet.BoolVar(&configtest, "t", false, "test configuration and exit")
	flagSet.BoolVar(&configtest, "configtest", false, "test configuration and exit")
	flagSet.BoolVar(&showVersion, "v", false, "show version information")
	flagSet.BoolVar(&showVersion, "version", false, "show version information")
	flagSet.BoolVar(&showHelp, "h", false, "show help")
	flagSet.BoolVar(&showHelp, "help", false, "show help")
	err := flagSet.Parse(args[1:])
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"err": err.Error(),
		}).Error("error while parsing flags")
		return 2
	}

	if showVersion {
		fmt.Println("go-nginx-oauth2-adapter", Version)
		return 0
	}

	if showHelp {
		flagSet.Usage()
		return 0
	}

	c, err := parseConfig(configFile)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"err": err.Error(),
		}).Error("error while parsing configure")
		return 1
	}

	s, err := NewServer(*c)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"err": err.Error(),
		}).Error("init server error")
		return 1
	}
	if configtest {
		return 0
	}

	l, err := getListener(c)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"err": err.Error(),
		}).Error("listen error")
		return 1
	}
	server := &http.Server{
		Handler: LoggingHandler(s),
	}
	go func() {
		err := server.Serve(l)
		if err == http.ErrServerClosed {
			return
		}
		if err != nil {
			logrus.WithFields(logrus.Fields{
				"err": err.Error(),
			}).Fatal("serve error")
		}
	}()

	waitSignal()
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()
	err = server.Shutdown(ctx)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"err": err.Error(),
		}).Error("shutdown server error")
	}
	return 0
}

func parseConfig(configFile string) (*Config, error) {
	c := NewConfig()
	if err := c.LoadEnv(); err != nil {
		return nil, err
	}
	if configFile != "" {
		if err := c.LoadYaml(configFile); err != nil {
			return nil, err
		}
	}

	return c, nil
}

func waitSignal() {
	signalChan := make(chan os.Signal, 1)
	signal.Notify(signalChan, syscall.SIGTERM)
	for {
		s := <-signalChan
		if s == syscall.SIGTERM {
			logrus.Info("received SIGTERM")
			return
		}
	}
}

func getListener(c *Config) (net.Listener, error) {
	listeners, err := listener.ListenAll()
	if err != nil && err != listener.ErrNoListeningTarget {
		panic(err)
	}
	if err != listener.ErrNoListeningTarget {
		return listeners[0], nil
	}

	// Fallback if not running under Server::Starter
	return net.Listen("tcp", c.Address)
}
<commit_msg>bump version<commit_after>package adapter

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

	"github.com/lestrrat/go-server-starter/listener"
	"github.com/sirupsen/logrus"
)

// Version is the version of go-nginx-oauth2-adapter.
const Version = "0.3.0-rc1"

// Main starts the go-nginx-oauth2-adapter server.
func Main(args []string) int {

	flagSet := flag.NewFlagSet(args[0], flag.ContinueOnError)
	var configFile string
	var configtest bool
	var showVersion bool
	var showHelp bool
	flagSet.StringVar(&configFile, "c", "", "configuration file")
	flagSet.StringVar(&configFile, "config", "", "configuration file")
	flagSet.BoolVar(&configtest, "t", false, "test configuration and exit")
	flagSet.BoolVar(&configtest, "configtest", false, "test configuration and exit")
	flagSet.BoolVar(&showVersion, "v", false, "show version information")
	flagSet.BoolVar(&showVersion, "version", false, "show version information")
	flagSet.BoolVar(&showHelp, "h", false, "show help")
	flagSet.BoolVar(&showHelp, "help", false, "show help")
	err := flagSet.Parse(args[1:])
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"err": err.Error(),
		}).Error("error while parsing flags")
		return 2
	}

	if showVersion {
		fmt.Println("go-nginx-oauth2-adapter", Version)
		return 0
	}

	if showHelp {
		flagSet.Usage()
		return 0
	}

	c, err := parseConfig(configFile)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"err": err.Error(),
		}).Error("error while parsing configure")
		return 1
	}

	s, err := NewServer(*c)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"err": err.Error(),
		}).Error("init server error")
		return 1
	}
	if configtest {
		return 0
	}

	l, err := getListener(c)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"err": err.Error(),
		}).Error("listen error")
		return 1
	}
	server := &http.Server{
		Handler: LoggingHandler(s),
	}
	go func() {
		err := server.Serve(l)
		if err == http.ErrServerClosed {
			return
		}
		if err != nil {
			logrus.WithFields(logrus.Fields{
				"err": err.Error(),
			}).Fatal("serve error")
		}
	}()

	waitSignal()
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()
	err = server.Shutdown(ctx)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"err": err.Error(),
		}).Error("shutdown server error")
	}
	return 0
}

func parseConfig(configFile string) (*Config, error) {
	c := NewConfig()
	if err := c.LoadEnv(); err != nil {
		return nil, err
	}
	if configFile != "" {
		if err := c.LoadYaml(configFile); err != nil {
			return nil, err
		}
	}

	return c, nil
}

func waitSignal() {
	signalChan := make(chan os.Signal, 1)
	signal.Notify(signalChan, syscall.SIGTERM)
	for {
		s := <-signalChan
		if s == syscall.SIGTERM {
			logrus.Info("received SIGTERM")
			return
		}
	}
}

func getListener(c *Config) (net.Listener, error) {
	listeners, err := listener.ListenAll()
	if err != nil && err != listener.ErrNoListeningTarget {
		panic(err)
	}
	if err != listener.ErrNoListeningTarget {
		return listeners[0], nil
	}

	// Fallback if not running under Server::Starter
	return net.Listen("tcp", c.Address)
}
<|endoftext|>


<commit_before>package main

import (
	"Go-Redis-Admin/api/v1"
	// "fmt"
	"html/template"
	"log"
	"net/http"
	"reflect"
	"strings"
)

func init() {

}

func main() {
	http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
	http.HandleFunc("/", sayhelloName) //设置访问的路由
	http.HandleFunc("/login", login)
	http.Handle("/api/", http.HandlerFunc(mainRouter))
	err := http.ListenAndServe(":9090", nil) //设置监听的端口
	if err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}
func sayhelloName(w http.ResponseWriter, r *http.Request) {
	//	r.ParseForm()                //解析参数，默认是不会解析的
	//	fmt.Println("form:", r.Form) //这些信息是输出到服务器端的打印信息
	//	fmt.Println("path", r.URL.Path)
	//	fmt.Println("scheme", r.URL.Scheme)
	//	fmt.Println("r.Form[\"test\"]", r.Form["test"])
	//	for k, v := range r.Form {
	//		fmt.Println("key:", k)
	//		fmt.Println("val:", strings.Join(v, ""))
	//	}
	log.Println("/")
	t, _ := template.ParseFiles("views/index.html")
	t.Execute(w, nil)
	//w.Write([]byte("Hello, I'm coming..."))
	//fmt.Fprintf(w, "Hello, I'm coming...") //这个写入到w的是输出到客户端的
}

func login(w http.ResponseWriter, r *http.Request) {
	log.Println("/login")
	t, _ := template.ParseFiles("views/login.html")
	t.Execute(w, nil)
	//w.Write([]byte("login"))
}

// main router
func mainRouter(w http.ResponseWriter, r *http.Request) {
	pathinfo := strings.Trim(r.URL.Path, "/")
	log.Println(pathinfo)
	// if /
	if strings.Contains(pathinfo, "/") {
		patterns := strings.Split(pathinfo, "/")
		//fmt.Println(reflect.TypeOf(patterns))
		log.Println("patterns:", patterns)
		switch patterns[0] {
		case "api":
			apiRouter(w, r, patterns)
		case "tpl":
			tplRouter(w, r, patterns)
		case "res":
			resRouter(w, r, patterns)
		default:
		}
	} else {
		// default router
	}
}

// API router
func apiRouter(w http.ResponseWriter, r *http.Request, patterns []string) {
	handle := &v1.Handlers{}
	controller := reflect.ValueOf(handle)
	version := patterns[1]
	action := version + "." + strings.ToUpper(patterns[2]) + "Action"
	log.Println("action:", action)
	method := controller.MethodByName(action)
	wr := reflect.ValueOf(w)
	rr := reflect.ValueOf(r)
	method.Call([]reflect.Value{wr, rr})
}

// template router
func tplRouter(w http.ResponseWriter, r *http.Request, patterns []string) {

}

// resource router
func resRouter(w http.ResponseWriter, r *http.Request, patterns []string) {

}
<commit_msg>modify router<commit_after>package main

import (
	"Go-Redis-Admin/api/v1"
	// "fmt"
	"html/template"
	"log"
	"net/http"
	"reflect"
	"strings"
)

func init() {

}

func main() {
	http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
	http.HandleFunc("/", sayhelloName) //设置访问的路由
	http.HandleFunc("/login", login)
	http.Handle("/api/", http.HandlerFunc(mainRouter))
	err := http.ListenAndServe(":9090", nil) //设置监听的端口
	if err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}
func sayhelloName(w http.ResponseWriter, r *http.Request) {
	//	r.ParseForm()                //解析参数，默认是不会解析的
	//	fmt.Println("form:", r.Form) //这些信息是输出到服务器端的打印信息
	//	fmt.Println("path", r.URL.Path)
	//	fmt.Println("scheme", r.URL.Scheme)
	//	fmt.Println("r.Form[\"test\"]", r.Form["test"])
	//	for k, v := range r.Form {
	//		fmt.Println("key:", k)
	//		fmt.Println("val:", strings.Join(v, ""))
	//	}
	log.Println("/")
	t, _ := template.ParseFiles("views/index.html")
	t.Execute(w, nil)
	//w.Write([]byte("Hello, I'm coming..."))
	//fmt.Fprintf(w, "Hello, I'm coming...") //这个写入到w的是输出到客户端的
}

func login(w http.ResponseWriter, r *http.Request) {
	log.Println("/login")
	t, _ := template.ParseFiles("views/login.html")
	t.Execute(w, nil)
	//w.Write([]byte("login"))
}

// main router
func mainRouter(w http.ResponseWriter, r *http.Request) {
	pathinfo := strings.Trim(r.URL.Path, "/")
	log.Println(pathinfo)
	// if /
	if strings.Contains(pathinfo, "/") {
		patterns := strings.Split(pathinfo, "/")
		//fmt.Println(reflect.TypeOf(patterns))
		log.Println("patterns:", patterns)
		switch patterns[0] {
		case "api":
			apiRouter(w, r, patterns)
		case "tpl":
			tplRouter(w, r, patterns)
		case "res":
			resRouter(w, r, patterns)
		default:
		}
	} else {
		// default router
	}
}

// API router
func apiRouter(w http.ResponseWriter, r *http.Request, patterns []string) {
	handle := &v1.Handlers{}
	controller := reflect.ValueOf(handle)
	version := patterns[1]
	action := version + "." + strings.Title(patterns[2]) + "Action"
	log.Println("action:", action)
	method := controller.MethodByName(action)
	wr := reflect.ValueOf(w)
	rr := reflect.ValueOf(r)
	method.Call([]reflect.Value{wr, rr})
}

// template router
func tplRouter(w http.ResponseWriter, r *http.Request, patterns []string) {

}

// resource router
func resRouter(w http.ResponseWriter, r *http.Request, patterns []string) {

}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"flag"
	"os"
	"time"
	"sync"

	"github.com/jroimartin/gocui"
	"github.com/norwack/tinder"
)

type Message struct {
	ID string
	MatchID string
	Timestamp int64
	To string
	From string
	Message string
	Sent string
}

type Person struct {
	ID string
	Bio string
	Birth string
	Gender int
	Name string
	PingTime string
}

type Match struct {
	ID string
	CommonFriendCount int
	CommonLikeCount int
	MessageCount int
	Messages []*Message
	Person *Person
}

type TinderProfile struct {
	Matches []*Match
}

var (
	facebookUserID, facebookToken string
	tinderClient *tinder.Tinder
	profile TinderProfile
	profileMut sync.Mutex

	// gui
	g *gocui.Gui
	backgroundView *gocui.View
	profilePictureView *gocui.View
	swipeLeftView *gocui.View
	swipeRightView *gocui.View
	infoView *gocui.View
)

func layout(g *gocui.Gui) error {
	var err error
	maxX, maxY := g.Size()
	if backgroundView, err = g.SetView("background", 0, 0, maxX, maxY); err != nil {
		if err != gocui.ErrorUnkView {
			return err
		}
	}
    if profilePictureView, err = g.SetView("profilePicture", 1, 1, maxX-1, maxY-5); err != nil {
        if err != gocui.ErrorUnkView {
            return err
        }
		fmt.Fprintln(profilePictureView, "Loading...")
    }
	if swipeLeftView, err = g.SetView("swipeLeft", 6, maxY-4, maxX/2-5, maxY-1); err != nil {
		if err != gocui.ErrorUnkView {
			return err
		}
		fmt.Fprintln(swipeLeftView, "X")
	}
	if swipeRightView, err = g.SetView("swipeRight", maxX-(maxX/2-5), maxY-4, maxX-6, maxY-1); err != nil {
		if err != gocui.ErrorUnkView {
			return err
		}
		fmt.Fprintln(swipeRightView, "<3")
	}
	if infoView, err = g.SetView("info", maxX/2-4, maxY-4, maxX/2+4, maxY-1); err != nil {
		if err != gocui.ErrorUnkView {
			return err
		}
		fmt.Fprintln(infoView, "i")
	}
    return nil
}

func quit(g *gocui.Gui, v *gocui.View) error {
	return gocui.Quit
}

func runGUI() error {
	g = gocui.NewGui()
	if err := g.Init(); err != nil {
		return err
	}
	defer g.Close()
	g.SetLayout(layout)
	if err := g.SetKeybinding(
		"", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil {
		return err
	}
	g.SelBgColor = gocui.ColorGreen
	g.SelFgColor = gocui.ColorBlack
	err := g.MainLoop()
	if err != nil && err != gocui.Quit {
		return err
	}
	return nil
}

func pollTinder(updateGUI chan struct{}, client *tinder.Tinder, profile *TinderProfile) {
	for _ = range time.Tick(5 * time.Second) {
		profileMut.Lock()
		resp, err := client.GetUpdates()
		if err != nil {
			fmt.Fprintln(os.Stderr, "Error polling:", err)
		}
		matches := make([]*Match, len(resp.Matches))
		for i, match := range resp.Matches {
			matches[i] = &Match{
				ID: match.ID,
				CommonFriendCount: match.CommonFriendCount,
				CommonLikeCount: match.CommonLikeCount,
				MessageCount: match.MessageCount,
				Person: &Person{
					ID: match.Person.ID,
					Bio: match.Person.Bio,
					Birth: match.Person.Birth,
					Gender: match.Person.Gender,
					Name: match.Person.Name,
					PingTime: match.Person.PingTime,
				},
			}
			messages := make([]*Message, len(match.Messages))
			for i, msg := range match.Messages {
				messages[i] = &Message{
					ID: msg.ID,
					MatchID: msg.MatchID,
					Timestamp: msg.Timestamp,
					To: msg.To,
					From: msg.From,
					Message: msg.Message,
					Sent: msg.Sent,
				}
			}
			matches[i].Messages = messages
		}
		profile.Matches = matches
		profileMut.Unlock()

		updateGUI<-struct{}{}
	}
}

func updateGUI(updateGUI chan struct{}) {
	for _ = range updateGUI {
		profilePictureView.Clear()
		fmt.Fprintln(profilePictureView, profile.Matches[0].Person.Name)
		g.Flush()
	}
}

func main() {
	flag.StringVar(&facebookUserID, "fb_user_id", "", "facebook user id")
	flag.StringVar(&facebookToken, "fb_token", "", "facebook token")
	flag.Parse()

	if flag.NArg() == flag.NFlag() {
		fmt.Fprintf(os.Stderr, "Error: all flags are required. Run with -help for options.\n")
		os.Exit(1)
	}

	tinderClient = tinder.Init(facebookUserID, facebookToken)
	if err := tinderClient.Auth(); err != nil {
		fmt.Fprintln(os.Stderr, "Could not authenticate: ", err.Error())
		os.Exit(1)
	}

	updateGUIChan := make(chan struct{})

	go pollTinder(updateGUIChan, tinderClient, &profile)
	go updateGUI(updateGUIChan)

	if err := runGUI(); err != nil {
		fmt.Fprintf(os.Stderr, err.Error())
	}
}
<commit_msg>swiping works<commit_after>package main

import (
	"fmt"
	"flag"
	"os"
	"time"
	"sync"

	"github.com/jroimartin/gocui"
	"github.com/zachlatta/tinder"
)

type Message struct {
	ID string
	MatchID string
	Timestamp int64
	To string
	From string
	Message string
	Sent string
}

type Person struct {
	ID string
	Bio string
	Birth string
	Gender int
	Name string
	PingTime string
}

type Match struct {
	ID string
	CommonFriendCount int
	CommonLikeCount int
	MessageCount int
	Messages []*Message
	Person *Person
}

type TinderProfile struct {
	Matches []*Match
	Recommendations []tinder.Recommendation
}

var (
	facebookUserID, facebookToken string
	tinderClient *tinder.Tinder
	profile TinderProfile
	profileMut sync.Mutex
	updateGUIChan chan struct{}

	// gui
	g *gocui.Gui
	backgroundView *gocui.View
	profilePictureView *gocui.View
	swipeLeftView *gocui.View
	swipeRightView *gocui.View
	infoView *gocui.View
)

func swipeLeft(g *gocui.Gui, v *gocui.View) error {
	if err := tinderClient.Pass(profile.Recommendations[0].ID); err != nil {
		fmt.Println(err)
	}
	profile.Recommendations = profile.Recommendations[1:]
	updateGUIChan<-struct{}{}
	return nil
}

func swipeRight(g *gocui.Gui, v *gocui.View) error {
	_, err := tinderClient.Like(profile.Recommendations[0].ID)
	if err != nil {
		fmt.Println(err)
	}
	profile.Recommendations = profile.Recommendations[1:]
	updateGUIChan<-struct{}{}
	return nil
}

func layout(g *gocui.Gui) error {
	var err error
	maxX, maxY := g.Size()
	if backgroundView, err = g.SetView("background", 0, 0, maxX, maxY); err != nil {
		if err != gocui.ErrorUnkView {
			return err
		}
	}
    if profilePictureView, err = g.SetView("profilePicture", 1, 1, maxX-1, maxY-5); err != nil {
        if err != gocui.ErrorUnkView {
            return err
        }
		profilePictureView.Wrap = true
		fmt.Fprintln(profilePictureView, "Loading...")
    }
	if swipeLeftView, err = g.SetView("swipeLeft", 6, maxY-4, maxX/2-5, maxY-1); err != nil {
		if err != gocui.ErrorUnkView {
			return err
		}
		fmt.Fprintln(swipeLeftView, "X")
	}
	if swipeRightView, err = g.SetView("swipeRight", maxX-(maxX/2-5), maxY-4, maxX-6, maxY-1); err != nil {
		if err != gocui.ErrorUnkView {
			return err
		}
		fmt.Fprintln(swipeRightView, "<3")
	}
	if infoView, err = g.SetView("info", maxX/2-4, maxY-4, maxX/2+4, maxY-1); err != nil {
		if err != gocui.ErrorUnkView {
			return err
		}
		fmt.Fprintln(infoView, "i")
	}
    return nil
}

func quit(g *gocui.Gui, v *gocui.View) error {
	return gocui.Quit
}

func keybindings(g *gocui.Gui) error {
	if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil {
		return err
	}
	if err := g.SetKeybinding("", 'h', gocui.ModNone, swipeLeft); err != nil {
		return err
	}
	if err := g.SetKeybinding("", 'l', gocui.ModNone, swipeRight); err != nil {
		return err
	}
	return nil
}

func runGUI() error {
	g = gocui.NewGui()
	if err := g.Init(); err != nil {
		return err
	}
	defer g.Close()
	g.SetLayout(layout)
	if err := keybindings(g); err != nil {
		return err
	}
	g.SelBgColor = gocui.ColorGreen
	g.SelFgColor = gocui.ColorBlack
	err := g.MainLoop()
	if err != nil && err != gocui.Quit {
		return err
	}
	return nil
}

func pollTinder(updateGUI chan struct{}, client *tinder.Tinder, profile *TinderProfile) {
	for _ = range time.Tick(5 * time.Second) {
		profileMut.Lock()
		resp, err := client.GetUpdates()
		if err != nil {
			fmt.Fprintln(os.Stderr, "Error polling:", err)
		}
		matches := make([]*Match, len(resp.Matches))
		for i, match := range resp.Matches {
			matches[i] = &Match{
				ID: match.ID,
				CommonFriendCount: match.CommonFriendCount,
				CommonLikeCount: match.CommonLikeCount,
				MessageCount: match.MessageCount,
				Person: &Person{
					ID: match.Person.ID,
					Bio: match.Person.Bio,
					Birth: match.Person.Birth,
					Gender: match.Person.Gender,
					Name: match.Person.Name,
					PingTime: match.Person.PingTime,
				},
			}
			messages := make([]*Message, len(match.Messages))
			for i, msg := range match.Messages {
				messages[i] = &Message{
					ID: msg.ID,
					MatchID: msg.MatchID,
					Timestamp: msg.Timestamp,
					To: msg.To,
					From: msg.From,
					Message: msg.Message,
					Sent: msg.Sent,
				}
			}
			matches[i].Messages = messages
		}
		profile.Matches = matches

		if len(profile.Recommendations) == 0 {
			recsResp, err := client.GetRecommendations()
			if err != nil {
				if err != tinder.RecsExhausted && err != tinder.RecsTimeout {
					fmt.Fprintln(os.Stderr, "Error polling:", err)
				}
			} else {
				profile.Recommendations = recsResp.Results
			}
		}

		profileMut.Unlock()

		updateGUI<-struct{}{}
	}
}

func updateGUI(updateGUI chan struct{}) {
	for _ = range updateGUI {
		profilePictureView.Clear()
		if len(profile.Recommendations) > 0 {
			topRec := profile.Recommendations[0]
			fmt.Fprintf(profilePictureView, `Name: %s
Distance (mi): %d
----------------
%s`, topRec.Name, topRec.DistanceInMiles, topRec.Bio)
		} else {
			fmt.Fprintln(profilePictureView, "There's no one new around you.")
		}
		g.Flush()
	}
}

func main() {
	flag.StringVar(&facebookUserID, "fb_user_id", "", "facebook user id")
	flag.StringVar(&facebookToken, "fb_token", "", "facebook token")
	flag.Parse()

	if flag.NArg() == flag.NFlag() {
		fmt.Fprintf(os.Stderr, "Error: all flags are required. Run with -help for options.\n")
		os.Exit(1)
	}

	tinderClient = tinder.Init(facebookUserID, facebookToken)
	if err := tinderClient.Auth(); err != nil {
		fmt.Fprintln(os.Stderr, "Could not authenticate: ", err.Error())
		os.Exit(1)
	}

	updateGUIChan = make(chan struct{})

	go pollTinder(updateGUIChan, tinderClient, &profile)
	go updateGUI(updateGUIChan)

	if err := runGUI(); err != nil {
		fmt.Fprintf(os.Stderr, err.Error())
	}
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2014 Matt Jibson <matt.jibson@gmail.com>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package main

import (
	"bytes"
	"flag"
	"go/format"
	"go/parser"
	"go/printer"
	"go/token"
	"io"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"strconv"
	"strings"

	"code.google.com/p/go.tools/astutil"
)

const ThirdParty = "third_party"
const dirMode os.FileMode = 0755

var (
	dryrun   = flag.Bool("n", false, "don't perform any action, instead print them")
	create   = flag.Bool("c", false, "create the "+ThirdParty+" directory if needed")
	relative = flag.Bool("r", false, "use a relative third party directory (needed on App Engine)")
	verbose  = flag.Bool("v", false, "print actions")

	relpath, gopath string
)

func main() {
	flag.Parse()
	if *dryrun {
		*verbose = true
	}

	if *create {
		os.Mkdir(ThirdParty, dirMode)
	}
	if _, err := os.Open(ThirdParty); err != nil {
		log.Fatalf("could not open %s directory: run with -c or create it manually", ThirdParty)
	}

	pwd, err := os.Getwd()
	if err != nil {
		log.Fatal(err)
	}
	for _, s := range filepath.SplitList(os.Getenv("GOPATH")) {
		s, err := filepath.Abs(s)
		if err != nil {
			log.Fatal(err)
		}
		s, err = filepath.EvalSymlinks(s)
		if err != nil {
			log.Fatal(err)
		}
		if !strings.HasPrefix(pwd, s) {
			continue
		}
		gopath = s
		relpath = strings.TrimPrefix(pwd, filepath.Join(s, "src")+string(os.PathSeparator))
		break
	}
	if relpath == "" {
		log.Fatal("couldn't determine current directory relative to $GOPATH")
	}

	if *verbose {
		log.Println("using GOPATH:", gopath)
		log.Println("using relative path:", relpath)
	}

	for {
		update()
		if !rewriteImports() {
			break
		}
	}
}

var ImportSites = []string{
	"bazil.org",
	"code.google.com",
	"github.com",
	"labix.org",
	"launchpad.net",
}

func update() {
	paths := make(map[string]struct{})
	reltp := ThirdParty + "/"
	if !*relative {
		reltp = filepath.ToSlash(relpath) + "/" + reltp
	}
	filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
		if err != nil || info.IsDir() {
			return nil
		}
		fset := token.NewFileSet()
		f, err := parser.ParseFile(fset, path, nil, parser.ParseComments)
		if err != nil {
			return nil
		}
		for _, im := range f.Imports {
			v := im.Path.Value[1 : len(im.Path.Value)-1]
			if !strings.HasPrefix(v, reltp) {
				continue
			}
			paths[strings.TrimPrefix(v, reltp)] = struct{}{}
		}
		return nil
	})
	for k := range paths {
		fpath := filepath.Join(gopath, "src", k)
		f, err := os.Open(fpath)
		if err != nil {
			log.Printf("%s required, but could not be found at %s", k, fpath)
			continue
		}
		files, err := f.Readdir(0)
		if err != nil {
			log.Fatal(err)
		}
		f.Close()
		for _, source := range files {
			if source.IsDir() || strings.HasPrefix(source.Name(), ".") {
				continue
			}
			spath := filepath.Join(f.Name(), source.Name())
			destdir := filepath.Join(ThirdParty, k)
			dest := filepath.Join(destdir, source.Name())
			if err := os.MkdirAll(destdir, dirMode); err != nil {
				log.Fatal(err)
			}
			dst, err := os.Open(dest)
			created := false
			newer := false
			if os.IsNotExist(err) {
				if *verbose {
					log.Println("create", dest)
				}
				created = true
			} else if err != nil {
				log.Fatal(err)
			} else {
				destination, err := dst.Stat()
				if err != nil {
					log.Fatal(err)
				}
				newer = source.ModTime().After(destination.ModTime())
				dst.Close()
			}
			if created || newer {
				if *verbose {
					log.Printf("copy %s -> %s\n", spath, dest)
				}
				if !*dryrun {
					src, err := os.Open(spath)
					if err != nil {
						log.Fatal(err)
					}
					dst, err = os.OpenFile(dest, os.O_RDWR|os.O_CREATE|os.O_TRUNC, source.Mode())
					if err != nil {
						log.Fatal(err)
					}
					if _, err := io.Copy(dst, src); err != nil {
						log.Fatal(err)
					}
					src.Close()
					dst.Close()
				}
			}
		}
	}
}

func rewriteImports() (rewritten bool) {
	filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
		if err != nil || info.IsDir() {
			return nil
		}
		fset := token.NewFileSet()
		f, err := parser.ParseFile(fset, path, nil, parser.ParseComments)
		if err != nil {
			return nil
		}
		for _, im := range f.Imports {
			for _, site := range ImportSites {
				v, err := strconv.Unquote(im.Path.Value)
				if err != nil {
					log.Fatal(err)
				}
				// don't replace ourself
				if strings.HasPrefix(v, relpath+"/") {
					continue
				}
				if strings.HasPrefix(v, site+"/") {
					target := ThirdParty + "/" + v
					if !*relative {
						target = relpath + "/" + target
					}
					if *verbose {
						log.Printf("rewrite %s: %s -> %s\n", path, v, target)
					}
					if *dryrun {
						break
					}
					if !astutil.RewriteImport(fset, f, v, target) {
						log.Fatalf("%s: could not rewrite %s", path, im.Path.Value)
					}
					rewritten = true
					break
				}
			}
		}
		var buf bytes.Buffer
		if err := printer.Fprint(&buf, fset, f); err != nil {
			log.Fatal(err)
		}
		fb, err := format.Source(buf.Bytes())
		if err != nil {
			log.Fatal(err)
		}
		if err := ioutil.WriteFile(path, fb, info.Mode()); err != nil {
			log.Fatal(err)
		}
		return nil
	})
	return
}
<commit_msg>Default to _third_party<commit_after>/*
 * Copyright (c) 2014 Matt Jibson <matt.jibson@gmail.com>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package main

import (
	"bytes"
	"flag"
	"go/format"
	"go/parser"
	"go/printer"
	"go/token"
	"io"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"strconv"
	"strings"

	"code.google.com/p/go.tools/astutil"
)

const ThirdParty = "_third_party"
const dirMode os.FileMode = 0755

var (
	dryrun   = flag.Bool("n", false, "don't perform any action, instead print them")
	create   = flag.Bool("c", false, "create the "+ThirdParty+" directory if needed")
	relative = flag.Bool("r", false, "use a relative third party directory (needed on App Engine)")
	verbose  = flag.Bool("v", false, "print actions")

	relpath, gopath string
)

func main() {
	flag.Parse()
	if *dryrun {
		*verbose = true
	}

	if *create {
		os.Mkdir(ThirdParty, dirMode)
	}
	if _, err := os.Open(ThirdParty); err != nil {
		log.Fatalf("could not open %s directory: run with -c or create it manually", ThirdParty)
	}

	pwd, err := os.Getwd()
	if err != nil {
		log.Fatal(err)
	}
	for _, s := range filepath.SplitList(os.Getenv("GOPATH")) {
		s, err := filepath.Abs(s)
		if err != nil {
			log.Fatal(err)
		}
		s, err = filepath.EvalSymlinks(s)
		if err != nil {
			log.Fatal(err)
		}
		if !strings.HasPrefix(pwd, s) {
			continue
		}
		gopath = s
		relpath = strings.TrimPrefix(pwd, filepath.Join(s, "src")+string(os.PathSeparator))
		break
	}
	if relpath == "" {
		log.Fatal("couldn't determine current directory relative to $GOPATH")
	}

	if *verbose {
		log.Println("using GOPATH:", gopath)
		log.Println("using relative path:", relpath)
	}

	for {
		update()
		if !rewriteImports() {
			break
		}
	}
}

var ImportSites = []string{
	"bazil.org",
	"code.google.com",
	"github.com",
	"labix.org",
	"launchpad.net",
}

func update() {
	paths := make(map[string]struct{})
	reltp := ThirdParty + "/"
	if !*relative {
		reltp = filepath.ToSlash(relpath) + "/" + reltp
	}
	filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
		if err != nil || info.IsDir() {
			return nil
		}
		fset := token.NewFileSet()
		f, err := parser.ParseFile(fset, path, nil, parser.ParseComments)
		if err != nil {
			return nil
		}
		for _, im := range f.Imports {
			v := im.Path.Value[1 : len(im.Path.Value)-1]
			if !strings.HasPrefix(v, reltp) {
				continue
			}
			paths[strings.TrimPrefix(v, reltp)] = struct{}{}
		}
		return nil
	})
	for k := range paths {
		fpath := filepath.Join(gopath, "src", k)
		f, err := os.Open(fpath)
		if err != nil {
			log.Printf("%s required, but could not be found at %s", k, fpath)
			continue
		}
		files, err := f.Readdir(0)
		if err != nil {
			log.Fatal(err)
		}
		f.Close()
		for _, source := range files {
			if source.IsDir() || strings.HasPrefix(source.Name(), ".") {
				continue
			}
			spath := filepath.Join(f.Name(), source.Name())
			destdir := filepath.Join(ThirdParty, k)
			dest := filepath.Join(destdir, source.Name())
			if err := os.MkdirAll(destdir, dirMode); err != nil {
				log.Fatal(err)
			}
			dst, err := os.Open(dest)
			created := false
			newer := false
			if os.IsNotExist(err) {
				if *verbose {
					log.Println("create", dest)
				}
				created = true
			} else if err != nil {
				log.Fatal(err)
			} else {
				destination, err := dst.Stat()
				if err != nil {
					log.Fatal(err)
				}
				newer = source.ModTime().After(destination.ModTime())
				dst.Close()
			}
			if created || newer {
				if *verbose {
					log.Printf("copy %s -> %s\n", spath, dest)
				}
				if !*dryrun {
					src, err := os.Open(spath)
					if err != nil {
						log.Fatal(err)
					}
					dst, err = os.OpenFile(dest, os.O_RDWR|os.O_CREATE|os.O_TRUNC, source.Mode())
					if err != nil {
						log.Fatal(err)
					}
					if _, err := io.Copy(dst, src); err != nil {
						log.Fatal(err)
					}
					src.Close()
					dst.Close()
				}
			}
		}
	}
}

func rewriteImports() (rewritten bool) {
	filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
		if err != nil || info.IsDir() {
			return nil
		}
		fset := token.NewFileSet()
		f, err := parser.ParseFile(fset, path, nil, parser.ParseComments)
		if err != nil {
			return nil
		}
		for _, im := range f.Imports {
			for _, site := range ImportSites {
				v, err := strconv.Unquote(im.Path.Value)
				if err != nil {
					log.Fatal(err)
				}
				// don't replace ourself
				if strings.HasPrefix(v, relpath+"/") {
					continue
				}
				if strings.HasPrefix(v, site+"/") {
					target := ThirdParty + "/" + v
					if !*relative {
						target = relpath + "/" + target
					}
					if *verbose {
						log.Printf("rewrite %s: %s -> %s\n", path, v, target)
					}
					if *dryrun {
						break
					}
					if !astutil.RewriteImport(fset, f, v, target) {
						log.Fatalf("%s: could not rewrite %s", path, im.Path.Value)
					}
					rewritten = true
					break
				}
			}
		}
		var buf bytes.Buffer
		if err := printer.Fprint(&buf, fset, f); err != nil {
			log.Fatal(err)
		}
		fb, err := format.Source(buf.Bytes())
		if err != nil {
			log.Fatal(err)
		}
		if err := ioutil.WriteFile(path, fb, info.Mode()); err != nil {
			log.Fatal(err)
		}
		return nil
	})
	return
}
<|endoftext|>


<commit_before>package main

import (
	"os"
	"os/signal"
	"syscall"
	"time"

	log "github.com/Sirupsen/logrus"
	"github.com/minchao/smsender/smsender"
	"github.com/minchao/smsender/smsender/api"
	"github.com/minchao/smsender/smsender/providers/aws"
	"github.com/minchao/smsender/smsender/providers/dummy"
	"github.com/minchao/smsender/smsender/providers/nexmo"
	"github.com/minchao/smsender/smsender/providers/twilio"
	"github.com/minchao/smsender/smsender/web"
	"github.com/spf13/cobra"
	config "github.com/spf13/viper"
)

func handleSignals(s *smsender.Sender) {
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, syscall.SIGTERM)

	<-c

	log.Infoln("Shutting down")
	go time.AfterFunc(60*time.Second, func() {
		os.Exit(1)
	})
	s.Shutdown()
	os.Exit(0)
}

func main() {
	var configFile string
	var debug bool
	var help bool

	var rootCmd = &cobra.Command{
		Use:   "",
		Short: "smsender",
		Long:  "A SMS server written in Go (Golang)",
		Run: func(cmd *cobra.Command, args []string) {

			if len(configFile) > 0 {
				config.SetConfigFile(configFile)
			} else {
				config.SetConfigName("config")
				config.AddConfigPath(".")
			}
			if err := config.ReadInConfig(); err != nil {
				log.Fatalf("Fatal error config file: %s", err)
			}

			log.Infof("Config path: %s", config.ConfigFileUsed())

			if debug {
				log.SetLevel(log.DebugLevel)
				log.Debugln("Running in debug mode")
			}

			sender := smsender.NewSender()

			dummyProvider := dummy.NewProvider("dummy")
			sender.Router.AddProvider(dummyProvider)

			if ok := config.IsSet("providers.aws"); ok {
				provider := aws.Config{
					Region: config.GetString("providers.aws.region"),
					ID:     config.GetString("providers.aws.id"),
					Secret: config.GetString("providers.aws.secret"),
				}.NewProvider("aws")
				sender.Router.AddProvider(provider)
			}
			if ok := config.IsSet("providers.nexmo"); ok {
				provider := nexmo.Config{
					Key:           config.GetString("providers.nexmo.key"),
					Secret:        config.GetString("providers.nexmo.secret"),
					EnableWebhook: config.GetBool("providers.nexmo.webhook.enable"),
				}.NewProvider("nexmo")
				sender.Router.AddProvider(provider)
			}
			if ok := config.IsSet("providers.twilio"); ok {
				provider := twilio.Config{
					Sid:           config.GetString("providers.twilio.sid"),
					Token:         config.GetString("providers.twilio.token"),
					EnableWebhook: config.GetBool("providers.twilio.webhook.enable"),
					SiteURL:       config.GetString("http.siteURL"),
				}.NewProvider("twilio")
				sender.Router.AddProvider(provider)
			}

			sender.Router.LoadFromDB()

			api.InitAPI(sender)
			web.InitWeb(sender)

			go handleSignals(sender)

			sender.Run()
		},
	}

	rootCmd.Flags().StringVarP(&configFile, "config", "c", "", "Configuration file path")
	rootCmd.Flags().BoolVarP(&debug, "debug", "d", false, "Enable debug mode")
	rootCmd.Flags().BoolVarP(&help, "help", "h", false, "This help text")

	rootCmd.Execute()
}
<commit_msg>Fix command<commit_after>package main

import (
	"os"
	"os/signal"
	"syscall"
	"time"

	log "github.com/Sirupsen/logrus"
	"github.com/minchao/smsender/smsender"
	"github.com/minchao/smsender/smsender/api"
	"github.com/minchao/smsender/smsender/providers/aws"
	"github.com/minchao/smsender/smsender/providers/dummy"
	"github.com/minchao/smsender/smsender/providers/nexmo"
	"github.com/minchao/smsender/smsender/providers/twilio"
	"github.com/minchao/smsender/smsender/web"
	"github.com/spf13/cobra"
	config "github.com/spf13/viper"
)

func handleSignals(s *smsender.Sender) {
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, syscall.SIGTERM)

	<-c

	log.Infoln("Shutting down")
	go time.AfterFunc(60*time.Second, func() {
		os.Exit(1)
	})
	s.Shutdown()
	os.Exit(0)
}

func main() {
	var configFile string
	var debug bool

	var rootCmd = &cobra.Command{
		Use:   "smsender",
		Short: "smsender",
		Long:  "A SMS server written in Go (Golang)",
		Run: func(cmd *cobra.Command, args []string) {

			if len(configFile) > 0 {
				config.SetConfigFile(configFile)
			} else {
				config.SetConfigName("config")
				config.AddConfigPath(".")
			}
			if err := config.ReadInConfig(); err != nil {
				log.Fatalf("Fatal error config file: %s", err)
			}

			log.Infof("Config path: %s", config.ConfigFileUsed())

			if debug {
				log.SetLevel(log.DebugLevel)
				log.Debugln("Running in debug mode")
			}

			sender := smsender.NewSender()

			dummyProvider := dummy.NewProvider("dummy")
			sender.Router.AddProvider(dummyProvider)

			if ok := config.IsSet("providers.aws"); ok {
				provider := aws.Config{
					Region: config.GetString("providers.aws.region"),
					ID:     config.GetString("providers.aws.id"),
					Secret: config.GetString("providers.aws.secret"),
				}.NewProvider("aws")
				sender.Router.AddProvider(provider)
			}
			if ok := config.IsSet("providers.nexmo"); ok {
				provider := nexmo.Config{
					Key:           config.GetString("providers.nexmo.key"),
					Secret:        config.GetString("providers.nexmo.secret"),
					EnableWebhook: config.GetBool("providers.nexmo.webhook.enable"),
				}.NewProvider("nexmo")
				sender.Router.AddProvider(provider)
			}
			if ok := config.IsSet("providers.twilio"); ok {
				provider := twilio.Config{
					Sid:           config.GetString("providers.twilio.sid"),
					Token:         config.GetString("providers.twilio.token"),
					EnableWebhook: config.GetBool("providers.twilio.webhook.enable"),
					SiteURL:       config.GetString("http.siteURL"),
				}.NewProvider("twilio")
				sender.Router.AddProvider(provider)
			}

			sender.Router.LoadFromDB()

			api.InitAPI(sender)
			web.InitWeb(sender)

			go handleSignals(sender)

			sender.Run()
		},
	}

	rootCmd.Flags().StringVarP(&configFile, "config", "c", "", "Configuration file path")
	rootCmd.Flags().BoolVarP(&debug, "debug", "d", false, "Enable debug mode")

	rootCmd.Execute()
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"path"

	"github.com/mitchellh/go-homedir"
	"github.com/rojters/opengraph"
)

func main() {
	args := os.Args[1:]

	destinationDir, err := homedir.Expand("~/Downloads")
	if err != nil {
		log.Fatal(err)
	}

	if len(args) <= 0 {
		Usage()
		return
	}

	url := args[0]
	if url == "" {
		Usage()
		return
	}

	res, err := http.Get(url)
	if err != nil {
		log.Fatal(err)
	}

	md, err := opengraph.Extract(res.Body)
	if err != nil {
		log.Fatal(err)
	}

	var title, imageURL string

	for i := range md {
		switch md[i].Property {
		case "title":
			title = md[i].Content
		case "image":
			imageURL = md[i].Content
		}
	}

	if len(title) > 0 && len(imageURL) > 0 {
		title = title + ".jpg"

		SaveFile(destinationDir, title, imageURL)

		fmt.Println("Downloaded " + title + " to " + destinationDir)
	} else {
		fmt.Println("couldn't locate metadata")
	}
}

// SaveFile - saves the image to a local file
func SaveFile(destDir string, title string, imageURL string) {
	res, e := http.Get(imageURL)
	if e != nil {
		log.Fatal(e)
	}

	defer res.Body.Close()

	file, err := os.Create(path.Join(destDir, title))
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()

	_, err = io.Copy(file, res.Body)
	if err != nil {
		log.Fatal(err)
	}
}

// Usage - Display usage info
func Usage() {
	fmt.Println("Please pass a url to check")
	fmt.Println("")
	fmt.Println("usage: scov https://soundcloud.com/artist/track")
	return
}
<commit_msg>update usage info<commit_after>package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"path"

	"github.com/mitchellh/go-homedir"
	"github.com/rojters/opengraph"
)

func main() {
	args := os.Args[1:]

	destinationDir, err := homedir.Expand("~/Downloads")
	if err != nil {
		log.Fatal(err)
	}

	if len(args) <= 0 {
		Usage()
		return
	}

	url := args[0]
	if url == "" {
		Usage()
		return
	}

	res, err := http.Get(url)
	if err != nil {
		log.Fatal(err)
	}

	md, err := opengraph.Extract(res.Body)
	if err != nil {
		log.Fatal(err)
	}

	var title, imageURL string

	for i := range md {
		switch md[i].Property {
		case "title":
			title = md[i].Content
		case "image":
			imageURL = md[i].Content
		}
	}

	if len(title) > 0 && len(imageURL) > 0 {
		title = title + ".jpg"

		SaveFile(destinationDir, title, imageURL)

		fmt.Println("Downloaded " + title + " to " + destinationDir)
	} else {
		fmt.Println("couldn't locate metadata")
	}
}

// SaveFile - saves the image to a local file
func SaveFile(destDir string, title string, imageURL string) {
	res, e := http.Get(imageURL)
	if e != nil {
		log.Fatal(e)
	}

	defer res.Body.Close()

	file, err := os.Create(path.Join(destDir, title))
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()

	_, err = io.Copy(file, res.Body)
	if err != nil {
		log.Fatal(err)
	}
}

// Usage - Display usage info
func Usage() {
	fmt.Println("Please pass a url to check")
	fmt.Println("")
	fmt.Println("usage: scar https://soundcloud.com/artist/track")
	return
}
<|endoftext|>