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

package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"os/exec"
	"regexp"
	"strings"
)

func set_background(fname string) {
	fmt.Println("Setting APOD picture to desktop background.")

	osacmd := fmt.Sprintf(`tell application "System Events" to set picture of every desktop to "%s"`, fname)
	cmdbytes := []byte(osacmd)
	scriptf := "/tmp/background.scpt"
	var mode os.FileMode = 0644
	e := ioutil.WriteFile(scriptf, cmdbytes, mode)
	if e != nil {
		fmt.Printf("Error writing AppleScript file: %s\n", e.Error())
		os.Exit(1)
	}

	_, e = exec.Command("/usr/bin/osascript", scriptf).CombinedOutput()
	if e != nil {
		fmt.Printf("Error setting APOD picture to background: \n%s\n", e.Error())
		os.Exit(1)
	}

	e = os.Remove(scriptf)
	if e != nil {
		fmt.Printf("Error deleting file: %s\n", e.Error())
	}
}

func download_image(url string, uri string) string {
	fmt.Printf("Downloading photo...")
	img_url := url + "/" + uri
	resp, e := http.Get(img_url)
	if e != nil {
		fmt.Printf("Error downloading APOD photo: %s\n", e.Error())
		os.Exit(1)
	}

	body, e := ioutil.ReadAll(resp.Body)
	if e != nil {
		fmt.Printf("Error reading response from APOD: %s\n", e.Error())
		os.Exit(1)
	}

	ext := strings.Split(uri, ".")
	fname := "/tmp/apod." + ext[len(ext)-1:][0]
	var mode os.FileMode = 0644
	e = ioutil.WriteFile(fname, body, mode)
	if e != nil {
		fmt.Printf("Error writing file to ", e.Error())
		os.Exit(1)
	}
	fmt.Println("Done.")
	fmt.Printf("Photo saved to %s.\n", fname)

	return fname
}

func get_image_uri(page []byte) string {
	fmt.Println("Getting APOD image URL.")
	pattern := `<a href="(image\/\d{4}\/\w+\.jpg|png)">`
	re := regexp.MustCompile(pattern)
	match := re.FindAllStringSubmatch(string(page[:]), 1)
	return match[0][1]
}

func fetch_page(url string) []byte {
	fmt.Println("Fetching APOD page.")
	resp, e := http.Get(url)
	if e != nil {
		fmt.Printf("Error while contacting APOD: %s\n", e.Error())
		os.Exit(1)
	}
	body, e := ioutil.ReadAll(resp.Body)
	if e != nil {
		fmt.Printf("Error reading response from APOD: %s\n", e.Error())
		os.Exit(1)
	}
	return body
}

func main() {
	url := "http://apod.nasa.gov"
	page := fetch_page(url)
	img_uri := get_image_uri(page)
	fname := download_image(url, img_uri)
	set_background(fname)
}
<commit_msg>Oh, how ironic that I didn't check for an image thinking, 'Hey, of course NASA will always have an image'.  That was wrong, of course, because today they had a YouTube video timelapse thingy.  Thanks, NASA<commit_after>// Copyright 2014 Paul Durivage <pauldurivage@gmail.com>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"os/exec"
	"regexp"
	"strings"
)

func set_background(fname string) {
	fmt.Println("Setting APOD picture to desktop background.")

	osacmd := fmt.Sprintf(`tell application "System Events" to set picture of every desktop to "%s"`, fname)
	cmdbytes := []byte(osacmd)
	scriptf := "/tmp/background.scpt"
	var mode os.FileMode = 0644
	e := ioutil.WriteFile(scriptf, cmdbytes, mode)
	if e != nil {
		fmt.Printf("Error writing AppleScript file: %s\n", e.Error())
		os.Exit(1)
	}

	_, e = exec.Command("/usr/bin/osascript", scriptf).CombinedOutput()
	if e != nil {
		fmt.Printf("Error setting APOD picture to background: \n%s\n", e.Error())
		os.Exit(1)
	}

	e = os.Remove(scriptf)
	if e != nil {
		fmt.Printf("Error deleting file: %s\n", e.Error())
	}
}

func download_image(url string, uri string) string {
	fmt.Printf("Downloading photo...")
	img_url := url + "/" + uri
	resp, e := http.Get(img_url)
	if e != nil {
		fmt.Printf("Error downloading APOD photo: %s\n", e.Error())
		os.Exit(1)
	}

	body, e := ioutil.ReadAll(resp.Body)
	if e != nil {
		fmt.Printf("Error reading response from APOD: %s\n", e.Error())
		os.Exit(1)
	}

	ext := strings.Split(uri, ".")
	fname := "/tmp/apod." + ext[len(ext)-1:][0]
	var mode os.FileMode = 0644
	e = ioutil.WriteFile(fname, body, mode)
	if e != nil {
		fmt.Printf("Error writing file to ", e.Error())
		os.Exit(1)
	}
	fmt.Println("Done.")
	fmt.Printf("Photo saved to %s.\n", fname)

	return fname
}

func get_image_uri(page []byte) string {
	fmt.Println("Getting APOD image URL.")
	pattern := `<a href="(image\/\d{4}\/\w+\.jpg|png)">`
	re := regexp.MustCompile(pattern)
	match := re.FindAllStringSubmatch(string(page[:]), 1)
	if match == nil {
		fmt.Println("No image found today!")
		os.Exit(0)
	}
	return match[0][1]
}

func fetch_page(url string) []byte {
	fmt.Println("Fetching APOD page.")
	resp, e := http.Get(url)
	if e != nil {
		fmt.Printf("Error while contacting APOD: %s\n", e.Error())
		os.Exit(1)
	}
	body, e := ioutil.ReadAll(resp.Body)
	if e != nil {
		fmt.Printf("Error reading response from APOD: %s\n", e.Error())
		os.Exit(1)
	}
	return body
}

func main() {
	url := "http://apod.nasa.gov"
	page := fetch_page(url)
	img_uri := get_image_uri(page)
	fname := download_image(url, img_uri)
	set_background(fname)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"html/template"
	"net/http"

	"github.com/facebookgo/grace/gracehttp"
	"github.com/gin-gonic/gin"

	"github.com/eirka/eirka-libs/config"
	"github.com/eirka/eirka-libs/csrf"
	"github.com/eirka/eirka-libs/db"

	local "github.com/eirka/eirka-index/config"
)

func init() {

	// Database connection settings
	dbase := db.Database{
		User:           local.Settings.Database.User,
		Password:       local.Settings.Database.Password,
		Proto:          local.Settings.Database.Protocol,
		Host:           local.Settings.Database.Host,
		Database:       local.Settings.Database.Database,
		MaxIdle:        local.Settings.Index.DatabaseMaxIdle,
		MaxConnections: local.Settings.Index.DatabaseMaxConnections,
	}

	// Set up DB connection
	dbase.NewDb()

	// Get limits and stuff from database
	config.GetDatabaseSettings()

}

func main() {

	// parse our template
	t := template.Must(template.New("templates").Delims("[[", "]]").Parse(index))
	t = template.Must(t.Parse(head))
	t = template.Must(t.Parse(header))
	t = template.Must(t.Parse(navmenu))
	t = template.Must(t.Parse(angular))
	t = template.Must(t.ParseGlob(fmt.Sprintf("%s/includes/*.tmpl", local.Settings.Directories.AssetsDir)))

	r := gin.Default()

	// load template into gin
	r.SetHTMLTemplate(t)

	// use the details middleware
	r.Use(Details())
	// generates our csrf cookie
	r.Use(csrf.Cookie())

	// these routes are handled by angularjs
	r.GET("/", IndexController)
	r.GET("/page/:id", IndexController)
	r.GET("/thread/:id/:page", IndexController)
	r.GET("/directory", IndexController)
	r.GET("/directory/:page", IndexController)
	r.GET("/image/:id", IndexController)
	r.GET("/tags/:page", IndexController)
	r.GET("/tags", IndexController)
	r.GET("/tag/:id/:page", IndexController)
	r.GET("/account", IndexController)
	r.GET("/trending", IndexController)
	r.GET("/favorites/:page", IndexController)
	r.GET("/favorites", IndexController)
	r.GET("/admin", IndexController)
	r.GET("/error", ErrorController)

	// if nothing matches
	r.NoRoute(ErrorController)

	s := &http.Server{
		Addr:    fmt.Sprintf("%s:%d", local.Settings.Index.Host, local.Settings.Index.Port),
		Handler: r,
	}

	gracehttp.Serve(s)

}
<commit_msg>add pid file for systemd graceful reloading<commit_after>package main

import (
	"fmt"
	"html/template"
	"net/http"

	"github.com/facebookgo/grace/gracehttp"
	"github.com/facebookgo/pidfile"
	"github.com/gin-gonic/gin"

	"github.com/eirka/eirka-libs/config"
	"github.com/eirka/eirka-libs/csrf"
	"github.com/eirka/eirka-libs/db"

	local "github.com/eirka/eirka-index/config"
)

func init() {

	// Database connection settings
	dbase := db.Database{
		User:           local.Settings.Database.User,
		Password:       local.Settings.Database.Password,
		Proto:          local.Settings.Database.Protocol,
		Host:           local.Settings.Database.Host,
		Database:       local.Settings.Database.Database,
		MaxIdle:        local.Settings.Index.DatabaseMaxIdle,
		MaxConnections: local.Settings.Index.DatabaseMaxConnections,
	}

	// Set up DB connection
	dbase.NewDb()

	// Get limits and stuff from database
	config.GetDatabaseSettings()

}

func main() {

	// create pid file
	pidfile.SetPidfilePath("/run/eirka/eirka-index.pid")

	err := pidfile.Write()
	if err != nil {
		panic("Could not write pid file")
	}

	// parse our template
	t := template.Must(template.New("templates").Delims("[[", "]]").Parse(index))
	t = template.Must(t.Parse(head))
	t = template.Must(t.Parse(header))
	t = template.Must(t.Parse(navmenu))
	t = template.Must(t.Parse(angular))
	t = template.Must(t.ParseGlob(fmt.Sprintf("%s/includes/*.tmpl", local.Settings.Directories.AssetsDir)))

	r := gin.Default()

	// load template into gin
	r.SetHTMLTemplate(t)

	// use the details middleware
	r.Use(Details())
	// generates our csrf cookie
	r.Use(csrf.Cookie())

	// these routes are handled by angularjs
	r.GET("/", IndexController)
	r.GET("/page/:id", IndexController)
	r.GET("/thread/:id/:page", IndexController)
	r.GET("/directory", IndexController)
	r.GET("/directory/:page", IndexController)
	r.GET("/image/:id", IndexController)
	r.GET("/tags/:page", IndexController)
	r.GET("/tags", IndexController)
	r.GET("/tag/:id/:page", IndexController)
	r.GET("/account", IndexController)
	r.GET("/trending", IndexController)
	r.GET("/favorites/:page", IndexController)
	r.GET("/favorites", IndexController)
	r.GET("/admin", IndexController)
	r.GET("/error", ErrorController)

	// if nothing matches
	r.NoRoute(ErrorController)

	s := &http.Server{
		Addr:    fmt.Sprintf("%s:%d", local.Settings.Index.Host, local.Settings.Index.Port),
		Handler: r,
	}

	gracehttp.Serve(s)

}
<|endoftext|>


<commit_before>package main

import (
  "flag"
  "fmt"
  "os"
  "os/exec"
  "strings"
  "syscall"
  "time"
)

const VERSION="v0.0.1"

func main() {
  var interval float64
  flag.Float64Var(&interval, "i", 1.0, "Interval to wait between executions in seconds")

  var interrupt bool
  flag.BoolVar(&interrupt, "x", false, "Exit and elevate status code if the command fails")

  var version bool
  flag.BoolVar(&version, "v", false, "Print out version")

  flag.Parse()

  if version {
    fmt.Println(VERSION)
    os.Exit(0)
  }

  command := flag.Args()

  if len(command) == 0 {
    os.Exit(0)
  }

  loop(intervalToTime(1000*interval), func () {
    status := run(measure(command))
    if(interrupt && status != 0) {
      os.Exit(status)
    }
  })
}

func intervalToTime(i float64) time.Duration {
  return time.Duration(i) * time.Millisecond
}

func reset() {
  run([]string {"clear"})
}

func measure(command []string) []string {
  return append([]string {"time"}, command...)
}

func run(command []string) int {
  cmd := exec.Command(getShell(), wrapForShell(buildArgs(command))...)
  cmd.Env = os.Environ()
  cmd.Stdout = os.Stdout
  cmd.Stderr = os.Stderr
  cmd.Run()
  status, _ := cmd.ProcessState.Sys().(syscall.WaitStatus)
  return status.ExitStatus()
}

func buildArgs(command []string) string {
  return strings.Join(command, " ")
}

func wrapForShell(command string) []string {
  return []string {"-c", fmt.Sprintf("%s; eval %s", sourceFiles(), command)}
}

func sourceFiles() string {
  return fmt.Sprintf("%s %s", getShellSourceCmd(), getSourceFilePath())
}

func getSourceFilePath() string {
  return "~/.zshrc"
}

func getShellSourceCmd() string {
  return "."
}

func getShell() string {
  bin, found := syscall.Getenv("SHELL")
  if found == false {
    bin, _ = exec.LookPath("sh")
  }
  return bin
}

func loop(d time.Duration, fn func()) {
  fn()
  for range time.Tick(d) {
    fn()
  }
}
<commit_msg>Close #7. Do not source dotfiles<commit_after>package main

import (
  "flag"
  "fmt"
  "os"
  "os/exec"
  "strings"
  "syscall"
  "time"
)

const VERSION="v0.0.1"

func main() {
  var interval float64
  flag.Float64Var(&interval, "i", 1.0, "Interval to wait between executions in seconds")

  var interrupt bool
  flag.BoolVar(&interrupt, "x", false, "Exit and elevate status code if the command fails")

  var version bool
  flag.BoolVar(&version, "v", false, "Print out version")

  flag.Parse()

  if version {
    fmt.Println(VERSION)
    os.Exit(0)
  }

  command := flag.Args()

  if len(command) == 0 {
    os.Exit(0)
  }

  loop(intervalToTime(1000*interval), func () {
    status := run(measure(command))
    if(interrupt && status != 0) {
      os.Exit(status)
    }
  })
}

func intervalToTime(i float64) time.Duration {
  return time.Duration(i) * time.Millisecond
}

func reset() {
  run([]string {"clear"})
}

func measure(command []string) []string {
  return append([]string {"time"}, command...)
}

func run(command []string) int {
  cmd := exec.Command(getShell(), wrapForShell(buildArgs(command))...)
  cmd.Env = os.Environ()
  cmd.Stdout = os.Stdout
  cmd.Stderr = os.Stderr
  cmd.Run()
  status, _ := cmd.ProcessState.Sys().(syscall.WaitStatus)
  return status.ExitStatus()
}

func buildArgs(command []string) string {
  return strings.Join(command, " ")
}

func wrapForShell(command string) []string {
  return []string {"-c", fmt.Sprintf("eval %s", command)}
}

func getShell() string {
  bin, found := syscall.Getenv("SHELL")
  if found == false {
    bin, _ = exec.LookPath("sh")
  }
  return bin
}

func loop(d time.Duration, fn func()) {
  fn()
  for range time.Tick(d) {
    fn()
  }
}
<|endoftext|>


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

package main

import (
	"fmt"
	"io/ioutil"
	"log"
  //"unicode/utf8"
  //"container/list"
  //"bytes"
	"net/http"
	//"encoding/json"
	//"net/url"
    "strings"
	// "database/sql"
	"os"
	"github.com/line/line-bot-sdk-go/linebot"
	// _ "github.com/go-sql-driver/mysql"
)

var bot *linebot.Client
var echo string
var op string
var bottun bool

type Data struct{
    resultType string `json:"resultType"`
    resultQuestion string `json:"resultQuestion"`
    resultContent []content `json:"resultContent"`
    requirementType string `json:"requirementType"`
}

type content struct{
    entity string `json:"entity"`
    Type string `json:"Type"`
}

var d Data

func main() {
	var err error
	bot, err = linebot.New(os.Getenv("ChannelSecret"), os.Getenv("ChannelAccessToken"))
	log.Println("Bot:", bot, " err:", err)
	http.HandleFunc("/callback", callbackHandler)
    http.HandleFunc("/", sayhelloName) // set router
	port := os.Getenv("PORT")
	addr := fmt.Sprintf(":%s", port)
	http.ListenAndServe(addr, nil)

    bottun = false
}

func sayhelloName(w http.ResponseWriter, r *http.Request) {
    r.ParseForm()  // parse arguments, you have to call this by yourself
    fmt.Println(r.Form)  // print form information in server side
    fmt.Println("path", r.URL.Path)
    fmt.Println("scheme", r.URL.Scheme)
    fmt.Println(r.Form["user"])
    fmt.Println(r.Form["message"])
    bot.PushMessage(r.Form["user"][0], linebot.NewTextMessage(r.Form["message"][0])).Do()
    for k, v := range r.Form {
        fmt.Println("key:", k)
        fmt.Println("val:", strings.Join(v, ""))
    }
    fmt.Fprintf(w, r.Form["user"][0]+r.Form["message"][0]) // send data to client side
}

// func mysql(){
// 	var db, err = sql.Open("mysql","wmlab:wmlab@tcp(140.115.54.82:3306)/wmlab?charset=utf8")
// 	if err != nil {
// 		fmt.Println(err)
//          // Just for example purpose. You should use proper error handling instead of panic
//     }
//     defer db.Close()

//  	err = db.Ping()
// 	if err != nil {
// 		log.Fatal(err)
// 	}

// 	rows, err := db.Query("select * from test")
// 	if err != nil {
// 		log.Println(err)
// 	}

// 	defer rows.Close()
// 	var col1 int
// 	for rows.Next() {
// 		err := rows.Scan(&col1)
// 		if err != nil {
// 			log.Fatal(err)
// 		}
// 		dbinfo=col1
// 	}
// }
func httpGet(q string , id string) {

    echo = "OK"
    bottun = false
    op = ""

    q = strings.Replace( q , " " , "," , -1)
    //q = strings.Replace("oink oink oink", "oink", "moo", -1)
    resp, err := http.Get("http://140.115.54.93:8088/?q="+q+"&id="+id)
    if err != nil {
        // handle error
       panic(err.Error())
    }
    defer resp.Body.Close()

    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        // handle error
       panic(err.Error())
    }

    echo = string(body)

    if echo == "location"{
       bottun = true
    }

    // _, err = bot.PushMessage("Uf6263c4b814700c680228b8b64a27dd6", linebot.NewTextMessage(echo)).Do()

    //------------for Luis
    // var r =  map[string]interface{}{}
    // var tempString string
    // tempString =string(body)

    // temp1 := strings.Split(tempString,"entity")
    // temp2 := strings.Split(tempString,"\"Type")
    // entity := list.New()
    // Type := list.New()
    // for i := 0; i < len(temp1); i++ {
    //   if i>=1{
    //     entity.PushBack( strings.Split(strings.Split(temp1[i],"\",")[0],":\"")[1] )
    //   }
    // }
    // for i := 0; i < len(temp2); i++ {
    //   if i>=1{
    //     Type.PushBack( strings.Split(strings.Split(temp2[i],"\"}")[0],":\"")[1] )
    //   }
    // }
    // json.Unmarshal(body, &r)

    // if r["resultType"].(string) == "none" {
    //   echo = "我不了解你在說什麼～@@"
    // } else if r["resultType"].(string) == "greeting" {
    //   echo = "你好！我是LUIS！我可以提供您數學的教材或是練習題喔！"
    // } else if r["resultType"].(string) == "appreciation" {
    //   echo = "歡迎您再次使用LUIS!我很樂意再次提供您服務！"
    // } else if r["resultType"].(string) == "connectionError" {
    //   echo = "對不起，我出了點問題，現在沒辦法回答你問題@@"
    // } else if r["resultType"].(string) == "unknown" {
    //   echo = "不好意思，我不知道你問的定理是什麼QQ"
    // } else if r["resultType"].(string) == "question" {
    //   if r["requirementType"].(string) == "none" {
    //     bottun = true
    //     for e:= entity.Front();e!=nil;e = e.Next(){

    //      op += e.Value.(string)
    //     }
    //   }
    // }

    //-----------------for luis

}

func callbackHandler(w http.ResponseWriter, r *http.Request) {
	events, err := bot.ParseRequest(r)

	if err != nil {
		if err == linebot.ErrInvalidSignature {
			w.WriteHeader(400)
		} else {
			w.WriteHeader(500)
		}
		return
	}
	//GG

	for _, event := range events {
		if event.Type == linebot.EventTypeMessage {
			switch message := event.Message.(type) {
			case *linebot.TextMessage:

        echo ="OK"
        bottun = false
        if message.Type =="text" {
            httpGet(message.Text,event.Source.UserID)
        }else if message.Type == "location" {
            httpGet(message.Address,event.Source.UserID)
        } else {
            echo ="我不能了解您的話"
        }

				// mysql()
				//message.ID+":"+message.Text
        if bottun {
           //_, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage(echo)).Do()
            // var ff string
            // var gg string
            // ff = "我要"+op+"的練習題"
            // gg = "我要"+op+"的教材"
            // leftBtn := linebot.NewMessageTemplateAction("練習題", ff)
            // rightBtn := linebot.NewMessageTemplateAction("教材", gg)
            uri := linebot.NewURITemplateAction("提供地點","line://nv/location")
            template := linebot.NewButtonsTemplate("","地點","請問您目前所處的地點是?", uri)

            templatemessgage := linebot.NewTemplateMessage("Sorry :(, please update your app.", template)
            _, err = bot.ReplyMessage(event.ReplyToken, templatemessgage).Do()
           //op=""

        } else {
           _, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage( echo )).Do()
           // _, err = bot.PushMessage(event.ReplyToken, linebot.NewTextMessage( echo )).Do()
           op=""
        }

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

package main

import (
	"fmt"
	"io/ioutil"
	"log"
  //"unicode/utf8"
  //"container/list"
  //"bytes"
	"net/http"
	//"encoding/json"
	//"net/url"
    "strings"
	// "database/sql"
	"os"
	"github.com/line/line-bot-sdk-go/linebot"
	// _ "github.com/go-sql-driver/mysql"
)

var bot *linebot.Client
var echo string
var op string
var bottun bool

type Data struct{
    resultType string `json:"resultType"`
    resultQuestion string `json:"resultQuestion"`
    resultContent []content `json:"resultContent"`
    requirementType string `json:"requirementType"`
}

type content struct{
    entity string `json:"entity"`
    Type string `json:"Type"`
}

var d Data

func main() {
	var err error
	bot, err = linebot.New(os.Getenv("ChannelSecret"), os.Getenv("ChannelAccessToken"))
	log.Println("Bot:", bot, " err:", err)
	http.HandleFunc("/callback", callbackHandler)
    http.HandleFunc("/", sayhelloName) // set router
	port := os.Getenv("PORT")
	addr := fmt.Sprintf(":%s", port)
	http.ListenAndServe(addr, nil)

    bottun = false
}

func sayhelloName(w http.ResponseWriter, r *http.Request) {
    r.ParseForm()  // parse arguments, you have to call this by yourself
    fmt.Println(r.Form)  // print form information in server side
    fmt.Println("path", r.URL.Path)
    fmt.Println("scheme", r.URL.Scheme)
    fmt.Println(r.Form["user"])
    fmt.Println(r.Form["message"])
    bot.PushMessage(r.Form["user"][0], linebot.NewTextMessage(r.Form["message"][0])).Do()
    for k, v := range r.Form {
        fmt.Println("key:", k)
        fmt.Println("val:", strings.Join(v, ""))
    }
    fmt.Fprintf(w, r.Form["user"][0]+r.Form["message"][0]) // send data to client side
}

// func mysql(){
// 	var db, err = sql.Open("mysql","wmlab:wmlab@tcp(140.115.54.82:3306)/wmlab?charset=utf8")
// 	if err != nil {
// 		fmt.Println(err)
//          // Just for example purpose. You should use proper error handling instead of panic
//     }
//     defer db.Close()

//  	err = db.Ping()
// 	if err != nil {
// 		log.Fatal(err)
// 	}

// 	rows, err := db.Query("select * from test")
// 	if err != nil {
// 		log.Println(err)
// 	}

// 	defer rows.Close()
// 	var col1 int
// 	for rows.Next() {
// 		err := rows.Scan(&col1)
// 		if err != nil {
// 			log.Fatal(err)
// 		}
// 		dbinfo=col1
// 	}
// }
func httpGet(q string , id string) {

    echo = "OK"
    bottun = false
    op = ""

    q = strings.Replace( q , " " , "," , -1)
    //q = strings.Replace("oink oink oink", "oink", "moo", -1)
    resp, err := http.Get("http://140.115.54.93:8088/?q="+q+"&id="+id)
    if err != nil {
        // handle error
       panic(err.Error())
    }
    defer resp.Body.Close()

    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        // handle error
       panic(err.Error())
    }

    echo = string(body)

    if echo == "location"{
       bottun = true
    }

    // _, err = bot.PushMessage("Uf6263c4b814700c680228b8b64a27dd6", linebot.NewTextMessage(echo)).Do()

    //------------for Luis
    // var r =  map[string]interface{}{}
    // var tempString string
    // tempString =string(body)

    // temp1 := strings.Split(tempString,"entity")
    // temp2 := strings.Split(tempString,"\"Type")
    // entity := list.New()
    // Type := list.New()
    // for i := 0; i < len(temp1); i++ {
    //   if i>=1{
    //     entity.PushBack( strings.Split(strings.Split(temp1[i],"\",")[0],":\"")[1] )
    //   }
    // }
    // for i := 0; i < len(temp2); i++ {
    //   if i>=1{
    //     Type.PushBack( strings.Split(strings.Split(temp2[i],"\"}")[0],":\"")[1] )
    //   }
    // }
    // json.Unmarshal(body, &r)

    // if r["resultType"].(string) == "none" {
    //   echo = "我不了解你在說什麼～@@"
    // } else if r["resultType"].(string) == "greeting" {
    //   echo = "你好！我是LUIS！我可以提供您數學的教材或是練習題喔！"
    // } else if r["resultType"].(string) == "appreciation" {
    //   echo = "歡迎您再次使用LUIS!我很樂意再次提供您服務！"
    // } else if r["resultType"].(string) == "connectionError" {
    //   echo = "對不起，我出了點問題，現在沒辦法回答你問題@@"
    // } else if r["resultType"].(string) == "unknown" {
    //   echo = "不好意思，我不知道你問的定理是什麼QQ"
    // } else if r["resultType"].(string) == "question" {
    //   if r["requirementType"].(string) == "none" {
    //     bottun = true
    //     for e:= entity.Front();e!=nil;e = e.Next(){

    //      op += e.Value.(string)
    //     }
    //   }
    // }

    //-----------------for luis

}

func callbackHandler(w http.ResponseWriter, r *http.Request) {
	events, err := bot.ParseRequest(r)

	if err != nil {
		if err == linebot.ErrInvalidSignature {
			w.WriteHeader(400)
		} else {
			w.WriteHeader(500)
		}
		return
	}
	//GG

	for _, event := range events {
		if event.Type == linebot.EventTypeMessage {
			switch message := event.Message.(type) {
			case *linebot.TextMessage:

        echo ="OK"
        bottun = false
        if message.type =="text" {
            httpGet(message.Text,event.Source.UserID)
        }else if message.type == "location" {
            httpGet(message.address,event.Source.UserID)
        } else {
            echo ="我不能了解您的話"
        }

				// mysql()
				//message.ID+":"+message.Text
        if bottun {
           //_, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage(echo)).Do()
            // var ff string
            // var gg string
            // ff = "我要"+op+"的練習題"
            // gg = "我要"+op+"的教材"
            // leftBtn := linebot.NewMessageTemplateAction("練習題", ff)
            // rightBtn := linebot.NewMessageTemplateAction("教材", gg)
            uri := linebot.NewURITemplateAction("提供地點","line://nv/location")
            template := linebot.NewButtonsTemplate("","地點","請問您目前所處的地點是?", uri)

            templatemessgage := linebot.NewTemplateMessage("Sorry :(, please update your app.", template)
            _, err = bot.ReplyMessage(event.ReplyToken, templatemessgage).Do()
           //op=""

        } else {
           _, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage( echo )).Do()
           // _, err = bot.PushMessage(event.ReplyToken, linebot.NewTextMessage( echo )).Do()
           op=""
        }

			}
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	_ "github.com/lib/pq"

	"database/sql"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
)

const (
	graphUrl string = "https://graph.facebook.com"
)

type paging struct {
	Previous string `json:"previous"`
	Next     string `json:"next"`
}

type feed struct {
	Id string `json:"id"`
}

type graphResponse struct {
	Data []feed `json:"data"`
	Paging paging `json:"paging"`
}

func graph(path string, accessToken string) (resp *http.Response, err error) {
	return http.Get(graphUrl + path + "?access_token=" + accessToken)
}

func main() {
	accessToken := os.Getenv("ACCESS_TOKEN")

	if accessToken == "" {
		fmt.Print("access token is not specified")
	}

	resp, err := graph("/10150149727825637/feed", accessToken)

	if err != nil {
		fmt.Printf("%s\n", err)
	}

	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)

	if err != nil {
		fmt.Printf("%s\n", err)
	}

	var data graphResponse
	err = json.Unmarshal(body, &data)

	if err != nil {
		fmt.Printf("%s\n", err)
	}

	for _, feed := range data.Data {
		fmt.Printf("%s\n", feed.Id)
	}

	db, err := sql.Open("postgres", "user=postgres dbname=mycrawler")

	defer db.Close()

	if err != nil {
		fmt.Printf("%s\n", err)
	}

	query := "insert into feeds (id) values ($1)"
	stmt, err := db.Prepare(query)

	if err != nil {
		fmt.Printf("%s\n", err)
	}

	for _, feed := range data.Data {
		row := stmt.QueryRow(feed.Id)
		fmt.Printf("%s\n", row)
	}

}
<commit_msg>panic<commit_after>package main

import (
	_ "github.com/lib/pq"

	"database/sql"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
)

const (
	graphUrl string = "https://graph.facebook.com"
)

type paging struct {
	Previous string `json:"previous"`
	Next     string `json:"next"`
}

type feed struct {
	Id string `json:"id"`
}

type graphResponse struct {
	Data []feed `json:"data"`
	Paging paging `json:"paging"`
}

func graph(path string, accessToken string) (resp *http.Response, err error) {
	return http.Get(graphUrl + path + "?access_token=" + accessToken)
}

func main() {
	accessToken := os.Getenv("ACCESS_TOKEN")

	if accessToken == "" {
		panic(fmt.Sprint("access token is not specified"))
	}

	// request
	resp, err := graph("/10150149727825637/feed", accessToken)
	if err != nil {
		panic(fmt.Sprintf("%s\n", err))
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		panic(fmt.Sprintf("%s\n", err))
	}

	// parse
	var data graphResponse
	err = json.Unmarshal(body, &data)
	if err != nil {
		panic(fmt.Sprintf("%s\n", err))
	}
	for _, feed := range data.Data {
		fmt.Printf("%s\n", feed.Id)
	}

	// get db connection
	db, err := sql.Open("postgres", "user=postgres dbname=mycrawler")
	if err != nil {
		panic(fmt.Sprintf("%s\n", err))
	}
	defer db.Close()

	// bulk insert
	query := "insert into feeds (id) values ($1)"
	stmt, err := db.Prepare(query)

	if err != nil {
		panic(fmt.Sprintf("%s\n", err))
	}

	for _, feed := range data.Data {
		row := stmt.QueryRow(feed.Id)
		fmt.Printf("%s\n", row)
	}

}
<|endoftext|>


<commit_before>package main

import (
	"os"
	"os/signal"
	"syscall"
	"github.com/golang/glog"
)

func main() {
	c := parseConfig()

	//Exit gracefully
	exit := make(chan os.Signal, 1)
	signal.Notify(exit, os.Interrupt, syscall.SIGTERM)
	go func() {
		<-exit
		glog.Info("Shutting down...")
		os.Exit(0)
	}()

	b := NewBackends(c)
	b.Init()
	glog.Info("Starting proxy")
	p := NewTCPProxy(c, b)
	p.start()

}
<commit_msg>NXIO-209 handle SIGUSR1 by dumping goroutine stacks<commit_after>package main

import (
	"os"
	"os/signal"
	"syscall"
	"github.com/golang/glog"
	"runtime/pprof"
)

func main() {
	c := parseConfig()

	handleSignals()

	b := NewBackends(c)

	b.Init()
	glog.Info("Starting proxy")
	p := NewTCPProxy(c, b)
	p.start()

}

func handleSignals() {
	signals := make(chan os.Signal, 1)
	signal.Notify(signals, os.Interrupt, syscall.SIGTERM)
	signal.Notify(signals, os.Interrupt, syscall.SIGUSR1)
	go func() {
		sig := <-signals
		switch sig {
		case syscall.SIGTERM, syscall.SIGINT:
			//Exit gracefully
			glog.Info("Shutting down...")
			os.Exit(0)
		case syscall.SIGUSR1:
			pprof.Lookup("goroutine").WriteTo(os.Stdout, 1)
		}
	}()

}
<|endoftext|>


<commit_before>package main

import (
	"./pair"
	"bytes"
	"crypto/tls"
	"crypto/x509"
	"encoding/pem"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	_ "net/http/pprof"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"
	//        "net"
)

type debugger bool

func (d debugger) Printf(format string, args ...interface{}) {
	if d {
		log.Printf(format, args...)
	}
}

func (d debugger) Print(args ...interface{}) {
	if d {
		log.Print(args...)
	}
}

const debug debugger = false
const info debugger = true

var build string

func main() {
	hostname, _ := os.Hostname()
	var source = flag.String("source", hostname, "source (for reporting)")
	var interval = flag.Int("interval", 10, "stats interval (in seconds)")
	var timeout = flag.Int("timeout", 1000, "receive timeout (in ms)")
	var reg_addr = flag.String("registration", "tcp://127.0.0.1:5867", "address to which clients register")
	var log_output = flag.Bool("log_output", true, "log aggregated data")
	var librato_email = flag.String("librato_email", "", "librato email")
	var librato_token = flag.String("librato_token", "", "librato token")
	http_addr := flag.String("http", "127.0.0.1:8990", "HTTP debugging address (e.g. ':8990')")
	https_addr := flag.String("https", "0.0.0.0:8443", "HTTPS address (e.g. ':8443')")
	http_features_string := flag.String("features", "ws-json,http-json,sparkline", "HTTP features (ws-json,http-json,sparkline)")
	ssl_crt := flag.String("crt", "", "SSL Certificate")
	ssl_key := flag.String("key", "", "SSL Key")
	ssl_ca := flag.String("ca", "", "Client certificate CA (If left unspecified, client certificates are not used)")
	var showBuild = flag.Bool("build", false, "Print build information")
	flag.Parse()
	http_features := make(map[string]bool)
	for _, s := range strings.Split(*http_features_string, ",") {
		http_features[s] = true
	}
	if *ssl_crt == "" || *ssl_key == "" {
		*https_addr = ""
		info.Printf("[main] Either SSL crt (%v) and key (%v) left unspecified, disabling https interface", *ssl_crt, *ssl_key)
	}
	if *showBuild {
		if len(build) > 0 {
			fmt.Println(build)
		} else {
			fmt.Println("Build with `go build -ldflags \"-X main.build <info-string>\"` to include build information in binary")
		}
		os.Exit(0)
	}

	ts_complete := make(chan int64)
	ts_new := make(chan int64)

	ticker := NewTicker(*interval)

	aggregator := NewAggregator()
	go aggregator.Run(ts_complete, ts_new)

	client_manager := NewClientManager(aggregator)
	go client_manager.Run(ticker, *timeout, ts_complete, ts_new)

	pair_server := pair.NewServer(*reg_addr, pair.ServerDelegate(client_manager))
	go pair_server.Run()

	output := NewOutput()

	if len(*librato_email) > 0 && len(*librato_token) > 0 {
		librato := NewLibrato(*source, *librato_email, *librato_token)
		go librato.Run()
		output.Add(librato)
	}

	if *log_output {
		stdout := NewStdOut()
		output.Add(stdout)
	}
	if *http_addr != "" || *https_addr != "" {
		if _, ok := http_features["http-json"]; ok {
			log.Println("[main] Http json enabled at http://" + *http_addr + "/snapshot.json")
			snapshot := NewSnapshot()
			output.Add(snapshot)
			go func() {
				http.Handle("/snapshot.json", snapshot)
			}()
		}
		if _, ok := http_features["ws-json"]; ok {
			log.Println("[main] Websocket json enabled at ws://" + *http_addr + "/ws.json")
			websocketsender := NewWebsocketsender()
			output.Add(websocketsender)
			go func() {
				http.Handle("/ws.json", websocketsender.GetWebsocketSenderHandler())
			}()
		}
		if _, ok := http_features["sparkline"]; ok {
			log.Println("[main] Sparkline enabled at http://" + *http_addr + "/spark.html")
			js_data := []string{"/jquery.js", "/jquery.sparkline.js", "/jquery.appear.js", "/reconnecting-websocket.js"}

			for _, n := range js_data {
				js, _ := Asset("sparkline" + n)
				http.HandleFunc(n,
					func(w http.ResponseWriter, req *http.Request) {
						w.Header().Set("Content-Type", "application/javascript")
						http.ServeContent(w, req, n, time.Time{}, bytes.NewReader(js))
					})
			}
			hb, _ := Asset("sparkline/spark.html")
			http.HandleFunc("/spark",
				func(w http.ResponseWriter, req *http.Request) {
					w.Header().Set("Content-Type", "text/html")
					http.ServeContent(w, req, "spark", time.Time{}, bytes.NewReader(hb))
				})
		}
		if *http_addr != "" {
			go func() {
				info.Printf("[main] HTTP server running on %v", *http_addr)
				log.Println(http.ListenAndServe(*http_addr, nil))
			}()
		}
		if *https_addr != "" {
			cert, err := tls.LoadX509KeyPair(*ssl_crt, *ssl_key)
			if err != nil {
				log.Fatalf("[main] loading key/crt pair: %s", err)
			}
			cp := x509.NewCertPool()
			var request_cert tls.ClientAuthType
			if *ssl_ca != "" {
				ca_data, err := ioutil.ReadFile(*ssl_ca)
				if err != nil {
					log.Fatalf("[main] loading ca: %s", err)
				}
				ca_decoded, _ := pem.Decode(ca_data)
				x509cert, err := x509.ParseCertificate(ca_decoded.Bytes)
				if err != nil {
					log.Fatalf("[main] ca not x509?, %s", err)
				}
				cp.AddCert(x509cert)
				request_cert = tls.RequireAndVerifyClientCert
			} else {
				request_cert = tls.NoClientCert
				log.Println("[main] WARNING: No client certificate specified, disabling authentication")
			}
			config := tls.Config{
				Certificates:       []tls.Certificate{cert},
				ClientAuth:         request_cert,
				RootCAs:            cp,
				ClientCAs:          cp,
				InsecureSkipVerify: true, //Don't check hostname of client certificate
				NextProtos:         []string{"http/1.1"},
				CipherSuites: []uint16{ // Work around chrome ssl certificate issue
					tls.TLS_RSA_WITH_RC4_128_SHA,
					tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
					tls.TLS_RSA_WITH_AES_128_CBC_SHA,
					tls.TLS_RSA_WITH_AES_256_CBC_SHA,
				},
			}
			srv := http.Server{
				Addr:      *https_addr,
				TLSConfig: &config,
			}
			go func() {
				info.Printf("[main] HTTPS server running on %v", *https_addr)
				log.Println(srv.ListenAndServeTLS(*ssl_crt, *ssl_key))
			}()
		}
	}

	go output.Run(aggregator.output)

	info.Printf("[main] Stagger running")

	// Handle termination
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, syscall.SIGTERM)
	<-c
	pair_server.Shutdown()
	info.Print("[main] Exiting cleanly")
}
<commit_msg>Redirect / to sparkline for now<commit_after>package main

import (
	"./pair"
	"bytes"
	"crypto/tls"
	"crypto/x509"
	"encoding/pem"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	_ "net/http/pprof"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"
	//        "net"
)

type debugger bool

func (d debugger) Printf(format string, args ...interface{}) {
	if d {
		log.Printf(format, args...)
	}
}

func (d debugger) Print(args ...interface{}) {
	if d {
		log.Print(args...)
	}
}

const debug debugger = false
const info debugger = true

var build string

func main() {
	hostname, _ := os.Hostname()
	var source = flag.String("source", hostname, "source (for reporting)")
	var interval = flag.Int("interval", 10, "stats interval (in seconds)")
	var timeout = flag.Int("timeout", 1000, "receive timeout (in ms)")
	var reg_addr = flag.String("registration", "tcp://127.0.0.1:5867", "address to which clients register")
	var log_output = flag.Bool("log_output", true, "log aggregated data")
	var librato_email = flag.String("librato_email", "", "librato email")
	var librato_token = flag.String("librato_token", "", "librato token")
	http_addr := flag.String("http", "127.0.0.1:8990", "HTTP debugging address (e.g. ':8990')")
	https_addr := flag.String("https", "0.0.0.0:8443", "HTTPS address (e.g. ':8443')")
	http_features_string := flag.String("features", "ws-json,http-json,sparkline", "HTTP features (ws-json,http-json,sparkline)")
	ssl_crt := flag.String("crt", "", "SSL Certificate")
	ssl_key := flag.String("key", "", "SSL Key")
	ssl_ca := flag.String("ca", "", "Client certificate CA (If left unspecified, client certificates are not used)")
	var showBuild = flag.Bool("build", false, "Print build information")
	flag.Parse()
	http_features := make(map[string]bool)
	for _, s := range strings.Split(*http_features_string, ",") {
		http_features[s] = true
	}
	if *ssl_crt == "" || *ssl_key == "" {
		*https_addr = ""
		info.Printf("[main] Either SSL crt (%v) and key (%v) left unspecified, disabling https interface", *ssl_crt, *ssl_key)
	}
	if *showBuild {
		if len(build) > 0 {
			fmt.Println(build)
		} else {
			fmt.Println("Build with `go build -ldflags \"-X main.build <info-string>\"` to include build information in binary")
		}
		os.Exit(0)
	}

	ts_complete := make(chan int64)
	ts_new := make(chan int64)

	ticker := NewTicker(*interval)

	aggregator := NewAggregator()
	go aggregator.Run(ts_complete, ts_new)

	client_manager := NewClientManager(aggregator)
	go client_manager.Run(ticker, *timeout, ts_complete, ts_new)

	pair_server := pair.NewServer(*reg_addr, pair.ServerDelegate(client_manager))
	go pair_server.Run()

	output := NewOutput()

	if len(*librato_email) > 0 && len(*librato_token) > 0 {
		librato := NewLibrato(*source, *librato_email, *librato_token)
		go librato.Run()
		output.Add(librato)
	}

	if *log_output {
		stdout := NewStdOut()
		output.Add(stdout)
	}
	if *http_addr != "" || *https_addr != "" {
		if _, ok := http_features["http-json"]; ok {
			log.Println("[main] Http json enabled at http://" + *http_addr + "/snapshot.json")
			snapshot := NewSnapshot()
			output.Add(snapshot)
			go func() {
				http.Handle("/snapshot.json", snapshot)
			}()
		}
		if _, ok := http_features["ws-json"]; ok {
			log.Println("[main] Websocket json enabled at ws://" + *http_addr + "/ws.json")
			websocketsender := NewWebsocketsender()
			output.Add(websocketsender)
			go func() {
				http.Handle("/ws.json", websocketsender.GetWebsocketSenderHandler())
			}()
		}
		if _, ok := http_features["sparkline"]; ok {
			log.Println("[main] Sparkline enabled at http://" + *http_addr + "/spark.html")
			js_data := []string{"/jquery.js", "/jquery.sparkline.js", "/jquery.appear.js", "/reconnecting-websocket.js"}

			for _, n := range js_data {
				js, _ := Asset("sparkline" + n)
				http.HandleFunc(n,
					func(w http.ResponseWriter, req *http.Request) {
						w.Header().Set("Content-Type", "application/javascript")
						http.ServeContent(w, req, n, time.Time{}, bytes.NewReader(js))
					})
			}
			hb, _ := Asset("sparkline/spark.html")
			http.HandleFunc("/spark",
				func(w http.ResponseWriter, req *http.Request) {
					w.Header().Set("Content-Type", "text/html")
					http.ServeContent(w, req, "spark", time.Time{}, bytes.NewReader(hb))
				})
			http.HandleFunc("/",
				func(w http.ResponseWriter, req *http.Request) {
					if req.URL.Path != "/" {
						http.NotFound(w, req)
						return
					}
					http.Redirect(w, req, "/spark", http.StatusFound)
				})

		}
		if *http_addr != "" {
			go func() {
				info.Printf("[main] HTTP server running on %v", *http_addr)
				log.Println(http.ListenAndServe(*http_addr, nil))
			}()
		}
		if *https_addr != "" {
			cert, err := tls.LoadX509KeyPair(*ssl_crt, *ssl_key)
			if err != nil {
				log.Fatalf("[main] loading key/crt pair: %s", err)
			}
			cp := x509.NewCertPool()
			var request_cert tls.ClientAuthType
			if *ssl_ca != "" {
				ca_data, err := ioutil.ReadFile(*ssl_ca)
				if err != nil {
					log.Fatalf("[main] loading ca: %s", err)
				}
				ca_decoded, _ := pem.Decode(ca_data)
				x509cert, err := x509.ParseCertificate(ca_decoded.Bytes)
				if err != nil {
					log.Fatalf("[main] ca not x509?, %s", err)
				}
				cp.AddCert(x509cert)
				request_cert = tls.RequireAndVerifyClientCert
			} else {
				request_cert = tls.NoClientCert
				log.Println("[main] WARNING: No client certificate specified, disabling authentication")
			}
			config := tls.Config{
				Certificates:       []tls.Certificate{cert},
				ClientAuth:         request_cert,
				RootCAs:            cp,
				ClientCAs:          cp,
				InsecureSkipVerify: true, //Don't check hostname of client certificate
				NextProtos:         []string{"http/1.1"},
				CipherSuites: []uint16{ // Work around chrome ssl certificate issue
					tls.TLS_RSA_WITH_RC4_128_SHA,
					tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
					tls.TLS_RSA_WITH_AES_128_CBC_SHA,
					tls.TLS_RSA_WITH_AES_256_CBC_SHA,
				},
			}
			srv := http.Server{
				Addr:      *https_addr,
				TLSConfig: &config,
			}
			go func() {
				info.Printf("[main] HTTPS server running on %v", *https_addr)
				log.Println(srv.ListenAndServeTLS(*ssl_crt, *ssl_key))
			}()
		}
	}

	go output.Run(aggregator.output)

	info.Printf("[main] Stagger running")

	// Handle termination
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, syscall.SIGTERM)
	<-c
	pair_server.Shutdown()
	info.Print("[main] Exiting cleanly")
}
<|endoftext|>


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

package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"net/http"
	"strings"
	"sync"
	"time"

	"github.com/prometheus/client_golang/prometheus"
)

type collectdMetric struct {
	Values         []float64
	Dstypes        []string
	Dsnames        []string
	Time           float64
	Interval       float64
	Host           string
	Plugin         string
	PluginInstance string `json:"plugin_instance"`
	Type           string
	TypeInstance   string `json:"type_instance"`
}

var (
	addr     = flag.String("listen-address", ":6060", "The address to listen on for HTTP requests.")
	lastPush = prometheus.NewGauge(
		prometheus.GaugeOpts{
			Name: "collectd_last_push",
			Help: "Unixtime the collectd exporter was last pushed to.",
		},
	)
)

func metricName(m collectdMetric, dstype string, dsname string) string {
	result := "collectd"
	if m.Plugin != m.Type && !strings.HasPrefix(m.Type, m.Plugin+"_") {
		result += "_" + m.Plugin
	}
	result += "_" + m.Type
	if dsname != "value" {
		result += "_" + dsname
	}
	if dstype == "counter" {
		result += "_total"
	}
	return result
}

func metricHelp(m collectdMetric, dstype string, dsname string) string {
	return fmt.Sprintf("Collectd Metric Plugin: '%s' Type: '%s' Dstype: '%s' Dsname: '%s'",
		m.Plugin, m.Type, dstype, dsname)
}

type collectdSample struct {
	Name    string
	Labels  map[string]string
	Help    string
	Value   float64
	Gauge   bool
	Expires time.Time
}

type collectdSampleLabelset struct {
	Name           string
	Instance       string
	Type           string
	Plugin         string
	PluginInstance string
}

type CollectdCollector struct {
	samples map[collectdSampleLabelset]*collectdSample
	mu      *sync.Mutex
	ch      chan *collectdSample
}

func newCollectdCollector() *CollectdCollector {
	c := &CollectdCollector{
		ch:      make(chan *collectdSample, 0),
		mu:      &sync.Mutex{},
		samples: map[collectdSampleLabelset]*collectdSample{},
	}
	go c.processSamples()
	return c
}

func (c *CollectdCollector) collectdPost(w http.ResponseWriter, r *http.Request) {
	var postedMetrics []collectdMetric
	err := json.NewDecoder(r.Body).Decode(&postedMetrics)
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		return
	}
	now := time.Now()
	lastPush.Set(float64(now.UnixNano()) / 1e9)
	for _, metric := range postedMetrics {
		for i, value := range metric.Values {
			name := metricName(metric, metric.Dstypes[i], metric.Dsnames[i])
			help := metricHelp(metric, metric.Dstypes[i], metric.Dsnames[i])
			labels := prometheus.Labels{}
			if metric.PluginInstance != "" {
				labels[metric.Plugin] = metric.PluginInstance
			}
			if metric.TypeInstance != "" {
				if metric.PluginInstance == "" {
					labels[metric.Plugin] = metric.TypeInstance
				} else {
					labels["type"] = metric.TypeInstance
				}
			}
			labels["instance"] = metric.Host
			c.ch <- &collectdSample{
				Name:    name,
				Labels:  labels,
				Help:    help,
				Value:   value,
				Gauge:   metric.Dstypes[i] != "counter",
				Expires: now.Add(time.Duration(metric.Interval) * time.Second * 2),
			}
		}
	}
}

func (c *CollectdCollector) processSamples() {
	ticker := time.NewTicker(time.Minute).C
	for {
		select {
		case sample := <-c.ch:
			labelset := &collectdSampleLabelset{
				Name: sample.Name,
			}
			for k, v := range sample.Labels {
				switch k {
				case "instance":
					labelset.Instance = v
				case "type":
					labelset.Type = v
				default:
					labelset.Plugin = k
					labelset.PluginInstance = v
				}
			}
			c.mu.Lock()
			c.samples[*labelset] = sample
			c.mu.Unlock()
		case <-ticker:
			// Garbage collect expired samples.
			now := time.Now()
			c.mu.Lock()
			for k, sample := range c.samples {
				if now.After(sample.Expires) {
					delete(c.samples, k)
				}
			}
			c.mu.Unlock()
		}
	}
}

// Implements Collector.
func (c CollectdCollector) Collect(ch chan<- prometheus.Metric) {
	ch <- lastPush
	c.mu.Lock()
	samples := c.samples
	c.mu.Unlock()
	now := time.Now()
	for _, sample := range samples {
		if now.After(sample.Expires) {
			continue
		}
		if sample.Gauge {
			gauge := prometheus.NewGauge(
				prometheus.GaugeOpts{
					Name:        sample.Name,
					Help:        sample.Help,
					ConstLabels: sample.Labels})
			gauge.Set(sample.Value)
			ch <- gauge
		} else {
			counter := prometheus.NewCounter(
				prometheus.CounterOpts{
					Name:        sample.Name,
					Help:        sample.Help,
					ConstLabels: sample.Labels})
			counter.Set(sample.Value)
			ch <- counter
		}
	}
}

// Implements Collector.
func (c CollectdCollector) Describe(ch chan<- *prometheus.Desc) {
	ch <- lastPush.Desc()
}

func main() {
	flag.Parse()
	http.Handle("/metrics", prometheus.Handler())
	c := newCollectdCollector()
	http.HandleFunc("/collectd-post", c.collectdPost)
	prometheus.MustRegister(c)
	http.ListenAndServe(*addr, nil)
}
<commit_msg>Some metrics metadata cleanups.<commit_after>// Copyright 2015 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"net/http"
	"strings"
	"sync"
	"time"

	"github.com/prometheus/client_golang/prometheus"
)

type collectdMetric struct {
	Values         []float64
	Dstypes        []string
	Dsnames        []string
	Time           float64
	Interval       float64
	Host           string
	Plugin         string
	PluginInstance string `json:"plugin_instance"`
	Type           string
	TypeInstance   string `json:"type_instance"`
}

var (
	addr     = flag.String("listen-address", ":6060", "The address to listen on for HTTP requests.")
	lastPush = prometheus.NewGauge(
		prometheus.GaugeOpts{
			Name: "collectd_last_push_timestamp_seconds",
			Help: "Unix timestamp of the last received collectd metrics push in seconds.",
		},
	)
)

func metricName(m collectdMetric, dstype string, dsname string) string {
	result := "collectd"
	if m.Plugin != m.Type && !strings.HasPrefix(m.Type, m.Plugin+"_") {
		result += "_" + m.Plugin
	}
	result += "_" + m.Type
	if dsname != "value" {
		result += "_" + dsname
	}
	if dstype == "counter" {
		result += "_total"
	}
	return result
}

func metricHelp(m collectdMetric, dstype string, dsname string) string {
	return fmt.Sprintf("Collectd exporter: '%s' Type: '%s' Dstype: '%s' Dsname: '%s'",
		m.Plugin, m.Type, dstype, dsname)
}

type collectdSample struct {
	Name    string
	Labels  map[string]string
	Help    string
	Value   float64
	Gauge   bool
	Expires time.Time
}

type collectdSampleLabelset struct {
	Name           string
	Instance       string
	Type           string
	Plugin         string
	PluginInstance string
}

type CollectdCollector struct {
	samples map[collectdSampleLabelset]*collectdSample
	mu      *sync.Mutex
	ch      chan *collectdSample
}

func newCollectdCollector() *CollectdCollector {
	c := &CollectdCollector{
		ch:      make(chan *collectdSample, 0),
		mu:      &sync.Mutex{},
		samples: map[collectdSampleLabelset]*collectdSample{},
	}
	go c.processSamples()
	return c
}

func (c *CollectdCollector) collectdPost(w http.ResponseWriter, r *http.Request) {
	var postedMetrics []collectdMetric
	err := json.NewDecoder(r.Body).Decode(&postedMetrics)
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		return
	}
	now := time.Now()
	lastPush.Set(float64(now.UnixNano()) / 1e9)
	for _, metric := range postedMetrics {
		for i, value := range metric.Values {
			name := metricName(metric, metric.Dstypes[i], metric.Dsnames[i])
			help := metricHelp(metric, metric.Dstypes[i], metric.Dsnames[i])
			labels := prometheus.Labels{}
			if metric.PluginInstance != "" {
				labels[metric.Plugin] = metric.PluginInstance
			}
			if metric.TypeInstance != "" {
				if metric.PluginInstance == "" {
					labels[metric.Plugin] = metric.TypeInstance
				} else {
					labels["type"] = metric.TypeInstance
				}
			}
			labels["instance"] = metric.Host
			c.ch <- &collectdSample{
				Name:    name,
				Labels:  labels,
				Help:    help,
				Value:   value,
				Gauge:   metric.Dstypes[i] != "counter",
				Expires: now.Add(time.Duration(metric.Interval) * time.Second * 2),
			}
		}
	}
}

func (c *CollectdCollector) processSamples() {
	ticker := time.NewTicker(time.Minute).C
	for {
		select {
		case sample := <-c.ch:
			labelset := &collectdSampleLabelset{
				Name: sample.Name,
			}
			for k, v := range sample.Labels {
				switch k {
				case "instance":
					labelset.Instance = v
				case "type":
					labelset.Type = v
				default:
					labelset.Plugin = k
					labelset.PluginInstance = v
				}
			}
			c.mu.Lock()
			c.samples[*labelset] = sample
			c.mu.Unlock()
		case <-ticker:
			// Garbage collect expired samples.
			now := time.Now()
			c.mu.Lock()
			for k, sample := range c.samples {
				if now.After(sample.Expires) {
					delete(c.samples, k)
				}
			}
			c.mu.Unlock()
		}
	}
}

// Implements Collector.
func (c CollectdCollector) Collect(ch chan<- prometheus.Metric) {
	ch <- lastPush
	c.mu.Lock()
	samples := c.samples
	c.mu.Unlock()
	now := time.Now()
	for _, sample := range samples {
		if now.After(sample.Expires) {
			continue
		}
		if sample.Gauge {
			gauge := prometheus.NewGauge(
				prometheus.GaugeOpts{
					Name:        sample.Name,
					Help:        sample.Help,
					ConstLabels: sample.Labels})
			gauge.Set(sample.Value)
			ch <- gauge
		} else {
			counter := prometheus.NewCounter(
				prometheus.CounterOpts{
					Name:        sample.Name,
					Help:        sample.Help,
					ConstLabels: sample.Labels})
			counter.Set(sample.Value)
			ch <- counter
		}
	}
}

// Implements Collector.
func (c CollectdCollector) Describe(ch chan<- *prometheus.Desc) {
	ch <- lastPush.Desc()
}

func main() {
	flag.Parse()
	http.Handle("/metrics", prometheus.Handler())
	c := newCollectdCollector()
	http.HandleFunc("/collectd-post", c.collectdPost)
	prometheus.MustRegister(c)
	http.ListenAndServe(*addr, nil)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	auth "github.com/abbot/go-http-auth"
	"net/http"
	"os"
)

func Secret(user, realm string) string {
	if user == os.Getenv("login") {
		return os.Getenv("password")
	}
	return ""
}

func handle(w http.ResponseWriter, r *auth.AuthenticatedRequest) {
	fmt.Fprintf(w, "Welcome, %s!", r.Username)
}

func main() {
	authenticator := auth.NewBasicAuthenticator("aws-remote.herokuapp.com", Secret)
	http.HandleFunc("/", authenticator.Wrap(handle))
	http.ListenAndServe(":"+os.Getenv("PORT"), nil)
}
<commit_msg>Rewrite import path<commit_after>package main

import (
	"fmt"
	auth "github.com/swapagarwal/aws-remote/Godeps/_workspace/src/github.com/abbot/go-http-auth"
	"net/http"
	"os"
)

func Secret(user, realm string) string {
	if user == os.Getenv("login") {
		return os.Getenv("password")
	}
	return ""
}

func handle(w http.ResponseWriter, r *auth.AuthenticatedRequest) {
	fmt.Fprintf(w, "Welcome, %s!", r.Username)
}

func main() {
	authenticator := auth.NewBasicAuthenticator("aws-remote.herokuapp.com", Secret)
	http.HandleFunc("/", authenticator.Wrap(handle))
	http.ListenAndServe(":"+os.Getenv("PORT"), nil)
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"crypto/rand"
	"encoding/xml"
	"fmt"
	"io"
	"log"
	"net"
	"net/http"
	"os"
	"syscall"
	"time"
)

const (
	serverField   = "Linux/3.4 UPnP/1.1 DMS/1.0"
	ssdpMcastAddr = "239.255.255.250:1900"
	httpPort      = "1337"
	rootDeviceType = "urn:schemas-upnp-org:device:MediaServer:1"
)

func makeDeviceUuid() string {
	buf := make([]byte, 16)
	if _, err := io.ReadFull(rand.Reader, buf); err != nil {
		panic(err)
	}
	return fmt.Sprintf("uuid:%x-%x-%x-%x-%x", buf[:4], buf[4:6], buf[6:8], buf[8:10], buf[10:])
}

type server struct {
	uuid       string
	xmlDesc    []byte
	ssdpConn   *net.UDPConn
	ssdpAddr   *net.UDPAddr
	http       *http.Server
	ssdpLogger *log.Logger
}

type specVersion struct {
	Major int
	Minor int
}

type icon struct {
	Mimetype, Width, Height, Depth, URL string
}

type service struct {
	ServiceType, ServiceId, SCPDURL, ControlURL, EventSubURL string
}

type device struct {
	DeviceType, FriendlyName, Manufacturer, ModelName, UDN string
	IconList []icon
	ServiceList []service
}

var services = []service{
	service{
		ServiceType: "urn:schemas-upnp-org:service:ContentDirectory:1",
		ServiceId: "urn:upnp-org:serviceId:ContentDirectory",
		SCPDURL: "/scpd/ContentDirectory.xml",
		ControlURL: "/ctl/ContentDirectory",
		EventSubURL: "/evt/ContentDirectory",
	},
}

type root struct {
	Device device
	SpecVersion specVersion
}

func respondToSSDP(conn *net.UDPConn, lgr *log.Logger) {
	for {
		b := make([]byte, 4096)
		n, addr, err := conn.ReadFromUDP(b)
		lgr.Println("received ssdp:", n, addr, err, string(b))
	}
}

func usnFromTarget(target, uuid string) string {
	if target == uuid {
		return target
	}
	return uuid + "::" + target
}

func (me *server) notifyAlive() {
	conn := me.ssdpConn
	uuid := me.uuid
	logger := me.ssdpLogger
	for {
		for _, target := range me.targets() {
			lines := [...][2]string{
				{"HOST", ssdpMcastAddr},
				{"CACHE-CONTROL", "max-age = 30"},
				{"LOCATION", "http://192.168.26.2:" + httpPort + "/rootDesc.xml"},
				{"NT", target},
				{"NTS", "ssdp:alive"},
				{"SERVER", serverField},
				{"USN", usnFromTarget(target, uuid)},
			}
			buf := &bytes.Buffer{}
			fmt.Fprint(buf, "NOTIFY * HTTP/1.1\r\n")
			for _, pair := range lines {
				fmt.Fprintf(buf, "%s: %s\r\n", pair[0], pair[1])
			}
			fmt.Fprint(buf, "\r\n")
			n, err := conn.WriteToUDP(buf.Bytes(), me.ssdpAddr)
			logger.Println("sending", string(buf.Bytes()))
			if err != nil {
				panic(err)
			}
			if n != buf.Len() {
				panic(fmt.Sprintf("sent %d < %d bytes", n, buf.Len()))
			}
		}
		time.Sleep(time.Second)
	}
}

func (me *server) targets() (ret []string) {
	ret = append([]string{
		"upnp:rootdevice",
		"urn:schemas-upnp-org:device:MediaServer:1",
	}, me.uuid)
	return
}

func main() {
	s := server{
		uuid: makeDeviceUuid(),
	}
	ssdpLogFile, err := os.Create("ssdp.log")
	if err != nil {
		log.Fatalln(err)
	}
	s.ssdpLogger = log.New(ssdpLogFile, "", log.Flags())
	s.xmlDesc, err = xml.MarshalIndent(root{Device: device{UDN: s.uuid, ServiceList:services}}, " ", "  ")
	if err != nil {
		panic(err)
	}
	log.Println("device description:", string(s.xmlDesc))
	go func() {
		if err := http.ListenAndServe(":"+httpPort, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			log.Println("got http request:", r)
			http.NotFound(w, r)
		})); err != nil {
			log.Fatalln(err)
		}
	}()
	s.ssdpAddr, err = net.ResolveUDPAddr("udp4", "239.255.255.250:1900")
	if err != nil {
		panic(err)
	}
	s.ssdpConn, err = net.ListenMulticastUDP("udp4", nil, s.ssdpAddr)
	if err != nil {
		panic(err)
	}
	f, _ := s.ssdpConn.File()
	syscall.SetsockoptInt(int(f.Fd()), syscall.IPPROTO_IP, syscall.IP_MULTICAST_TTL, 4)
	f.Close()
	go s.notifyAlive()
	respondToSSDP(s.ssdpConn, s.ssdpLogger)
}
<commit_msg>SSDP notifies, and the root description are now functioning.<commit_after>package main

import (
	"bytes"
	"crypto/rand"
	"encoding/xml"
	"fmt"
	"io"
	"log"
	"net"
	"net/http"
	"os"
	"os/user"
	"syscall"
	"time"
)

const (
	serverField         = "Linux/3.4 UPnP/1.1 DMS/1.0"
	rootDeviceType      = "urn:schemas-upnp-org:device:MediaServer:1"
	rootDeviceModelName = "dms 1.0"
)

func makeDeviceUuid() string {
	buf := make([]byte, 16)
	if _, err := io.ReadFull(rand.Reader, buf); err != nil {
		panic(err)
	}
	return fmt.Sprintf("uuid:%x-%x-%x-%x-%x", buf[:4], buf[4:6], buf[6:8], buf[8:10], buf[10:])
}

type specVersion struct {
	Major int `xml:"major"`
	Minor int `xml:"minor"`
}

type icon struct {
	Mimetype, Width, Height, Depth, URL string
}

type service struct {
	XMLName xml.Name `xml:"service"`
	ServiceType string `xml:"serviceType"`
	ServiceId string `xml:"serviceId"`
	SCPDURL string
	ControlURL string `xml:"controlURL"`
	EventSubURL string `xml:"eventSubURL"`
}

type device struct {
	DeviceType   string `xml:"deviceType"`
	FriendlyName string `xml:"friendlyName"`
	Manufacturer string `xml:"manufacturer"`
	ModelName    string `xml:"modelName"`
	UDN          string
	IconList     []icon
	ServiceList  []service `xml:"serviceList>service"`
}

var services = []service{
	service{
		ServiceType: "urn:schemas-upnp-org:service:ContentDirectory:1",
		ServiceId:   "urn:upnp-org:serviceId:ContentDirectory",
		SCPDURL:     "/scpd/ContentDirectory.xml",
		ControlURL:  "/ctl/ContentDirectory",
		EventSubURL: "/evt/ContentDirectory",
	},
}

type root struct {
	XMLName     xml.Name    `xml:"urn:schemas-upnp-org:device-1-0 root"`
	ConfigId    uint        `xml:"configId,attr"`
	SpecVersion specVersion `xml:"specVersion"`
	Device      device      `xml:"device"`
}

func usnFromTarget(target string) string {
	if target == rootDeviceUUID {
		return target
	}
	return rootDeviceUUID + "::" + target
}

func targets() []string {
	return append([]string{
		"upnp:rootdevice",
		"urn:schemas-upnp-org:device:MediaServer:1",
		"urn:schemas-upnp-org:service:ContentDirectory:1",
	}, rootDeviceUUID)
}

func httpPort() int {
	return httpConn.Addr().(*net.TCPAddr).Port
}

func makeNotifyMessage(locHost net.IP, target, nts string) []byte {
	lines := [...][2]string{
		{"HOST", ssdpAddr.String()},
		{"CACHE-CONTROL", "max-age = 30"},
		{"LOCATION", fmt.Sprintf("http://%s:%d/rootDesc.xml", locHost.String(), httpPort())},
		{"NT", target},
		{"NTS", nts},
		{"SERVER", serverField},
		{"USN", usnFromTarget(target)},
	}
	buf := &bytes.Buffer{}
	fmt.Fprint(buf, "NOTIFY * HTTP/1.1\r\n")
	for _, pair := range lines {
		fmt.Fprintf(buf, "%s: %s\r\n", pair[0], pair[1])
	}
	fmt.Fprint(buf, "\r\n")
	return buf.Bytes()
}

func notifyAlive(conn *net.UDPConn, host net.IP) {
	for _, target := range targets() {
		data := makeNotifyMessage(host, target, "ssdp:alive")
		n, err := conn.WriteToUDP(data, ssdpAddr)
		ssdpLogger.Println("sending", string(data))
		if err != nil {
			panic(err)
		}
		if n != len(data) {
			panic(fmt.Sprintf("sent %d < %d bytes", n, len(data)))
		}
	}
}

func serveHTTP() {
	srv := &http.Server{
		Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			log.Println("got http request:", r)
			http.DefaultServeMux.ServeHTTP(w, r)
		}),
	}
	if err := srv.Serve(httpConn); err != nil {
		panic(err)
	}
	panic(nil)
}

func sSDPInterface(if_ net.Interface) {
	conn, err := net.ListenMulticastUDP("udp4", &if_, ssdpAddr)
	if err != nil {
		panic(err)
	}
	defer conn.Close()
	f, err := conn.File()
	if err != nil {
		panic(err)
	}
	fd := int(f.Fd())
	if err := syscall.SetsockoptInt(fd, syscall.SOL_IP, syscall.IP_MULTICAST_TTL, 4); err != nil {
		panic(err)
	}
	f.Close()
	for {
		addrs, err := if_.Addrs()
		if err != nil {
			panic(err)
		}
		for _, addr := range addrs {
			addr4 := addr.(*net.IPNet).IP.To4()
			if addr4 == nil {
				continue
			}
			log.Println(addr)
			notifyAlive(conn, addr4)
		}
		time.Sleep(time.Second)
	}
}

func doSSDP() {
	active := map[int]bool{}
	for {
		ifs, err := net.Interfaces()
		if err != nil {
			panic(err)
		}
		for _, if_ := range ifs {
			if active[if_.Index] {
				continue
			}
			active[if_.Index] = true
			go sSDPInterface(if_)
		}
		time.Sleep(time.Second)
	}
}

var (
	rootDeviceUUID string
	httpConn       *net.TCPListener
	ssdpAddr       *net.UDPAddr
	ssdpLogger     *log.Logger
	rootDescXML    []byte
)

func main() {
	rootDeviceUUID = makeDeviceUuid()
	var err error
	rootDescXML, err = xml.MarshalIndent(
		root{
			SpecVersion: specVersion{Major: 1, Minor: 0},
			Device: device{
				DeviceType: rootDeviceType,
				FriendlyName: fmt.Sprintf("%s: %s on %s", rootDeviceModelName, func() string {
					user, err := user.Current()
					if err != nil {
						panic(err)
					}
					return user.Name
				}(),
					func() string {
						name, err := os.Hostname()
						if err != nil {
							panic(err)
						}
						return name
					}()),
				Manufacturer: "Matt Joiner <anacrolix@gmail.com>",
				ModelName:    rootDeviceModelName,
				UDN:          rootDeviceUUID,
				ServiceList:  services,
			},
		},
		" ", "  ")
	if err != nil {
		panic(err)
	}
	rootDescXML = append([]byte(`<?xml version="1.0"?>`), rootDescXML...)
	log.Println(string(rootDescXML))
	ssdpAddr, err = net.ResolveUDPAddr("udp4", "239.255.255.250:1900")
	if err != nil {
		panic(err)
	}
	httpConn, err = net.ListenTCP("tcp", &net.TCPAddr{})
	if err != nil {
		panic(err)
	}
	defer httpConn.Close()
	log.Println("HTTP server on", httpConn.Addr())
	logFile, err := os.Create("ssdp.log")
	if err != nil {
		panic(err)
	}
	defer logFile.Close()
	ssdpLogger = log.New(logFile, "", log.Ltime|log.Lmicroseconds)
	http.HandleFunc("/rootDesc.xml", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("content-type", `text/xml; charset="utf-8"`)
		w.Header().Set("content-length", fmt.Sprint(len(rootDescXML)))
		w.Write(rootDescXML)
	})
	go serveHTTP()
	doSSDP()
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"time"
	"github.com/limetext/log4go"
	"github.com/micro/go-micro"
	// TODO SEEDMS fix imports after renaming project root folder
	// (replace all "github.com/tomogoma/seedms" refs with new path)
	"github.com/tomogoma/seedms/server"
	"github.com/tomogoma/seedms/server/proto"
	"github.com/tomogoma/go-commons/auth/token"
	confhelper "github.com/tomogoma/go-commons/config"
	"github.com/tomogoma/seedms/config"
	"runtime"
	"fmt"
)

const (
	// TODO SEEDMS change the name of the micro-service to a desired value
	// (preferably the same as the NAME value in install/systemd-install.sh)
	name = "seedms"
	version = "0.1.0"
	confCommand = "conf"
	defaultConfFile = "/etc/" + name + "/" + name + ".conf.yaml"
)

type Logger interface {
	Fine(interface{}, ...interface{})
	Info(interface{}, ...interface{})
	Warn(interface{}, ...interface{}) error
	Error(interface{}, ...interface{}) error
}

var confFilePath = flag.String(confCommand, defaultConfFile, "path to config file")

func main() {
	flag.Parse();
	defer func() {
		runtime.Gosched()
		time.Sleep(50 * time.Millisecond)
	}()
	conf := config.Config{}
	log := log4go.NewDefaultLogger(log4go.FINEST)
	err := confhelper.ReadYamlConfig(*confFilePath, &conf)
	if err != nil {
		log.Critical("Error reading config file: %s", err)
		return
	}
	err = bootstrap(log, conf)
	log.Critical(err)
}

// bootstrap collects all the dependencies necessary to start the server,
// injects said dependencies, and proceeds to register it as a micro grpc handler.
func bootstrap(log Logger, conf config.Config) error {
	tv, err := token.NewGenerator(conf.Auth)
	if err != nil {
		return fmt.Errorf("Error instantiating token validator: %s", err)
	}
	srv, err := server.New(name, tv, log);
	if err != nil {
		return fmt.Errorf("Error instantiating server: %s", err)
	}
	service := micro.NewService(
		micro.Name(name),
		micro.Version(version),
		micro.RegisterInterval(conf.Service.RegisterInterval),
	)
	// TODO SEEDMS modify this to match .proto file specification
	seed.RegisterSeedHandler(service.Server(), srv)
	if err := service.Run(); err != nil {
		return fmt.Errorf("Error serving: %s", err)
	}
	return nil
}
<commit_msg>use use "go.micro.web." name prefix to enable standard access<commit_after>package main

import (
	"flag"
	"time"
	"github.com/limetext/log4go"
	"github.com/micro/go-micro"
	// TODO SEEDMS fix imports after renaming project root folder
	// (replace all "github.com/tomogoma/seedms" refs with new path)
	"github.com/tomogoma/seedms/server"
	"github.com/tomogoma/seedms/server/proto"
	"github.com/tomogoma/go-commons/auth/token"
	confhelper "github.com/tomogoma/go-commons/config"
	"github.com/tomogoma/seedms/config"
	"runtime"
	"fmt"
)

const (
	// TODO SEEDMS change the name of the micro-service to a desired value
	// (preferably the same as the NAME value in install/systemd-install.sh)
	name = "seedms"
	id = "go.micro.web." + name
	version = "0.1.0"
	confCommand = "conf"
	defaultConfFile = "/etc/" + name + "/" + name + ".conf.yaml"
)

type Logger interface {
	Fine(interface{}, ...interface{})
	Info(interface{}, ...interface{})
	Warn(interface{}, ...interface{}) error
	Error(interface{}, ...interface{}) error
}

var confFilePath = flag.String(confCommand, defaultConfFile, "path to config file")

func main() {
	flag.Parse();
	defer func() {
		runtime.Gosched()
		time.Sleep(50 * time.Millisecond)
	}()
	conf := config.Config{}
	log := log4go.NewDefaultLogger(log4go.FINEST)
	err := confhelper.ReadYamlConfig(*confFilePath, &conf)
	if err != nil {
		log.Critical("Error reading config file: %s", err)
		return
	}
	err = bootstrap(log, conf)
	log.Critical(err)
}

// bootstrap collects all the dependencies necessary to start the server,
// injects said dependencies, and proceeds to register it as a micro grpc handler.
func bootstrap(log Logger, conf config.Config) error {
	tv, err := token.NewGenerator(conf.Auth)
	if err != nil {
		return fmt.Errorf("Error instantiating token validator: %s", err)
	}
	srv, err := server.New(id, tv, log);
	if err != nil {
		return fmt.Errorf("Error instantiating server: %s", err)
	}
	service := micro.NewService(
		micro.Name(id),
		micro.Version(version),
		micro.RegisterInterval(conf.Service.RegisterInterval),
	)
	// TODO SEEDMS modify this to match .proto file specification
	seed.RegisterSeedHandler(service.Server(), srv)
	if err := service.Run(); err != nil {
		return fmt.Errorf("Error serving: %s", err)
	}
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"encoding/binary"
	"errors"
	"flag"
	"fmt"
	"github.com/coreos/etcd/store"
	"github.com/coreos/go-etcd/etcd"
	"github.com/stathat/consistent"
	"net"
	"os"
	"strconv"
	"strings"
	"sync"
)

const (
	BufferLength     = 1024
	Magic            = 0x80
	BinaryHeaderSize = 24
)

var rwLock sync.RWMutex

var c *consistent.Consistent
var etcdClient *etcd.Client

var port int

func init() {
	flag.IntVar(&port, "p", 22122, "the port of the ds-memcached proxy")
}

func main() {

	flag.Parse()

	c = consistent.New()

	etcdClient = etcd.NewClient()

	etcdClient.SyncCluster()

	presps, err := etcdClient.Get("/service/memcached")

	if err != nil {
		fmt.Println("Add at least one memcached instance under path")
		os.Exit(1)
	}

	for _, resp := range presps {
		debugln("Add server ", resp.Value)
		c.Add(resp.Value)
	}

	go watch()

	startProxy()
}

func watch() {
	receiver := make(chan *store.Response, 10)
	stop := make(chan bool, 1)
	go update(receiver)
	etcdClient.Watch("/service/memcached", 0, receiver, stop)
}

func update(receiver chan *store.Response) {
	for {
		resp := <-receiver
		switch resp.Action {
		case "SET":
			// do nothing if the old server is the same as the new one
			if resp.PrevValue == resp.Value {
				debugln("Doing nothing; new server is the same as old one:", resp.Value)
				continue
			}
			// check if we're adding a new server or updating an old one
			if resp.PrevValue == "" {
				debugln("Adding server:", resp.Value)
				c.Add(resp.Value)
			} else {
				debugln("Replacing server:", resp.PrevValue, "with", resp.Value)
				c.Remove(resp.PrevValue)
				c.Add(resp.Value)
			}
		case "DELETE":
			if resp.PrevValue != "" {
				debugln("Removing server:", resp.PrevValue)
				c.Remove(resp.PrevValue)
			}
		}
	}
}

func dispatch(key string) string {
	//do load balance
	server, _ := c.Get(key)

	debugln("map", key, "to server ", server)

	return server
}

func startProxy() {

	listener, err := net.Listen("tcp", "0.0.0.0:"+strconv.Itoa(port))

	if err != nil {
		fmt.Println("error listening:", err.Error())
		os.Exit(1)
	}

	debugln("Start listening on port", port)

	for {
		conn, err := listener.Accept()
		if err != nil {
			warnln("Error accept:", err.Error())
			return
		}
		go serve(conn)
	}

}

func serve(conn net.Conn) {
	clientAddr := conn.RemoteAddr().String()

	debugln("accept client ", clientAddr)
	for {
		buf := make([]byte, BufferLength)
		n, err := conn.Read(buf)

		if err != nil {
			return
		}

		debugln("received ", n, " bytes of data from [", clientAddr, "]")

		if buf[0] == Magic {
			err = serveBinary(conn, buf)
		} else {
			err = serveText(conn, buf)
		}

		if err != nil {
			conn.Write([]byte(err.Error()))
			conn.Close()
			return
		}

	}

}

func serveText(conn net.Conn, buf []byte) error {
	clientAddr := conn.RemoteAddr().String()

	debugln("received text protocol from ", clientAddr)
	content := string(buf)

	index := strings.Index(content, "\r\n")

	if index == -1 {
		debugln("[text protocol] bad request from ", clientAddr)
		return errors.New("ERROR\r\n")
	}

	header := content[0:index]

	debugln("[text protocol] header from ", clientAddr)

	fields := strings.Split(header, " ")

	op := fields[0]

	var err error

	if textCommands[op] {
		// all the ops in the command list should be like
		// [op] [key] ...
		// we only need to grab the key to do hashing
		// proxy does not care about other stuffs

		if len(fields) < 2 {
			// bad request if there is no key
			return errors.New("ERROR\r\n")
		}

		key := fields[1]

		err = serveCommands(conn, key, buf)

		return err

	} else if op == "stats" {

		serveStat(conn, buf)

	} else {

		return errors.New("Unimplemented\r\n")
	}

	return err
}

func serveBinary(conn net.Conn, buf []byte) error {
	clientAddr := conn.RemoteAddr().String()

	debugln("received binary protocol from ", clientAddr)

	bufLength := len(buf)

	if bufLength < BinaryHeaderSize {
		return errors.New("ERROR\r\n")
	}

	op := buf[1]

	var err error

	if binaryCommands[op] {
		var keyLength uint16

		keyLengthBuf := bytes.NewBuffer(buf[2:4])
		err := binary.Read(keyLengthBuf, binary.BigEndian, &keyLength)

		if err != nil {
			return errors.New("ERROR\r\n")
		}

		key := string(buf[BinaryHeaderSize : BinaryHeaderSize+keyLength])

		err = serveCommands(conn, key, buf)
	}
	return err
}

func serveCommands(conn net.Conn, key string, buf []byte) error {
	clientAddr := conn.RemoteAddr().String()

	recv_buf := make([]byte, BufferLength)

	server := dispatch(key)

	memcachedConn, err := net.Dial("tcp", server)

	if err != nil {
		errString := "SERVER_ERROR <" + err.Error() + ">\r\n"
		conn.Write([]byte(errString))
		return nil
	}

	// send package to actual memcached server
	_, err = memcachedConn.Write(buf)

	if err != nil {
		errString := "SERVER_ERROR <" + err.Error() + ">\r\n"
		conn.Write([]byte(errString))
		return nil
	}

	// read result
	num, err := memcachedConn.Read(recv_buf)

	if err != nil {
		errString := "SERVER_ERROR <" + err.Error() + ">\r\n"
		conn.Write([]byte(errString))
		return nil
	}

	_, err = conn.Write(recv_buf[:num])

	if err != nil {
		debugln("cannot send result back to client ", clientAddr)
		return err
	}
	return nil
}

func serveStat(conn net.Conn, buf []byte) {
	total_get_hits := 0
	total_get_misses := 0
	total_cmd_get := 0
	total_cmd_set := 0

	recv_buf := make([]byte, BufferLength)
	// collect info from each real memcached
	for _, server := range c.Members() {

		memcachedConn, err := net.Dial("tcp", server)
		if err != nil {
			fmt.Println("error connect to memcached server:", err.Error())
		}

		//fmt.Println("send to memcached: ", string(buf))
		// send package to actual memcached server
		_, err = memcachedConn.Write(buf)

		if err != nil {
			println("Error send reply:", err.Error())
		}

		// read result
		_, err = memcachedConn.Read(recv_buf)

		//fmt.Println("recv to memcached: ", string(buf))

		stats := string(recv_buf)

		get_hits, err := getStatValue(stats, "get_hits")
		fmt.Println("server", server, "get_hits: ", get_hits)
		num_get_hits, _ := strconv.Atoi(get_hits)
		total_get_hits += num_get_hits

		get_misses, err := getStatValue(stats, "get_misses")
		fmt.Println("server", server, "get_misses: ", get_misses)
		num_get_misses, _ := strconv.Atoi(get_misses)
		total_get_misses += num_get_misses

		cmd_get, err := getStatValue(stats, "cmd_get")
		fmt.Println("server", server, "cmd_get: ", cmd_get)
		num_cmd_get, _ := strconv.Atoi(cmd_get)
		total_cmd_get += num_cmd_get

		cmd_set, err := getStatValue(stats, "cmd_set")
		fmt.Println("server", server, "cmd_set: ", cmd_set)
		num_cmd_set, _ := strconv.Atoi(cmd_set)
		total_cmd_set += num_cmd_set

	}
	str := fmt.Sprintln("total get_hits ", total_get_hits)
	_, _ = conn.Write([]byte(str))
	str = fmt.Sprintln("total get_missess ", total_get_hits)
	_, _ = conn.Write([]byte(str))
	str = fmt.Sprintln("total cmd_set ", total_cmd_set)
	_, _ = conn.Write([]byte(str))
	str = fmt.Sprintln("total cmd_get ", total_cmd_get)
	_, _ = conn.Write([]byte(str))
}

func getStatValue(stats string, key string) (string, error) {
	index := strings.Index(stats, key)
	if index == -1 {
		return "", errors.New("Stats Key Not Found")
	}

	stats = stats[index+len(key)+1:]
	index = strings.Index(stats, "\r\n")
	value := stats[:index]

	return value, nil
}
<commit_msg>make the etcd prefix configurable<commit_after>package main

import (
	"bytes"
	"encoding/binary"
	"errors"
	"flag"
	"fmt"
	"github.com/coreos/etcd/store"
	"github.com/coreos/go-etcd/etcd"
	"github.com/stathat/consistent"
	"net"
	"os"
	"strconv"
	"strings"
	"sync"
)

const (
	BufferLength     = 1024
	Magic            = 0x80
	BinaryHeaderSize = 24
)

var rwLock sync.RWMutex

var c *consistent.Consistent
var etcdClient *etcd.Client

var port int
var prefix string

func init() {
	flag.IntVar(&port, "p", 22122, "the port of the ds-memcached proxy")
	flag.StringVar(&prefix, "prefix", "/service/memcached", "the etcd prefix")
}

func main() {

	flag.Parse()

	c = consistent.New()

	etcdClient = etcd.NewClient()

	etcdClient.SyncCluster()

	presps, err := etcdClient.Get(prefix)

	if err != nil {
		fmt.Println("Add at least one memcached instance under path")
		os.Exit(1)
	}

	for _, resp := range presps {
		debugln("Add server ", resp.Value)
		c.Add(resp.Value)
	}

	go watch()

	startProxy()
}

func watch() {
	receiver := make(chan *store.Response, 10)
	stop := make(chan bool, 1)
	go update(receiver)
	etcdClient.Watch(prefix, 0, receiver, stop)
}

func update(receiver chan *store.Response) {
	for {
		resp := <-receiver
		switch resp.Action {
		case "SET":
			// do nothing if the old server is the same as the new one
			if resp.PrevValue == resp.Value {
				debugln("Doing nothing; new server is the same as old one:", resp.Value)
				continue
			}
			// check if we're adding a new server or updating an old one
			if resp.PrevValue == "" {
				debugln("Adding server:", resp.Value)
				c.Add(resp.Value)
			} else {
				debugln("Replacing server:", resp.PrevValue, "with", resp.Value)
				c.Remove(resp.PrevValue)
				c.Add(resp.Value)
			}
		case "DELETE":
			if resp.PrevValue != "" {
				debugln("Removing server:", resp.PrevValue)
				c.Remove(resp.PrevValue)
			}
		}
	}
}

func dispatch(key string) string {
	//do load balance
	server, _ := c.Get(key)

	debugln("map", key, "to server ", server)

	return server
}

func startProxy() {

	listener, err := net.Listen("tcp", "0.0.0.0:"+strconv.Itoa(port))

	if err != nil {
		fmt.Println("error listening:", err.Error())
		os.Exit(1)
	}

	debugln("Start listening on port", port)

	for {
		conn, err := listener.Accept()
		if err != nil {
			warnln("Error accept:", err.Error())
			return
		}
		go serve(conn)
	}

}

func serve(conn net.Conn) {
	clientAddr := conn.RemoteAddr().String()

	debugln("accept client ", clientAddr)
	for {
		buf := make([]byte, BufferLength)
		n, err := conn.Read(buf)

		if err != nil {
			return
		}

		debugln("received ", n, " bytes of data from [", clientAddr, "]")

		if buf[0] == Magic {
			err = serveBinary(conn, buf)
		} else {
			err = serveText(conn, buf)
		}

		if err != nil {
			conn.Write([]byte(err.Error()))
			conn.Close()
			return
		}

	}

}

func serveText(conn net.Conn, buf []byte) error {
	clientAddr := conn.RemoteAddr().String()

	debugln("received text protocol from ", clientAddr)
	content := string(buf)

	index := strings.Index(content, "\r\n")

	if index == -1 {
		debugln("[text protocol] bad request from ", clientAddr)
		return errors.New("ERROR\r\n")
	}

	header := content[0:index]

	debugln("[text protocol] header from ", clientAddr)

	fields := strings.Split(header, " ")

	op := fields[0]

	var err error

	if textCommands[op] {
		// all the ops in the command list should be like
		// [op] [key] ...
		// we only need to grab the key to do hashing
		// proxy does not care about other stuffs

		if len(fields) < 2 {
			// bad request if there is no key
			return errors.New("ERROR\r\n")
		}

		key := fields[1]

		err = serveCommands(conn, key, buf)

		return err

	} else if op == "stats" {

		serveStat(conn, buf)

	} else {

		return errors.New("Unimplemented\r\n")
	}

	return err
}

func serveBinary(conn net.Conn, buf []byte) error {
	clientAddr := conn.RemoteAddr().String()

	debugln("received binary protocol from ", clientAddr)

	bufLength := len(buf)

	if bufLength < BinaryHeaderSize {
		return errors.New("ERROR\r\n")
	}

	op := buf[1]

	var err error

	if binaryCommands[op] {
		var keyLength uint16

		keyLengthBuf := bytes.NewBuffer(buf[2:4])
		err := binary.Read(keyLengthBuf, binary.BigEndian, &keyLength)

		if err != nil {
			return errors.New("ERROR\r\n")
		}

		key := string(buf[BinaryHeaderSize : BinaryHeaderSize+keyLength])

		err = serveCommands(conn, key, buf)
	}
	return err
}

func serveCommands(conn net.Conn, key string, buf []byte) error {
	clientAddr := conn.RemoteAddr().String()

	recv_buf := make([]byte, BufferLength)

	server := dispatch(key)

	memcachedConn, err := net.Dial("tcp", server)

	if err != nil {
		errString := "SERVER_ERROR <" + err.Error() + ">\r\n"
		conn.Write([]byte(errString))
		return nil
	}

	// send package to actual memcached server
	_, err = memcachedConn.Write(buf)

	if err != nil {
		errString := "SERVER_ERROR <" + err.Error() + ">\r\n"
		conn.Write([]byte(errString))
		return nil
	}

	// read result
	num, err := memcachedConn.Read(recv_buf)

	if err != nil {
		errString := "SERVER_ERROR <" + err.Error() + ">\r\n"
		conn.Write([]byte(errString))
		return nil
	}

	_, err = conn.Write(recv_buf[:num])

	if err != nil {
		debugln("cannot send result back to client ", clientAddr)
		return err
	}
	return nil
}

func serveStat(conn net.Conn, buf []byte) {
	total_get_hits := 0
	total_get_misses := 0
	total_cmd_get := 0
	total_cmd_set := 0

	recv_buf := make([]byte, BufferLength)
	// collect info from each real memcached
	for _, server := range c.Members() {

		memcachedConn, err := net.Dial("tcp", server)
		if err != nil {
			fmt.Println("error connect to memcached server:", err.Error())
		}

		//fmt.Println("send to memcached: ", string(buf))
		// send package to actual memcached server
		_, err = memcachedConn.Write(buf)

		if err != nil {
			println("Error send reply:", err.Error())
		}

		// read result
		_, err = memcachedConn.Read(recv_buf)

		//fmt.Println("recv to memcached: ", string(buf))

		stats := string(recv_buf)

		get_hits, err := getStatValue(stats, "get_hits")
		fmt.Println("server", server, "get_hits: ", get_hits)
		num_get_hits, _ := strconv.Atoi(get_hits)
		total_get_hits += num_get_hits

		get_misses, err := getStatValue(stats, "get_misses")
		fmt.Println("server", server, "get_misses: ", get_misses)
		num_get_misses, _ := strconv.Atoi(get_misses)
		total_get_misses += num_get_misses

		cmd_get, err := getStatValue(stats, "cmd_get")
		fmt.Println("server", server, "cmd_get: ", cmd_get)
		num_cmd_get, _ := strconv.Atoi(cmd_get)
		total_cmd_get += num_cmd_get

		cmd_set, err := getStatValue(stats, "cmd_set")
		fmt.Println("server", server, "cmd_set: ", cmd_set)
		num_cmd_set, _ := strconv.Atoi(cmd_set)
		total_cmd_set += num_cmd_set

	}
	str := fmt.Sprintln("total get_hits ", total_get_hits)
	_, _ = conn.Write([]byte(str))
	str = fmt.Sprintln("total get_missess ", total_get_hits)
	_, _ = conn.Write([]byte(str))
	str = fmt.Sprintln("total cmd_set ", total_cmd_set)
	_, _ = conn.Write([]byte(str))
	str = fmt.Sprintln("total cmd_get ", total_cmd_get)
	_, _ = conn.Write([]byte(str))
}

func getStatValue(stats string, key string) (string, error) {
	index := strings.Index(stats, key)
	if index == -1 {
		return "", errors.New("Stats Key Not Found")
	}

	stats = stats[index+len(key)+1:]
	index = strings.Index(stats, "\r\n")
	value := stats[:index]

	return value, nil
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"html/template"
	"log"
	"net/http"
	"os"

	"github.com/StefanKjartansson/sundcloud/laterpay"
	"github.com/satori/go.uuid"
)

type Song struct {
	Id     string `json:"id"`
	Author string `json:"author"`
	Title  string `json:"title"`
	Image  string `json:"image"`
	Url    string `json:"url"`
	Access bool   `json:"access"`
}

const getToken = "https://api.sandbox.laterpaytest.net/gettoken"

const tpl = `
<!doctype html>

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>SundCloud</title>
    <meta name="robots" content="noindex, nofollow">
    <meta name="viewport" content="width=device-width, initial-scale=1">

`

func getIdsFromCatalog(songs []Song) []string {
	out := []string{}
	for _, s := range songs {
		out = append(out, s.Id)
	}
	return out
}

func main() {

	merchantID := os.Getenv("LP_ID")
	merchantSecret := os.Getenv("LP_SECRET")

	if merchantID == "" {
		log.Fatalln("LP_ID must be set")
	}

	if merchantSecret == "" {
		log.Fatalln("LP_SECRET must be set")
	}

	t, err := template.New("webpage").Parse(tpl)
	if err != nil {
		log.Fatalln("Unable to parse index")
	}

	catalog := []Song{
		{uuid.NewV4().String(), "Adele", "Hello", "http://lorempixel.com/200/100/", "/mp3/adele.mp3", true},
		{uuid.NewV4().String(), "Foo", "World", "http://lorempixel.com/200/100/", "/mp3/adele.mp3", true},
		{uuid.NewV4().String(), "Rammstein", "Bobo", "http://lorempixel.com/200/100/", "/mp3/adele.mp3", true},
		{uuid.NewV4().String(), "Fungi", "XXXX", "http://lorempixel.com/200/100/", "/mp3/adele.mp3", true},
	}

	c := laterpay.LaterPayClient{
		Id:        merchantID,
		SecretKey: []byte(merchantSecret),
		AddURL:    "/foo",
		AccessURL: "/bar",
		WebRoot:   "/baz",
	}

	http.HandleFunc("/api/songs/", func(w http.ResponseWriter, r *http.Request) {
		enc := json.NewEncoder(w)
		localCatalog := catalog[:]
		token := r.Header.Get("X-LP-Token")

		ids := getIdsFromCatalog(localCatalog)

		accessStats := c.Access(token, ids...)

		for id, access := range accessStats {
			if access {
				continue
			}
			for idx, l := range localCatalog {
				if l.Id == id {
					i := laterpay.ItemDefinition{
						Id:      id,
						Pricing: "EUR23",
						Title:   l.Title,
					}
					url, err := c.Add(i)
					if err != nil {
						log.Println(err)
					}
					localCatalog[idx].Url = url
					localCatalog[idx].Access = false
				}
			}
		}

		enc.Encode(localCatalog)
	})

	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		// IF no lptoken in q, redirect.
		Token := r.URL.Query().Get("lptoken")

		if Token == "" {
			redirectURL := fmt.Sprintf("%s?cp=%s", getToken, merchantID)
			log.Println(redirectURL)
			http.Redirect(w, r, redirectURL, 301)
			return
		}

		data := struct {
			Token string
		}{
			"Token",
		}
		err = t.Execute(w, data)
	})

	fs := http.FileServer(http.Dir("static"))
	http.Handle("/static/", fs)
	log.Fatal(http.ListenAndServe(":3000", nil))
}
<commit_msg>static redirect url<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"html/template"
	"log"
	"net/http"
	"os"

	"github.com/StefanKjartansson/sundcloud/laterpay"
	"github.com/satori/go.uuid"
)

type Song struct {
	Id     string `json:"id"`
	Author string `json:"author"`
	Title  string `json:"title"`
	Image  string `json:"image"`
	Url    string `json:"url"`
	Access bool   `json:"access"`
}

const getToken = "https://api.sandbox.laterpaytest.net/gettoken"

const tpl = `
<!doctype html>

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>SundCloud</title>
    <meta name="robots" content="noindex, nofollow">
    <meta name="viewport" content="width=device-width, initial-scale=1">

`

func getIdsFromCatalog(songs []Song) []string {
	out := []string{}
	for _, s := range songs {
		out = append(out, s.Id)
	}
	return out
}

func main() {

	merchantID := os.Getenv("LP_ID")
	merchantSecret := os.Getenv("LP_SECRET")

	if merchantID == "" {
		log.Fatalln("LP_ID must be set")
	}

	if merchantSecret == "" {
		log.Fatalln("LP_SECRET must be set")
	}

	t, err := template.New("webpage").Parse(tpl)
	if err != nil {
		log.Fatalln("Unable to parse index")
	}

	catalog := []Song{
		{uuid.NewV4().String(), "Adele", "Hello", "http://lorempixel.com/200/100/", "/mp3/adele.mp3", true},
		{uuid.NewV4().String(), "Foo", "World", "http://lorempixel.com/200/100/", "/mp3/adele.mp3", true},
		{uuid.NewV4().String(), "Rammstein", "Bobo", "http://lorempixel.com/200/100/", "/mp3/adele.mp3", true},
		{uuid.NewV4().String(), "Fungi", "XXXX", "http://lorempixel.com/200/100/", "/mp3/adele.mp3", true},
	}

	c := laterpay.LaterPayClient{
		Id:        merchantID,
		SecretKey: []byte(merchantSecret),
		AddURL:    "/foo",
		AccessURL: "/bar",
		WebRoot:   "/baz",
	}

	redirectURL := fmt.Sprintf("%s?cp=%s", getToken, merchantID)

	log.Printf("Redirect URL: %s\n", redirectURL)

	http.HandleFunc("/api/songs/", func(w http.ResponseWriter, r *http.Request) {
		enc := json.NewEncoder(w)
		localCatalog := catalog[:]
		token := r.Header.Get("X-LP-Token")

		ids := getIdsFromCatalog(localCatalog)

		accessStats := c.Access(token, ids...)

		for id, access := range accessStats {
			if access {
				continue
			}
			for idx, l := range localCatalog {
				if l.Id == id {
					i := laterpay.ItemDefinition{
						Id:      id,
						Pricing: "EUR23",
						Title:   l.Title,
					}
					url, err := c.Add(i)
					if err != nil {
						log.Println(err)
					}
					localCatalog[idx].Url = url
					localCatalog[idx].Access = false
				}
			}
		}

		enc.Encode(localCatalog)
	})

	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		// IF no lptoken in q, redirect.
		Token := r.URL.Query().Get("lptoken")

		if Token == "" {
			http.Redirect(w, r, redirectURL, 301)
			return
		}

		data := struct {
			Token string
		}{
			"Token",
		}
		err = t.Execute(w, data)
	})

	fs := http.FileServer(http.Dir("static"))
	http.Handle("/static/", fs)
	log.Fatal(http.ListenAndServe(":3000", nil))
}
<|endoftext|>


<commit_before>package main

import "io"
import "fmt"
import "net/http"
import "os"
import "os/exec"
import "flag"
import "strings"
import "strconv"

import "github.com/gorilla/websocket"
import "github.com/kr/pty"
import "github.com/creack/goterm/win"

func start() (*os.File, *exec.Cmd) {
	var err error

	cmdString := "/bin/bash"
	cmd := exec.Command(cmdString)
	ptym, err := pty.Start(cmd)
	if err != nil {
		fmt.Println("Failed to start command: %s", err)
	}

	return ptym, cmd
}

func stop(ptym *os.File, cmd *exec.Cmd, conn *websocket.Conn) {
	ptym.Close()
	conn.Close()
	cmd.Wait()
}

// Read from the websocket, copying to the pty master.
func handleInput(ptym *os.File, conn *websocket.Conn) {
	for {
		mt, payload, err := conn.ReadMessage()
		if err != nil {
			if err != io.EOF {
				fmt.Println("conn.ReadMessage failed: ", err)
				return
			}
		}

		switch mt {
		case websocket.BinaryMessage:
			ptym.Write(payload)
		default:
			fmt.Println("Invalid message type %d", mt)
			return
		}
	}
}

// Copy everything from the pty master to the websocket.
func handleOutput(ptym *os.File, conn *websocket.Conn) {
	buf := make([]byte, 512)
	// TODO: more graceful exit on socket close / process exit
	for {
		n, err := ptym.Read(buf)
		if err != nil {
			fmt.Println("Failed to read from pty master: ", err)
			return
		}

		err = conn.WriteMessage(websocket.BinaryMessage, buf[0:n])

		if err != nil {
			fmt.Println("Failed to send %d bytes on websocket: %s", n, err)
			return
		}
	}
}

func ptyHandler(w http.ResponseWriter, r *http.Request, sizeFlag string) {
	var upgrader = websocket.Upgrader{
		ReadBufferSize:  1,
		WriteBufferSize: 1,
		CheckOrigin: func(r *http.Request) bool {
			return true
		},
	}

	conn, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		fmt.Println("Websocket upgrade failed: %s", err)
	}

	ptym, cmd := start()

	size := strings.Split(sizeFlag, "x")
	cols, _ := strconv.Atoi(size[0])
	lines, _ := strconv.Atoi(size[1])
	if err := win.SetWinsize(ptym.Fd(), &win.Winsize{Height: uint16(lines), Width: uint16(cols)}); err != nil {
		panic(err)
	}

	go func() {
		handleOutput(ptym, conn)
	}()

	go func() {
		handleInput(ptym, conn)
	}()

	for {
		var size string
		_, scanErr := fmt.Scanln(&size)
		if scanErr != nil {
			fmt.Println("scan failed: ", scanErr)
		}

		fmt.Println("done scanning: ", size)
	}

	stop(ptym, cmd, conn)
}

func main() {
	addrFlag := flag.String("addr", ":12061", "IP:PORT or :PORT address to listen on")
	sizeFlag := flag.String("size", "80x24", "initial size for the tty")

	flag.Parse()

	http.HandleFunc("/pty", func(w http.ResponseWriter, r *http.Request) {
		ptyHandler(w, r, *sizeFlag)
	})

	err := http.ListenAndServe(*addrFlag, nil)
	if err != nil {
		fmt.Println("net.http could not listen on address '%s': %s", addrFlag, err)
	}
}
<commit_msg>Fixed some print fmt errors<commit_after>package main

import "io"
import "fmt"
import "net/http"
import "os"
import "os/exec"
import "flag"
import "strings"
import "strconv"

import "github.com/gorilla/websocket"
import "github.com/kr/pty"
import "github.com/creack/goterm/win"

func start() (*os.File, *exec.Cmd) {
	var err error

	cmdString := "/bin/bash"
	cmd := exec.Command(cmdString)
	ptym, err := pty.Start(cmd)
	if err != nil {
		fmt.Println("Failed to start command: ", err)
	}

	return ptym, cmd
}

func stop(ptym *os.File, cmd *exec.Cmd, conn *websocket.Conn) {
	ptym.Close()
	conn.Close()
	cmd.Wait()
}

// Read from the websocket, copying to the pty master.
func handleInput(ptym *os.File, conn *websocket.Conn) {
	for {
		mt, payload, err := conn.ReadMessage()
		if err != nil {
			if err != io.EOF {
				fmt.Println("conn.ReadMessage failed: ", err)
				return
			}
		}

		switch mt {
		case websocket.BinaryMessage:
			ptym.Write(payload)
		default:
			fmt.Println("Invalid message type: ", mt)
			return
		}
	}
}

// Copy everything from the pty master to the websocket.
func handleOutput(ptym *os.File, conn *websocket.Conn) {
	buf := make([]byte, 512)
	// TODO: more graceful exit on socket close / process exit
	for {
		n, err := ptym.Read(buf)
		if err != nil {
			fmt.Println("Failed to read from pty master: ", err)
			return
		}

		err = conn.WriteMessage(websocket.BinaryMessage, buf[0:n])

		if err != nil {
			fmt.Println("Failed to send %d bytes on websocket: %s", n, err)
			return
		}
	}
}

func ptyHandler(w http.ResponseWriter, r *http.Request, sizeFlag string) {
	var upgrader = websocket.Upgrader{
		ReadBufferSize:  1,
		WriteBufferSize: 1,
		CheckOrigin: func(r *http.Request) bool {
			return true
		},
	}

	conn, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		fmt.Println("Websocket upgrade failed: ", err)
	}

	ptym, cmd := start()

	size := strings.Split(sizeFlag, "x")
	cols, _ := strconv.Atoi(size[0])
	lines, _ := strconv.Atoi(size[1])
	if err := win.SetWinsize(ptym.Fd(), &win.Winsize{Height: uint16(lines), Width: uint16(cols)}); err != nil {
		panic(err)
	}

	go func() {
		handleOutput(ptym, conn)
	}()

	go func() {
		handleInput(ptym, conn)
	}()

	for {
		var size string
		_, scanErr := fmt.Scanln(&size)
		if scanErr != nil {
			fmt.Println("scan failed: ", scanErr)
		}

		fmt.Println("done scanning: ", size)
	}

	stop(ptym, cmd, conn)
}

func main() {
	addrFlag := flag.String("addr", ":12061", "IP:PORT or :PORT address to listen on")
	sizeFlag := flag.String("size", "80x24", "initial size for the tty")

	flag.Parse()

	http.HandleFunc("/pty", func(w http.ResponseWriter, r *http.Request) {
		ptyHandler(w, r, *sizeFlag)
	})

	err := http.ListenAndServe(*addrFlag, nil)
	if err != nil {
		fmt.Println("net.http could not listen on address '%s': %s", addrFlag, err)
	}
}
<|endoftext|>