<commit_before>package game

import (
  "fmt"
)

type SetupRule struct {
  Id int
  Description string
  Arity string
  Dependencies []*SetupRule
}

func NewSetupRule(desc string, arity string, deps ...*SetupRule) *SetupRule {
  return &SetupRule{0, desc, arity, deps}
}

type SetupStep struct {
  Rule *SetupRule
  Owner *Player
  Done bool
}

func NewGlobalSetupStep(rule *SetupRule) (*SetupStep, error) {
  if "Once" != rule.Arity {
    return nil, fmt.Errorf("Setup rule must be done once")
  }
  return &SetupStep{rule, nil, false}, nil
}

func NewSinglePlayerSetupStep(rule *SetupRule, owner *Player) (*SetupStep, error) {
  if "Each player" != rule.Arity {
    return nil, fmt.Errorf("Setup rule must be for each player")
  }
  return &SetupStep{rule, owner, false}, nil
}

func (step *SetupStep) CanBeOwnedBy(player *Player) bool {
  return step.Owner == nil || player.Id == step.Owner.Id
}

func (step *SetupStep) Finish() {
  step.Done = true
}

func (a *SetupStep) Equal(b *SetupStep) bool {
  if a.Rule.Id == b.Rule.Id {
    if a.Owner == nil && b.Owner == nil {
      return true
    }
    if a.Owner != nil && b.Owner != nil {
      if a.Owner.Id == b.Owner.Id {
        return true
      }
    }
  }
  return false
}

func (step *SetupStep) String() string {
  return fmt.Sprintf("%s", step.Rule.Description)
}
<commit_msg>Placeholder for setup rules details<commit_after>package game

import (
  "fmt"
)

type SetupRule struct {
  Id int
  Description string
  Details string
  Arity string
  Dependencies []*SetupRule
}

const IPSUM string = "You think water moves fast? You should see ice. It moves like it has a mind. Like it knows it killed the world once and got a taste for murder. After the avalanche, it took us a week to climb out. Now, I don't know exactly when we turned on each other, but I know that seven of us survived the slide... and only five made it out. Now we took an oath, that I'm breaking now. We said we'd say it was the snow that killed the other two, but it wasn't. Nature is lethal but it doesn't hold a candle to man."

func NewSetupRule(desc string, arity string, deps ...*SetupRule) *SetupRule {
  return &SetupRule{0, desc, IPSUM, arity, deps}
}

type SetupStep struct {
  Rule *SetupRule
  Owner *Player
  Done bool
}

func NewGlobalSetupStep(rule *SetupRule) (*SetupStep, error) {
  if "Once" != rule.Arity {
    return nil, fmt.Errorf("Setup rule must be done once")
  }
  return &SetupStep{rule, nil, false}, nil
}

func NewSinglePlayerSetupStep(rule *SetupRule, owner *Player) (*SetupStep, error) {
  if "Each player" != rule.Arity {
    return nil, fmt.Errorf("Setup rule must be for each player")
  }
  return &SetupStep{rule, owner, false}, nil
}

func (step *SetupStep) CanBeOwnedBy(player *Player) bool {
  return step.Owner == nil || player.Id == step.Owner.Id
}

func (step *SetupStep) Finish() {
  step.Done = true
}

func (a *SetupStep) Equal(b *SetupStep) bool {
  if a.Rule.Id == b.Rule.Id {
    if a.Owner == nil && b.Owner == nil {
      return true
    }
    if a.Owner != nil && b.Owner != nil {
      if a.Owner.Id == b.Owner.Id {
        return true
      }
    }
  }
  return false
}

func (step *SetupStep) String() string {
  return fmt.Sprintf("%s", step.Rule.Description)
}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"log"
	"os/exec"

	"cloud.google.com/go/pubsub"
	"google.golang.org/api/iterator"
)

const updateTopicString string = "onesie-updates"
const updateSub string = "onesie-server"

func main() {
	log.Println("Starting")
	pubsubClient, err := pubsub.NewClient(context.Background(), "940380154622")
	if err != nil {
		log.Fatalf("Failed to create client: %v", err)
	}

	updateTopic := pubsubClient.Topic(updateTopicString)
	sub := pubsubClient.Subscription(updateSub)
	b, err := sub.Exists(context.Background())
	if err != nil {
		log.Fatal(err)
	}
	if !b {
		sub, err = pubsubClient.CreateSubscription(context.Background(), updateSub, updateTopic, 0, nil)
		if err != nil {
			log.Fatal(err)
		}
	}

	// Construct the iterator
	it, err := sub.Pull(context.Background())
	if err != nil {
		log.Fatalf("Error getting messages: %+v", err)
	}
	defer it.Stop()

	// Consume 1 messages
	for i := 0; i < 1; i++ {
		msg, err := it.Next()
		if err == iterator.Done {
			log.Println("No more messages.")
			break
		}
		if err != nil {
			log.Printf("Error while getting message: %+v", err)
			break
		}

		msgStr := string(msg.Data)
		log.Printf("Recieved Message: %+v", msgStr)

		if msgStr == "update" {
			// Create an *exec.Cmd
			out, err := exec.Command("/opt/dehydrated/dehydrated -c --config /opt/onesie-configs/dehydrated.conf").Output()
			if err != nil {
				log.Printf("Error running command: %+v", err)
			}
			log.Println(out)
		}
		msg.Done(true)
	}

	log.Println("Finished.")
}
<commit_msg>fix worker<commit_after>package main

import (
	"context"
	"log"
	"os/exec"

	"cloud.google.com/go/pubsub"
	"google.golang.org/api/iterator"
)

const updateTopicString string = "onesie-updates"
const updateSub string = "onesie-server"

func main() {
	log.Println("Starting")
	pubsubClient, err := pubsub.NewClient(context.Background(), "940380154622")
	if err != nil {
		log.Fatalf("Failed to create client: %v", err)
	}

	updateTopic := pubsubClient.Topic(updateTopicString)
	sub := pubsubClient.Subscription(updateSub)
	b, err := sub.Exists(context.Background())
	if err != nil {
		log.Fatal(err)
	}
	if !b {
		sub, err = pubsubClient.CreateSubscription(context.Background(), updateSub, updateTopic, 0, nil)
		if err != nil {
			log.Fatal(err)
		}
	}

	// Construct the iterator
	it, err := sub.Pull(context.Background())
	if err != nil {
		log.Fatalf("Error getting messages: %+v", err)
	}
	defer it.Stop()

	// Consume 1 messages
	for i := 0; i < 1; i++ {
		msg, err := it.Next()
		if err == iterator.Done {
			log.Println("No more messages.")
			break
		}
		if err != nil {
			log.Printf("Error while getting message: %+v", err)
			break
		}

		msgStr := string(msg.Data)
		log.Printf("Recieved Message: %+v", msgStr)

		if msgStr == "update" {
			// Create an *exec.Cmd
			out, err := exec.Command("/opt/dehydrated/dehydrated", "-c --config /opt/onesie-configs/dehydrated.conf").Output()
			if err != nil {
				log.Printf("Error running command: %+v", err)
			}
			log.Println(out)
		}
		msg.Done(true)
	}

	log.Println("Finished.")
}
<|endoftext|>


<commit_before>package gameboy

import (
	"context"
	"fmt"
	"io"
	"io/ioutil"

	"github.com/scottyw/tetromino/gameboy/audio"
	"github.com/scottyw/tetromino/gameboy/controller"
	"github.com/scottyw/tetromino/gameboy/cpu"
	"github.com/scottyw/tetromino/gameboy/display"
	"github.com/scottyw/tetromino/gameboy/interrupts"
	"github.com/scottyw/tetromino/gameboy/memory"
	"github.com/scottyw/tetromino/gameboy/oam"
	"github.com/scottyw/tetromino/gameboy/ppu"
	"github.com/scottyw/tetromino/gameboy/serial"
	"github.com/scottyw/tetromino/gameboy/speakers"
	"github.com/scottyw/tetromino/gameboy/timer"
)

// Config control emulator behaviour
type Config struct {
	RomFilename        string
	DisableVideoOutput bool
	DisableAudioOutput bool
	DebugCPU           bool
	DebugLCD           bool
	SerialWriter       io.Writer
}

// Gameboy represents the Gameboy itself
type Gameboy struct {
	audio      *audio.Audio
	config     Config
	controller *controller.Controller
	dispatch   *cpu.Dispatch
	display    *display.Display
	interrupts *interrupts.Interrupts
	ppu        *ppu.PPU
	mapper     *memory.Mapper
	speakers   *speakers.Speakers
	timer      *timer.Timer
}

// NewGameboy returns a new Gameboy
func New(config Config) *Gameboy {

	// Create interrrupts subsystem
	i := interrupts.New()

	// Create CPU
	c := cpu.New(i, config.DebugCPU)

	// Create controller
	controller := controller.New(c.Restart)

	// Create a display
	var d *display.Display
	if !config.DisableVideoOutput {
		d = display.New(controller, config.DebugLCD)
	}

	// Create speakers
	var a *audio.Audio
	var s *speakers.Speakers
	if !config.DisableAudioOutput {
		s = speakers.New()
		a = audio.New(s.Left(), s.Right())
	} else {
		a = audio.New(nil, nil)
	}

	// Create OAM memory
	oam := oam.New()

	// Create the PPU
	ppu := ppu.New(i, oam, config.DebugLCD)

	// Create the serial bus subsystem
	serial := serial.New(config.SerialWriter)

	// Create the timer subsystem
	timer := timer.New()

	// Load the ROM file
	rom := readRomFile(config.RomFilename)

	mapper := memory.New(rom, i, oam, ppu, controller, serial, timer, a)

	dispatch := cpu.NewDispatch(c, mapper)

	return &Gameboy{
		audio:      a,
		config:     config,
		controller: controller,
		dispatch:   dispatch,
		display:    d,
		interrupts: i,
		ppu:        ppu,
		mapper:     mapper,
		speakers:   s,
		timer:      timer,
	}
}

func (gb *Gameboy) Cleanup() {
	if gb.speakers != nil {
		gb.speakers.Cleanup()
	}
	if gb.display != nil {
		gb.display.Cleanup()
	}
}

func readRomFile(romFilename string) []byte {
	var rom []byte
	if romFilename == "" {
		panic(fmt.Sprintf("No ROM file specified"))
	}
	rom, err := ioutil.ReadFile(romFilename)
	if err != nil {
		panic(fmt.Sprintf("Failed to read the ROM file at \"%s\" (%v)", romFilename, err))
	}
	return rom
}

func (gb *Gameboy) runFrame(ctx context.Context) bool {
	// The Game Boy clock runs at 4.194304MHz
	// Each loop iteration below represents one machine cycle
	// One machine cycle is 4 clock cycles
	// Each LCD frame is 17556 machine cycles
	for mtick := 0; mtick < 17556; mtick++ {
		gb.dispatch.ExecuteMachineCycle()
		gb.ppu.EndMachineCycle()
		gb.mapper.EndMachineCycle()
		gb.audio.EndMachineCycle()
		timerInterruptRequested := gb.timer.EndMachineCycle()
		if timerInterruptRequested {
			gb.interrupts.RequestTimer()
		}
	}
	frame := gb.ppu.Frame()
	if gb.display != nil {
		return gb.display.RenderFrame(frame)
	}
	return false

	// The emulator can run a frame much faster than a real Gameboy when running on a modern computer.
	// There is no need to sleep now between frames however, because the audio subsystem consumes
	// samples at a fixed rate from a blocking channel. The emulator can only push audio samples into
	// the channel at the same rate that the "speakers" consume them. Since the "speakers" are
	// consuming the data at the rate of a real Gameboy (in order to make sound play correctly), the
	// rest of the emulator is slowed to the same correct rate. In "fast" mode, the emulator disables
	// the "speakers" meaning there is no constraint on how fast samples are consumed or on how fast
	// the emulator runs.

}

// Run the Gameboy
func (gb *Gameboy) Run(ctx context.Context) {
	defer gb.Cleanup()
	for {
		select {
		case <-ctx.Done():
			return
		default:
			if gb.runFrame(ctx) {
				return
			}
		}
	}
}
<commit_msg>Code to check FPS<commit_after>package gameboy

import (
	"context"
	"fmt"
	"io"
	"io/ioutil"

	"github.com/scottyw/tetromino/gameboy/audio"
	"github.com/scottyw/tetromino/gameboy/controller"
	"github.com/scottyw/tetromino/gameboy/cpu"
	"github.com/scottyw/tetromino/gameboy/display"
	"github.com/scottyw/tetromino/gameboy/interrupts"
	"github.com/scottyw/tetromino/gameboy/memory"
	"github.com/scottyw/tetromino/gameboy/oam"
	"github.com/scottyw/tetromino/gameboy/ppu"
	"github.com/scottyw/tetromino/gameboy/serial"
	"github.com/scottyw/tetromino/gameboy/speakers"
	"github.com/scottyw/tetromino/gameboy/timer"
)

// Config control emulator behaviour
type Config struct {
	RomFilename        string
	DisableVideoOutput bool
	DisableAudioOutput bool
	DebugCPU           bool
	DebugLCD           bool
	SerialWriter       io.Writer
}

// Gameboy represents the Gameboy itself
type Gameboy struct {
	audio      *audio.Audio
	config     Config
	controller *controller.Controller
	dispatch   *cpu.Dispatch
	display    *display.Display
	interrupts *interrupts.Interrupts
	ppu        *ppu.PPU
	mapper     *memory.Mapper
	speakers   *speakers.Speakers
	timer      *timer.Timer
}

// NewGameboy returns a new Gameboy
func New(config Config) *Gameboy {

	// Create interrrupts subsystem
	i := interrupts.New()

	// Create CPU
	c := cpu.New(i, config.DebugCPU)

	// Create controller
	controller := controller.New(c.Restart)

	// Create a display
	var d *display.Display
	if !config.DisableVideoOutput {
		d = display.New(controller, config.DebugLCD)
	}

	// Create speakers
	var a *audio.Audio
	var s *speakers.Speakers
	if !config.DisableAudioOutput {
		s = speakers.New()
		a = audio.New(s.Left(), s.Right())
	} else {
		a = audio.New(nil, nil)
	}

	// Create OAM memory
	oam := oam.New()

	// Create the PPU
	ppu := ppu.New(i, oam, config.DebugLCD)

	// Create the serial bus subsystem
	serial := serial.New(config.SerialWriter)

	// Create the timer subsystem
	timer := timer.New()

	// Load the ROM file
	rom := readRomFile(config.RomFilename)

	mapper := memory.New(rom, i, oam, ppu, controller, serial, timer, a)

	dispatch := cpu.NewDispatch(c, mapper)

	return &Gameboy{
		audio:      a,
		config:     config,
		controller: controller,
		dispatch:   dispatch,
		display:    d,
		interrupts: i,
		ppu:        ppu,
		mapper:     mapper,
		speakers:   s,
		timer:      timer,
	}
}

func (gb *Gameboy) Cleanup() {
	if gb.speakers != nil {
		gb.speakers.Cleanup()
	}
	if gb.display != nil {
		gb.display.Cleanup()
	}
}

func readRomFile(romFilename string) []byte {
	var rom []byte
	if romFilename == "" {
		panic(fmt.Sprintf("No ROM file specified"))
	}
	rom, err := ioutil.ReadFile(romFilename)
	if err != nil {
		panic(fmt.Sprintf("Failed to read the ROM file at \"%s\" (%v)", romFilename, err))
	}
	return rom
}

func (gb *Gameboy) runFrame(ctx context.Context) bool {
	// The Game Boy clock runs at 4.194304MHz
	// Each loop iteration below represents one machine cycle
	// One machine cycle is 4 clock cycles
	// Each LCD frame is 17556 machine cycles
	for mtick := 0; mtick < 17556; mtick++ {
		gb.dispatch.ExecuteMachineCycle()
		gb.ppu.EndMachineCycle()
		gb.mapper.EndMachineCycle()
		gb.audio.EndMachineCycle()
		timerInterruptRequested := gb.timer.EndMachineCycle()
		if timerInterruptRequested {
			gb.interrupts.RequestTimer()
		}
	}
	frame := gb.ppu.Frame()
	if gb.display != nil {
		return gb.display.RenderFrame(frame)
	}
	return false

	// The emulator can run a frame much faster than a real Gameboy when running on a modern computer.
	// There is no need to sleep now between frames however, because the audio subsystem consumes
	// samples at a fixed rate from a blocking channel. The emulator can only push audio samples into
	// the channel at the same rate that the "speakers" consume them. Since the "speakers" are
	// consuming the data at the rate of a real Gameboy (in order to make sound play correctly), the
	// rest of the emulator is slowed to the same correct rate. In "fast" mode, the emulator disables
	// the "speakers" meaning there is no constraint on how fast samples are consumed or on how fast
	// the emulator runs.

}

// Run the Gameboy
func (gb *Gameboy) Run(ctx context.Context) {
	defer gb.Cleanup()
	// var frames int
	// var t0 time.Time
	for {
		select {
		case <-ctx.Done():
			return
		default:
			if gb.runFrame(ctx) {
				return
			}
		}

		// // Check FPS
		// if frames%300 == 0 {
		// 	duration := time.Now().Sub(t0)
		// 	fmt.Printf(">> %0.0ffps\n", 300.0/duration.Seconds())
		// 	t0 = time.Now()
		// }
		// frames++

	}
}
<|endoftext|>


<commit_before>package main

import (
	"crypto/sha1"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"os"
	"strconv"
	"sync"

	"github.com/progrium/simplex-gateway/Godeps/_workspace/src/github.com/progrium/simplex/golang"
	"github.com/progrium/simplex-gateway/Godeps/_workspace/src/golang.org/x/net/websocket"
)

var (
	endpoints map[string]*Endpoint
	mu        sync.Mutex
)

type Endpoint struct {
	sync.Mutex
	path     string
	secret   string
	upstream *websocket.Conn
	counter  int
	clients  map[string]*websocket.Conn
}

func RouteKey(id int) string {
	h := sha1.New()
	h.Write([]byte(os.Getenv("TOKEN")))
	h.Write([]byte(strconv.Itoa(id)))
	return hex.EncodeToString(h.Sum(nil))
}

func AcceptSimplexHandshake(ws *websocket.Conn) error {
	buf := make([]byte, 32)
	_, err := ws.Read(buf) // TODO: timeout
	if err != nil {
		return err
	}
	// TODO: check handshake
	_, err = ws.Write([]byte(simplex.HandshakeAccept))
	if err != nil {
		return err
	}
	return nil
}

func HandleClient(w http.ResponseWriter, r *http.Request) {
	mu.Lock()
	endpoint, exists := endpoints[r.URL.Path]
	mu.Unlock()
	if !exists {
		http.NotFound(w, r)
		return
	}
	if r.URL.Query().Get("secret") != endpoint.secret {
		http.Error(w, "Bad secret", http.StatusUnauthorized)
		return
	}
	s := websocket.Server{Handler: func(ws *websocket.Conn) {
		AcceptSimplexHandshake(ws) // TODO handle error
		endpoint.Lock()
		endpoint.counter++
		routeKey := RouteKey(endpoint.counter)
		endpoint.clients[routeKey] = ws
		endpoint.Unlock()
		log.Println("Endpoint", endpoint.path, "client connected", r.RemoteAddr)
		for {
			frameBuf := make([]byte, simplex.MaxFrameSize)
			n, err := ws.Read(frameBuf)
			if err != nil {
				endpoint.Lock()
				delete(endpoint.clients, routeKey)
				endpoint.Unlock()
				break
			}
			var msg simplex.Message
			err = json.Unmarshal(frameBuf[:n], &msg)
			if err != nil {
				// TODO: what happens on decode error
				panic(err)
			}
			var ext map[string]interface{}
			if msg.Ext == nil {
				ext = make(map[string]interface{})
			} else {
				ext = msg.Ext.(map[string]interface{})
			}
			ext["route"] = routeKey
			msg.Ext = ext
			frame, err := json.Marshal(&msg)
			if err != nil {
				// TODO: what happens on encode error
				panic(err)
			}
			if os.Getenv("DEBUG") != "" {
				fmt.Println("<<<", string(frame))
			}
			_, err = endpoint.upstream.Write(frame)
			if err != nil {
				// TODO: handle upstream write error
				// remove upstream endpoint?
				break
			}
		}
	}}
	s.ServeHTTP(w, r)
}

func HandleBackend(w http.ResponseWriter, r *http.Request) {
	if r.URL.Query().Get("secret") == "" {
		http.Error(w, "Secret required", http.StatusBadRequest)
		return
	}
	s := websocket.Server{Handler: func(ws *websocket.Conn) {
		endpoint := &Endpoint{
			path:    ws.Request().URL.Path,
			secret:  ws.Request().URL.Query().Get("secret"),
			counter: 0,
			clients: make(map[string]*websocket.Conn),
		}
		AcceptSimplexHandshake(ws) // TODO handle error
		endpoint.upstream = ws
		mu.Lock()
		old, exists := endpoints[endpoint.path]
		if exists {
			old.upstream.Close()
		}
		endpoints[endpoint.path] = endpoint
		mu.Unlock()
		log.Println("Endpoint", endpoint.path, "backend online")
		for {
			frame := make([]byte, simplex.MaxFrameSize)
			n, err := ws.Read(frame)
			if err != nil {
				// TODO: what happens on read error
				log.Println("read err")
				break
			}
			var msg simplex.Message
			err = json.Unmarshal(frame[:n], &msg)
			if err != nil {
				// TODO: what happens on decode error
				panic(err)
			}
			if msg.Ext == nil {
				log.Println("no ext")
				continue
			}
			ext, ok := msg.Ext.(map[string]interface{})
			if !ok {
				log.Println("ext not object")
				continue
			}
			routeKey := ext["route"].(string)
			endpoint.Lock()
			clientConn, ok := endpoint.clients[routeKey]
			endpoint.Unlock()
			if !ok {
				log.Println("routekey not found")
				continue
			}
			if os.Getenv("DEBUG") != "" {
				fmt.Println(">>>", string(frame[:n]))
			}
			_, err = clientConn.Write(frame[:n])
			if err != nil {
				endpoint.Lock()
				delete(endpoint.clients, routeKey)
				endpoint.Unlock()
			}
		}
		log.Println("Endpoint", endpoint.path, "backend offline")
	}}
	s.ServeHTTP(w, r)
}

func Handler(w http.ResponseWriter, r *http.Request) {
	if r.Header.Get("x-forwarded-proto") != "https" && os.Getenv("NOTLS") == "" {
		http.Error(w, "TLS required", http.StatusForbidden)
		return
	}
	if r.URL.Query().Get("token") == os.Getenv("TOKEN") {
		HandleBackend(w, r)
	} else {
		HandleClient(w, r)
	}
}

func main() {
	endpoints = make(map[string]*Endpoint)
	http.HandleFunc("/", Handler)
	port := ":" + os.Getenv("PORT")
	log.Println("Simplex gateway started on", port, "...")
	log.Fatal(http.ListenAndServe(port, nil))
}
<commit_msg>debugging heroku<commit_after>package main

import (
	"crypto/sha1"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"os"
	"strconv"
	"sync"

	"github.com/progrium/simplex-gateway/Godeps/_workspace/src/github.com/progrium/simplex/golang"
	"github.com/progrium/simplex-gateway/Godeps/_workspace/src/golang.org/x/net/websocket"
)

var (
	endpoints map[string]*Endpoint
	mu        sync.Mutex
)

type Endpoint struct {
	sync.Mutex
	path     string
	secret   string
	upstream *websocket.Conn
	counter  int
	clients  map[string]*websocket.Conn
}

func RouteKey(id int) string {
	h := sha1.New()
	h.Write([]byte(os.Getenv("TOKEN")))
	h.Write([]byte(strconv.Itoa(id)))
	return hex.EncodeToString(h.Sum(nil))
}

func AcceptSimplexHandshake(ws *websocket.Conn) error {
	buf := make([]byte, 32)
	_, err := ws.Read(buf) // TODO: timeout
	if err != nil {
		return err
	}
	// TODO: check handshake
	_, err = ws.Write([]byte(simplex.HandshakeAccept))
	if err != nil {
		return err
	}
	return nil
}

func HandleClient(w http.ResponseWriter, r *http.Request) {
	mu.Lock()
	endpoint, exists := endpoints[r.URL.Path]
	mu.Unlock()
	if !exists {
		http.NotFound(w, r)
		return
	}
	if r.URL.Query().Get("secret") != endpoint.secret {
		http.Error(w, "Bad secret", http.StatusUnauthorized)
		return
	}
	s := websocket.Server{Handler: func(ws *websocket.Conn) {
		AcceptSimplexHandshake(ws) // TODO handle error
		endpoint.Lock()
		endpoint.counter++
		routeKey := RouteKey(endpoint.counter)
		endpoint.clients[routeKey] = ws
		endpoint.Unlock()
		log.Println("Endpoint", endpoint.path, "client connected", r.RemoteAddr)
		for {
			frameBuf := make([]byte, simplex.MaxFrameSize)
			n, err := ws.Read(frameBuf)
			if err != nil {
				endpoint.Lock()
				delete(endpoint.clients, routeKey)
				endpoint.Unlock()
				break
			}
			var msg simplex.Message
			err = json.Unmarshal(frameBuf[:n], &msg)
			if err != nil {
				// TODO: what happens on decode error
				panic(err)
			}
			var ext map[string]interface{}
			if msg.Ext == nil {
				ext = make(map[string]interface{})
			} else {
				ext = msg.Ext.(map[string]interface{})
			}
			ext["route"] = routeKey
			msg.Ext = ext
			frame, err := json.Marshal(&msg)
			if err != nil {
				// TODO: what happens on encode error
				panic(err)
			}
			if os.Getenv("DEBUG") != "" {
				fmt.Println("<<<", string(frame))
			}
			_, err = endpoint.upstream.Write(frame)
			if err != nil {
				// TODO: handle upstream write error
				// remove upstream endpoint?
				break
			}
		}
	}}
	s.ServeHTTP(w, r)
}

func HandleBackend(w http.ResponseWriter, r *http.Request) {
	if r.URL.Query().Get("secret") == "" {
		http.Error(w, "Secret required", http.StatusBadRequest)
		return
	}
	s := websocket.Server{Handler: func(ws *websocket.Conn) {
		endpoint := &Endpoint{
			path:    ws.Request().URL.Path,
			secret:  ws.Request().URL.Query().Get("secret"),
			counter: 0,
			clients: make(map[string]*websocket.Conn),
		}
		AcceptSimplexHandshake(ws) // TODO handle error
		endpoint.upstream = ws
		mu.Lock()
		old, exists := endpoints[endpoint.path]
		if exists {
			old.upstream.Close()
		}
		endpoints[endpoint.path] = endpoint
		mu.Unlock()
		log.Println("Endpoint", endpoint.path, "backend online")
		for {
			frame := make([]byte, simplex.MaxFrameSize)
			n, err := ws.Read(frame)
			if err != nil {
				// TODO: what happens on read error
				log.Println("read err")
				break
			}
			var msg simplex.Message
			err = json.Unmarshal(frame[:n], &msg)
			if err != nil {
				// TODO: what happens on decode error
				panic(err)
			}
			if msg.Ext == nil {
				log.Println("no ext")
				continue
			}
			ext, ok := msg.Ext.(map[string]interface{})
			if !ok {
				log.Println("ext not object")
				continue
			}
			routeKey := ext["route"].(string)
			endpoint.Lock()
			clientConn, ok := endpoint.clients[routeKey]
			endpoint.Unlock()
			if !ok {
				log.Println("routekey not found")
				continue
			}
			if os.Getenv("DEBUG") != "" {
				fmt.Println(">>>", string(frame[:n]))
			}
			_, err = clientConn.Write(frame[:n])
			if err != nil {
				endpoint.Lock()
				delete(endpoint.clients, routeKey)
				endpoint.Unlock()
			}
		}
		log.Println("Endpoint", endpoint.path, "backend offline")
	}}
	s.ServeHTTP(w, r)
}

func Handler(w http.ResponseWriter, r *http.Request) {
	log.Println(r.Header.Get("x-forwarded-proto"))
	if r.Header.Get("x-forwarded-proto") != "https" && os.Getenv("NOTLS") == "" {
		http.Error(w, "TLS required", http.StatusForbidden)
		return
	}
	if r.URL.Query().Get("token") == os.Getenv("TOKEN") {
		HandleBackend(w, r)
	} else {
		HandleClient(w, r)
	}
}

func main() {
	endpoints = make(map[string]*Endpoint)
	http.HandleFunc("/", Handler)
	port := ":" + os.Getenv("PORT")
	log.Println("Simplex gateway started on", port, "...")
	log.Fatal(http.ListenAndServe(port, nil))
}
<|endoftext|>


<commit_before>package gateways

import (
	"fmt"
	"strings"

	"github.com/stripe/stripe-go"
	"github.com/stripe/stripe-go/client"

	"github.com/ghmeier/bloodlines/config"
	"github.com/ghmeier/coinage/models"
	tmodels "github.com/jakelong95/TownCenter/models"
	item "github.com/lcollin/warehouse/models"
)

/*Stripe wraps the stripe-go api for coinage use*/
type Stripe interface {
	NewCustomer(token string, userID string) (string, error)
	GetCustomer(id string) (*stripe.Customer, error)
	DeleteCustomer(id string) error
	AddSource(id string, token string) (*stripe.Customer, error)
	NewAccount(user *tmodels.User, roaster *tmodels.Roaster) (*stripe.Account, error)
	NewPlan(secret string, item *item.Item, freq models.Frequency) (*stripe.Plan, error)
	GetPlan(secret string, pid string) (*stripe.Plan, error)
	Subscribe(id string, planID string) (*stripe.Sub, error)
}

type stripeS struct {
	config config.Stripe
	c      *client.API
}

/*NewStripe initializes and returns a new Stripe implementation configured
  by the provided config*/
func NewStripe(config config.Stripe) Stripe {
	s := &stripeS{
		config: config,
		c:      client.New(config.Secret, nil),
	}

	return s
}

func (s *stripeS) NewCustomer(token string, userID string) (string, error) {
	params := &stripe.CustomerParams{
		Desc: fmt.Sprintf("Customer for user: %s", userID),
	}

	params.SetSource(token)
	c, err := s.c.Customers.New(params)
	if err != nil {
		return "", err
	}
	return c.ID, err
}

/*GetCustomer returns a stripe customer by their cutsomerID*/
func (s *stripeS) GetCustomer(id string) (*stripe.Customer, error) {
	c, err := s.c.Customers.Get(id, nil)
	if err != nil {
		return nil, err
	}

	return c, nil
}

/*DeleteCustomer removes customer from stripe by customer id*/
func (s *stripeS) DeleteCustomer(id string) error {
	_, err := s.c.Customers.Del(id)
	return err
}

/*AddSource creates and adds a new Default Source for the customer*/
func (s *stripeS) AddSource(id string, token string) (*stripe.Customer, error) {
	params := &stripe.CustomerParams{
		Source: &stripe.SourceParams{Token: token},
	}

	c, err := s.c.Customers.Update(id, params)
	if err != nil {
		return nil, err
	}

	return c, nil
}

func (s *stripeS) NewAccount(user *tmodels.User, roaster *tmodels.Roaster) (*stripe.Account, error) {
	params := &stripe.AccountParams{
		Managed:      true,
		Country:      "US",
		Email:        roaster.Email,
		BusinessName: roaster.Name,
		LegalEntity: &stripe.LegalEntity{
			BusinessName: roaster.Name,
			Address: stripe.Address{
				City:    roaster.AddressCity,
				Country: "US",
				Line1:   roaster.AddressLine1,
				Line2:   roaster.AddressLine2,
				Zip:     roaster.AddressZip,
				State:   roaster.AddressState,
			},
			PersonalAddress: stripe.Address{
				City:    user.AddressCity,
				Country: "US",
				Line1:   user.AddressLine1,
				Line2:   user.AddressLine2,
				Zip:     user.AddressZip,
				State:   user.AddressState,
			},
			First:       user.FirstName,
			Last:        user.LastName,
			PhoneNumber: roaster.Phone,
			Type:        "company",
		},
	}

	account, err := s.c.Account.New(params)
	if err != nil {
		return nil, err
	}

	return account, nil
}

func (s *stripeS) NewPlan(secret string, item *item.Item, freq models.Frequency) (*stripe.Plan, error) {
	interval, ok := models.ToFrequency(freq)
	if !ok {
		return nil, fmt.Errorf("ERROR: no frequency for interval %s", freq)
	}

	client := client.New(secret, nil)
	params := &stripe.PlanParams{
		ID:            fmt.Sprintf("%s-%s", item.ID.String(), string(freq)),
		Amount:        uint64(item.ConsumerPrice * 100),
		Currency:      "usd",
		Interval:      "week",
		IntervalCount: uint64(interval),
		Name:          fmt.Sprintf("%s %s", item.Name, string(freq)),
		Statement:     strings.fmt.Sprintf("exp-%18s", item.Name),
	}
	params.AddMeta("itemId", item.ID.String())
	plan, err := client.Plans.New(params)

	if err != nil {
		return nil, err
	}

	return plan, nil
}

func (s *stripeS) GetPlan(secret string, pid string) (*stripe.Plan, error) {
	client := client.New(secret, nil)
	plan, err := client.Plans.Get(pid, nil)
	if err != nil {
		return nil, err
	}

	return plan, nil
}

func (s *stripeS) Subscribe(id string, planID string) (*stripe.Sub, error) {
	sub, err := s.c.Subs.New(&stripe.SubParams{Customer: id, Plan: planID})
	if err != nil {
		return nil, err
	}

	return sub, nil
}
<commit_msg>Fix width of names<commit_after>package gateways

import (
	"fmt"

	"github.com/stripe/stripe-go"
	"github.com/stripe/stripe-go/client"

	"github.com/ghmeier/bloodlines/config"
	"github.com/ghmeier/coinage/models"
	tmodels "github.com/jakelong95/TownCenter/models"
	item "github.com/lcollin/warehouse/models"
)

/*Stripe wraps the stripe-go api for coinage use*/
type Stripe interface {
	NewCustomer(token string, userID string) (string, error)
	GetCustomer(id string) (*stripe.Customer, error)
	DeleteCustomer(id string) error
	AddSource(id string, token string) (*stripe.Customer, error)
	NewAccount(user *tmodels.User, roaster *tmodels.Roaster) (*stripe.Account, error)
	NewPlan(secret string, item *item.Item, freq models.Frequency) (*stripe.Plan, error)
	GetPlan(secret string, pid string) (*stripe.Plan, error)
	Subscribe(id string, planID string) (*stripe.Sub, error)
}

type stripeS struct {
	config config.Stripe
	c      *client.API
}

/*NewStripe initializes and returns a new Stripe implementation configured
  by the provided config*/
func NewStripe(config config.Stripe) Stripe {
	s := &stripeS{
		config: config,
		c:      client.New(config.Secret, nil),
	}

	return s
}

func (s *stripeS) NewCustomer(token string, userID string) (string, error) {
	params := &stripe.CustomerParams{
		Desc: fmt.Sprintf("Customer for user: %s", userID),
	}

	params.SetSource(token)
	c, err := s.c.Customers.New(params)
	if err != nil {
		return "", err
	}
	return c.ID, err
}

/*GetCustomer returns a stripe customer by their cutsomerID*/
func (s *stripeS) GetCustomer(id string) (*stripe.Customer, error) {
	c, err := s.c.Customers.Get(id, nil)
	if err != nil {
		return nil, err
	}

	return c, nil
}

/*DeleteCustomer removes customer from stripe by customer id*/
func (s *stripeS) DeleteCustomer(id string) error {
	_, err := s.c.Customers.Del(id)
	return err
}

/*AddSource creates and adds a new Default Source for the customer*/
func (s *stripeS) AddSource(id string, token string) (*stripe.Customer, error) {
	params := &stripe.CustomerParams{
		Source: &stripe.SourceParams{Token: token},
	}

	c, err := s.c.Customers.Update(id, params)
	if err != nil {
		return nil, err
	}

	return c, nil
}

func (s *stripeS) NewAccount(user *tmodels.User, roaster *tmodels.Roaster) (*stripe.Account, error) {
	params := &stripe.AccountParams{
		Managed:      true,
		Country:      "US",
		Email:        roaster.Email,
		BusinessName: roaster.Name,
		LegalEntity: &stripe.LegalEntity{
			BusinessName: roaster.Name,
			Address: stripe.Address{
				City:    roaster.AddressCity,
				Country: "US",
				Line1:   roaster.AddressLine1,
				Line2:   roaster.AddressLine2,
				Zip:     roaster.AddressZip,
				State:   roaster.AddressState,
			},
			PersonalAddress: stripe.Address{
				City:    user.AddressCity,
				Country: "US",
				Line1:   user.AddressLine1,
				Line2:   user.AddressLine2,
				Zip:     user.AddressZip,
				State:   user.AddressState,
			},
			First:       user.FirstName,
			Last:        user.LastName,
			PhoneNumber: roaster.Phone,
			Type:        "company",
		},
	}

	account, err := s.c.Account.New(params)
	if err != nil {
		return nil, err
	}

	return account, nil
}

func (s *stripeS) NewPlan(secret string, item *item.Item, freq models.Frequency) (*stripe.Plan, error) {
	interval, ok := models.ToFrequency(freq)
	if !ok {
		return nil, fmt.Errorf("ERROR: no frequency for interval %s", freq)
	}

	client := client.New(secret, nil)
	params := &stripe.PlanParams{
		ID:            fmt.Sprintf("%s-%s", item.ID.String(), string(freq)),
		Amount:        uint64(item.ConsumerPrice * 100),
		Currency:      "usd",
		Interval:      "week",
		IntervalCount: uint64(interval),
		Name:          fmt.Sprintf("%s %s", item.Name, string(freq)),
		Statement:     fmt.Sprintf("exp-%.18s", item.Name),
	}
	params.AddMeta("itemId", item.ID.String())
	plan, err := client.Plans.New(params)

	if err != nil {
		return nil, err
	}

	return plan, nil
}

func (s *stripeS) GetPlan(secret string, pid string) (*stripe.Plan, error) {
	client := client.New(secret, nil)
	plan, err := client.Plans.Get(pid, nil)
	if err != nil {
		return nil, err
	}

	return plan, nil
}

func (s *stripeS) Subscribe(id string, planID string) (*stripe.Sub, error) {
	sub, err := s.c.Subs.New(&stripe.SubParams{Customer: id, Plan: planID})
	if err != nil {
		return nil, err
	}

	return sub, nil
}
<|endoftext|>


<commit_before>package model

import "fmt"
import "net/url"
import "net/http"
import "net/http/cookiejar"
import "github.com/ishiikurisu/moneylog"
import "mime/multipart"
import "bufio"
import "time"

/*****************************
 * LOCAL STORAGE DEFINITIONS *
 *****************************/

// This is the structure that will deal with the session's cookies. It will
// need to know which URL these cookies relate to, and its logic is already
// coded to understand the app's behaviour.
type LocalStorage struct {
    // The actual data. The logic of this application. The reason we are here.
    MoneyLog moneylog.Log

    // The structure that will deal with our cookies.
    CookieJar *cookiejar.Jar

    // This is the URL these cookies refer to.
    Url *url.URL

    // This is where the current log is stored on local memory
    LogFile string
}

// Creates a cookie storage structure.
func NewLocalStorage() (*LocalStorage, error) {
    var storage *LocalStorage = nil
    jar, oops := cookiejar.New(nil)
    url, shit := url.Parse(GetAddress())

    if oops == nil && shit == nil {
        url.Scheme = "http"
        url.Host = "heroku.com"
        s := LocalStorage {
            // TODO Implement actual cookie jar
            MoneyLog: moneylog.EmptyLog(),
            CookieJar: jar,
            Url: url,
            LogFile: "log.txt",
        }
        storage = &s
    } else {
        fmt.Println(shit)
    }

    return storage, oops
}

// Extracts the current money log based on the store cookies. If there is no
// log, a string of length 0 is returned.
func (storage *LocalStorage) GetLog(w http.ResponseWriter, r *http.Request) string {
    outlet := ""
    cookie, err := r.Cookie("MoneyLog")

    if err == nil {
        outlet = cookie.Value
    } else {
        fmt.Println(err)
    }

    return outlet
}

// Extracts stuff from raw strings
func stuffFromRaw(rawDescription, rawValue string) (string, float64) {
    var description string
    var value float64

    description = rawDescription
    fmt.Sscanf(rawValue, "%F", &value)

    return description, value
}

func (storage *LocalStorage) AddLogFromFile(mmf multipart.File) string {
    buffer := bufio.NewReader(mmf)
    current := ReadField(buffer)
    outlet := ""

    for current != "...," {
        outlet += current
        outlet += ","
        current = ReadField(buffer)
    }

    outlet += current
    return outlet
}

func ReadField(reader *bufio.Reader) string {
    raw := make([]byte, 0)
    raw, err := reader.ReadBytes(',')
    if err != nil {
        panic(err)
    }
    return string(raw)
}

func (storage *LocalStorage) AddEntryFromRawAndSaveLog(d, v string, w http.ResponseWriter, r *http.Request) (http.ResponseWriter, *http.Request) {
    description, value := stuffFromRaw(d, v)
    raw := storage.GetLog(w, r)
    log := moneylog.LogFromString(raw)
    log.Add(description, value)
    cookie := http.Cookie {
        Name: "MoneyLog",
        Value: log.ToString(),
        Expires: time.Date(2020, time.May, 25, 23, 0, 0, 0, time.UTC),
    }
    http.SetCookie(w, &cookie)
    return w, r
}

func (storage *LocalStorage) AddLogFromRawAndSaveLog(raw string, w http.ResponseWriter, r *http.Request) (http.ResponseWriter, *http.Request) {
    log := moneylog.LogFromString(raw)
    cookie := http.Cookie {
        Name: "MoneyLog",
        Value: log.ToString(),
    }
    http.SetCookie(w, &cookie)
    return w, r
}
<commit_msg>Fixing log creation from upload<commit_after>package model

import "fmt"
import "net/url"
import "net/http"
import "net/http/cookiejar"
import "github.com/ishiikurisu/moneylog"
import "mime/multipart"
import "bufio"
import "time"

/*****************************
 * LOCAL STORAGE DEFINITIONS *
 *****************************/

// This is the structure that will deal with the session's cookies. It will
// need to know which URL these cookies relate to, and its logic is already
// coded to understand the app's behaviour.
type LocalStorage struct {
    // The actual data. The logic of this application. The reason we are here.
    MoneyLog moneylog.Log

    // The structure that will deal with our cookies.
    CookieJar *cookiejar.Jar

    // This is the URL these cookies refer to.
    Url *url.URL

    // This is where the current log is stored on local memory
    LogFile string
}

// Creates a cookie storage structure.
func NewLocalStorage() (*LocalStorage, error) {
    var storage *LocalStorage = nil
    jar, oops := cookiejar.New(nil)
    url, shit := url.Parse(GetAddress())

    if oops == nil && shit == nil {
        url.Scheme = "http"
        url.Host = "heroku.com"
        s := LocalStorage {
            // TODO Implement actual cookie jar
            MoneyLog: moneylog.EmptyLog(),
            CookieJar: jar,
            Url: url,
            LogFile: "log.txt",
        }
        storage = &s
    } else {
        fmt.Println(shit)
    }

    return storage, oops
}

// Extracts the current money log based on the store cookies. If there is no
// log, a string of length 0 is returned.
func (storage *LocalStorage) GetLog(w http.ResponseWriter, r *http.Request) string {
    outlet := ""
    cookie, err := r.Cookie("MoneyLog")

    if err == nil {
        outlet = cookie.Value
    } else {
        fmt.Println(err)
    }

    return outlet
}

// Extracts stuff from raw strings
func stuffFromRaw(rawDescription, rawValue string) (string, float64) {
    var description string
    var value float64

    description = rawDescription
    fmt.Sscanf(rawValue, "%F", &value)

    return description, value
}

func (storage *LocalStorage) AddLogFromFile(mmf multipart.File) string {
    buffer := bufio.NewReader(mmf)
    current := ReadField(buffer)
    outlet := ""

    for current != "...," {
        outlet += current
        outlet += ","
        current = ReadField(buffer)
    }

    outlet += current
    return outlet
}

func ReadField(reader *bufio.Reader) string {
    raw := make([]byte, 0)
    raw, err := reader.ReadBytes(',')
    if err != nil {
        panic(err)
    }
    return string(raw)
}

func (storage *LocalStorage) AddEntryFromRawAndSaveLog(d, v string, w http.ResponseWriter, r *http.Request) (http.ResponseWriter, *http.Request) {
    description, value := stuffFromRaw(d, v)
    raw := storage.GetLog(w, r)
    log := moneylog.LogFromString(raw)
    log.Add(description, value)
    cookie := http.Cookie {
        Name: "MoneyLog",
        Value: log.ToString(),
        Expires: time.Date(2020, time.May, 25, 23, 0, 0, 0, time.UTC),
    }
    http.SetCookie(w, &cookie)
    return w, r
}

func (storage *LocalStorage) AddLogFromRawAndSaveLog(raw string, w http.ResponseWriter, r *http.Request) (http.ResponseWriter, *http.Request) {
    log := moneylog.LogFromString(raw)
    cookie := http.Cookie {
        Name: "MoneyLog",
        Value: log.ToString(),
        Expires: time.Date(2020, time.May, 25, 23, 0, 0, 0, time.UTC),
    }
    http.SetCookie(w, &cookie)
    return w, r
}
<|endoftext|>


<commit_before>/*
Package xkcd allows access to metadata for xkcd comics.
*/
package xkcd

import (
	"encoding/json"
	"fmt"
	"net/http"
)

const (
	currentUrl  = "http://xkcd.com/info.0.json"
	templateUrl = "http://xkcd.com/%v/info.0.json"
)

type Comic struct {
	Num       int    `json:"num"`
	Title     string `json:"title"`
	SafeTitle string `json:"safe_title"`

	Img string `json:"img"`
	Alt string `json:"alt"`

	Year  string `json:"year"`
	Month string `json:"month"`
	Day   string `json:"day"`

	News       string `json:"news"`
	Link       string `json:"link"`
	Transcript string `json:"transcript"`
}

// Get returns the information about the xkcd comic number `n'.
func Get(n int) (*Comic, error) {
	url := fmt.Sprintf(templateUrl, n)
	return getByUrl(url)
}

// GetCurrent returns information for the newest xkcd comic.
func GetCurrent() (*Comic, error) {
	return getByUrl(currentUrl)
}

// getByUrl returns infomation downloaded from `url'.
func getByUrl(url string) (*Comic, error) {
	resp, err := http.Get(url)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	// TODO: handle status codes.

	dec := json.NewDecoder(resp.Body)

	c := new(Comic)
	err = dec.Decode(c)
	return c, err
}
<commit_msg>Fixed: Handling of HTTP Status codes.<commit_after>/*
Package xkcd allows access to metadata for xkcd comics.
*/
package xkcd

import (
	"encoding/json"
	"errors"
	"fmt"
	"net/http"
)

const (
	currentUrl  = "http://xkcd.com/info.0.json"
	templateUrl = "http://xkcd.com/%v/info.0.json"
)

type Comic struct {
	Num       int    `json:"num"`
	Title     string `json:"title"`
	SafeTitle string `json:"safe_title"`

	Img string `json:"img"`
	Alt string `json:"alt"`

	Year  string `json:"year"`
	Month string `json:"month"`
	Day   string `json:"day"`

	News       string `json:"news"`
	Link       string `json:"link"`
	Transcript string `json:"transcript"`
}

// Get returns the information about the xkcd comic number `n'.
func Get(n int) (*Comic, error) {
	url := fmt.Sprintf(templateUrl, n)
	return getByUrl(url)
}

// GetCurrent returns information for the newest xkcd comic.
func GetCurrent() (*Comic, error) {
	return getByUrl(currentUrl)
}

// getByUrl returns infomation downloaded from `url'.
func getByUrl(url string) (*Comic, error) {
	resp, err := http.Get(url)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	if resp.StatusCode >= 400 {
		return nil, errors.New(resp.Status)
	}

	dec := json.NewDecoder(resp.Body)

	c := new(Comic)
	err = dec.Decode(c)
	return c, err
}
<|endoftext|>


<commit_before>package models

import (
	"time"
)

type Idea struct {
	Id           int `orm:"pk;auto"`
	Title        string    `orm:"size(100)"`
	CreationDate time.Time `orm:"auto_now_add;type(datetime)"`
	EventDate    time.Time `orm:"type(datetime)"`
	Votes        int
	Description  string    `orm:"type(text)"`
	Status       string    `orm:"size(10)"`
	Creator      *User     `orm:"rel(fk)"`
	Assignees    []*User   `orm:"rel(m2m)"`
}

type User struct {
	Id       int `orm:"pk;auto"`
	Key      string  `orm:"size(100)"`
	Username string  `orm:"size(100)"`
	Fullname string  `orm:"size(100)"`
	Mail     string  `orm:"size(100)"`
	Role     string  `orm:"size(10);default(BASIC)"`
	MyIdeas  []*Idea `orm:"reverse(many)" json:"-"`
	Ideas    []*Idea `orm:"reverse(many)" json:"-"`
}
<commit_msg>New model for comments<commit_after>package models

import (
	"time"
)

type Idea struct {
	Id           int        `orm:"pk;auto"`
	CreationDate time.Time  `orm:"auto_now_add;type(datetime)"`
	EventDate    time.Time  `orm:"type(datetime)"`
	Title        string     `orm:"size(100)"`
	Description  string     `orm:"type(text)"`
	Status       string     `orm:"size(10)"`
	Creator      *User      `orm:"rel(fk)"`
	Voters       []*User    `orm:"rel(m2m);rel_table(user_idea_votes)"`
	Assignees    []*User    `orm:"rel(m2m);rel_table(user_idea_assignees)"`
	Comments     []*Comment `orm:"reverse(many)"`
}

type User struct {
	Id       int        `orm:"pk;auto"`
	Key      string     `orm:"size(100)"`
	Username string     `orm:"size(100)"`
	Fullname string     `orm:"size(100)"`
	Mail     string     `orm:"size(100)"`
	Role     string     `orm:"size(10);default(BASIC)"`
	MyIdeas  []*Idea    `orm:"reverse(many)" json:"-"`
	Votes    []*Idea    `orm:"reverse(many)" json:"-"`
	Ideas    []*Idea    `orm:"reverse(many)" json:"-"`
	Comments []*Comment `orm:"reverse(many)" json:"-"`
}

type Comment struct {
	Id    int    `orm:"pk;auto"`
	Title string `orm:"size(256)"`
	Body  string `orm:"type(text)"`
	User  *User  `orm:"rel(fk)"`
	Idea  *Idea  `orm:"rel(fk)"`
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"os"
	"strconv"
	"strings"
	"unicode/utf8"
)

func (e *SetExpr) eval(app *App, args []string) {
	switch e.opt {
	case "hidden":
		gOpts.hidden = true
		app.nav.renew(app.nav.height)
	case "nohidden":
		gOpts.hidden = false
		app.nav.renew(app.nav.height)
	case "hidden!":
		gOpts.hidden = !gOpts.hidden
		app.nav.renew(app.nav.height)
	case "preview":
		gOpts.preview = true
	case "nopreview":
		gOpts.preview = false
	case "preview!":
		gOpts.preview = !gOpts.preview
	case "dirfirst":
		gOpts.dirfirst = true
		app.nav.renew(app.nav.height)
	case "nodirfirst":
		gOpts.dirfirst = false
		app.nav.renew(app.nav.height)
	case "dirfirst!":
		gOpts.dirfirst = !gOpts.dirfirst
		app.nav.renew(app.nav.height)
	case "scrolloff":
		n, err := strconv.Atoi(e.val)
		if err != nil {
			msg := fmt.Sprintf("scrolloff: %s", err)
			app.ui.message = msg
			log.Print(msg)
			return
		}
		if n < 0 {
			msg := "scrolloff: value should be a non-negative number"
			app.ui.message = msg
			log.Print(msg)
			return
		}
		max := app.ui.wins[0].h / 2
		if n > max {
			n = max
		}
		gOpts.scrolloff = n
	case "tabstop":
		n, err := strconv.Atoi(e.val)
		if err != nil {
			msg := fmt.Sprintf("tabstop: %s", err)
			app.ui.message = msg
			log.Print(msg)
			return
		}
		if n <= 0 {
			msg := "tabstop: value should be a positive number"
			app.ui.message = msg
			log.Print(msg)
			return
		}
		gOpts.tabstop = n
	case "ifs":
		gOpts.ifs = e.val
	case "previewer":
		gOpts.previewer = strings.Replace(e.val, "~", envHome, -1)
	case "shell":
		gOpts.shell = e.val
	case "showinfo":
		if e.val != "none" && e.val != "size" && e.val != "time" {
			msg := "showinfo should either be 'none', 'size' or 'time'"
			app.ui.message = msg
			log.Print(msg)
			return
		}
		gOpts.showinfo = e.val
	case "sortby":
		if e.val != "name" && e.val != "size" && e.val != "time" {
			msg := "sortby should either be 'name', 'size' or 'time'"
			app.ui.message = msg
			log.Print(msg)
			return
		}
		gOpts.sortby = e.val
		app.nav.renew(app.nav.height)
	case "ratios":
		toks := strings.Split(e.val, ":")
		var rats []int
		for _, s := range toks {
			i, err := strconv.Atoi(s)
			if err != nil {
				msg := fmt.Sprintf("ratios: %s", err)
				app.ui.message = msg
				log.Print(msg)
				return
			}
			rats = append(rats, i)
		}
		gOpts.ratios = rats
		app.ui = newUI()
	default:
		msg := fmt.Sprintf("unknown option: %s", e.opt)
		app.ui.message = msg
		log.Print(msg)
	}
}

func (e *MapExpr) eval(app *App, args []string) {
	if e.expr == nil {
		delete(gOpts.keys, e.keys)
		return
	}
	gOpts.keys[e.keys] = e.expr
}

func (e *CmdExpr) eval(app *App, args []string) {
	if e.expr == nil {
		delete(gOpts.cmds, e.name)
		return
	}
	gOpts.cmds[e.name] = e.expr
}

func splitKeys(s string) (keys []string) {
	for i := 0; i < len(s); {
		c, w := utf8.DecodeRuneInString(s[i:])
		if c != '<' {
			keys = append(keys, s[i:i+w])
			i += w
		} else {
			j := i + w
			for c != '>' && j < len(s) {
				c, w = utf8.DecodeRuneInString(s[j:])
				j += w
			}
			keys = append(keys, s[i:j])
			i = j
		}
	}
	return
}

func (e *CallExpr) eval(app *App, args []string) {
	// TODO: check for extra toks in each case
	switch e.name {
	case "up":
		app.nav.up(1)
		app.ui.loadFile(app.nav)
	case "half-up":
		app.nav.up(app.nav.height / 2)
		app.ui.loadFile(app.nav)
	case "page-up":
		app.nav.up(app.nav.height)
		app.ui.loadFile(app.nav)
	case "down":
		app.nav.down(1)
		app.ui.loadFile(app.nav)
	case "half-down":
		app.nav.down(app.nav.height / 2)
		app.ui.loadFile(app.nav)
	case "page-down":
		app.nav.down(app.nav.height)
		app.ui.loadFile(app.nav)
	case "updir":
		if err := app.nav.updir(); err != nil {
			app.ui.message = err.Error()
			log.Print(err)
			return
		}
		app.ui.loadFile(app.nav)
	case "open":
		err := app.nav.open()
		if err == nil {
			app.ui.loadFile(app.nav)
			return
		}
		if err != ErrNotDir {
			app.ui.message = err.Error()
			log.Print(err)
			return
		}

		if gSelectionPath != "" {
			out, err := os.Create(gSelectionPath)
			if err != nil {
				log.Printf("opening selection file: %s", err)
				return
			}
			defer out.Close()

			var path string
			if len(app.nav.marks) != 0 {
				marks := app.nav.currMarks()
				path = strings.Join(marks, "\n")
			} else if curr, err := app.nav.currFile(); err == nil {
				path = curr.Path
			} else {
				return
			}

			_, err = out.WriteString(path)
			if err != nil {
				log.Printf("writing selection file: %s", err)
			}

			go func() { app.quit <- true }()

			return
		}

		if cmd, ok := gOpts.cmds["open-file"]; ok {
			cmd.eval(app, e.args)
		}
	case "quit":
		go func() { app.quit <- true }()
	case "bot":
		app.nav.bot()
		app.ui.loadFile(app.nav)
	case "top":
		app.nav.top()
		app.ui.loadFile(app.nav)
	case "read":
		s := app.ui.prompt(app.nav, ":")
		if len(s) == 0 {
			return
		}
		log.Printf("command: %s", s)
		p := newParser(strings.NewReader(s))
		for p.parse() {
			p.expr.eval(app, nil)
		}
		if p.err != nil {
			app.ui.message = p.err.Error()
			log.Print(p.err)
		}
	case "read-shell":
		s := app.ui.prompt(app.nav, "$")
		if len(s) == 0 {
			return
		}
		log.Printf("shell: %s", s)
		app.runShell(s, nil, false, false)
	case "read-shell-wait":
		s := app.ui.prompt(app.nav, "!")
		if len(s) == 0 {
			return
		}
		log.Printf("shell-wait: %s", s)
		app.runShell(s, nil, true, false)
	case "read-shell-async":
		s := app.ui.prompt(app.nav, "&")
		if len(s) == 0 {
			return
		}
		log.Printf("shell-async: %s", s)
		app.runShell(s, nil, false, true)
	case "search":
		s := app.ui.prompt(app.nav, "/")
		if len(s) == 0 {
			return
		}
		log.Printf("search: %s", s)
		app.ui.message = "sorry, search is not implemented yet!"
		// TODO: implement
	case "search-back":
		s := app.ui.prompt(app.nav, "?")
		if len(s) == 0 {
			return
		}
		log.Printf("search-back: %s", s)
		app.ui.message = "sorry, search-back is not implemented yet!"
		// TODO: implement
	case "toggle":
		app.nav.toggle()
	case "invert":
		app.nav.invert()
	case "yank":
		if err := app.nav.save(true); err != nil {
			msg := fmt.Sprintf("yank: %s", err)
			app.ui.message = msg
			log.Printf(msg)
			return
		}
		if len(app.nav.marks) == 0 {
			app.ui.message = "file saved for copy"
		} else {
			app.ui.message = fmt.Sprintf("%d files saved for copy", len(app.nav.marks))
		}
		app.nav.marks = make(map[string]bool)
	case "delete":
		if err := app.nav.save(false); err != nil {
			msg := fmt.Sprintf("delete: %s", err)
			app.ui.message = msg
			log.Printf(msg)
			return
		}
		if len(app.nav.marks) == 0 {
			app.ui.message = "file saved for move"
		} else {
			app.ui.message = fmt.Sprintf("%d files saved for move", len(app.nav.marks))
		}
		app.nav.marks = make(map[string]bool)
	case "put":
		if err := app.nav.put(); err != nil {
			msg := fmt.Sprintf("put: %s", err)
			app.ui.message = msg
			log.Printf(msg)
			return
		}
		app.nav.renew(app.nav.height)
		app.nav.save(false)
		app.nav.saves = make(map[string]bool)
		saveFiles(nil, false)
	case "renew":
		app.ui.sync()
		app.ui.renew()
		app.nav.renew(app.ui.wins[0].h)
	case "echo":
		app.ui.message = strings.Join(e.args, " ")
	case "cd":
		path := "~"
		if len(e.args) > 0 {
			path = e.args[0]
		}
		if err := app.nav.cd(path); err != nil {
			app.ui.message = err.Error()
			log.Print(err)
			return
		}
		app.ui.loadFile(app.nav)
	case "push":
		if len(e.args) > 0 {
			app.ui.keysbuf = append(app.ui.keysbuf, splitKeys(e.args[0])...)
		}
	default:
		cmd, ok := gOpts.cmds[e.name]
		if !ok {
			msg := fmt.Sprintf("command not found: %s", e.name)
			app.ui.message = msg
			log.Print(msg)
			return
		}
		cmd.eval(app, e.args)
	}
}

func (e *ExecExpr) eval(app *App, args []string) {
	switch e.pref {
	case "$":
		log.Printf("shell: %s -- %s", e, args)
		app.ui.clearMsg()
		app.runShell(e.expr, args, false, false)
		app.ui.loadFile(app.nav)
	case "!":
		log.Printf("shell-wait: %s -- %s", e, args)
		app.runShell(e.expr, args, true, false)
	case "&":
		log.Printf("shell-async: %s -- %s", e, args)
		app.runShell(e.expr, args, false, true)
	case "/":
		log.Printf("search: %s -- %s", e, args)
		// TODO: implement
	case "?":
		log.Printf("search-back: %s -- %s", e, args)
		// TODO: implement
	default:
		log.Printf("unknown execution prefix: %q", e.pref)
	}
}

func (e *ListExpr) eval(app *App, args []string) {
	for _, expr := range e.exprs {
		expr.eval(app, nil)
	}
}
<commit_msg>load current file when ratios is modified<commit_after>package main

import (
	"fmt"
	"log"
	"os"
	"strconv"
	"strings"
	"unicode/utf8"
)

func (e *SetExpr) eval(app *App, args []string) {
	switch e.opt {
	case "hidden":
		gOpts.hidden = true
		app.nav.renew(app.nav.height)
	case "nohidden":
		gOpts.hidden = false
		app.nav.renew(app.nav.height)
	case "hidden!":
		gOpts.hidden = !gOpts.hidden
		app.nav.renew(app.nav.height)
	case "preview":
		gOpts.preview = true
	case "nopreview":
		gOpts.preview = false
	case "preview!":
		gOpts.preview = !gOpts.preview
	case "dirfirst":
		gOpts.dirfirst = true
		app.nav.renew(app.nav.height)
	case "nodirfirst":
		gOpts.dirfirst = false
		app.nav.renew(app.nav.height)
	case "dirfirst!":
		gOpts.dirfirst = !gOpts.dirfirst
		app.nav.renew(app.nav.height)
	case "scrolloff":
		n, err := strconv.Atoi(e.val)
		if err != nil {
			msg := fmt.Sprintf("scrolloff: %s", err)
			app.ui.message = msg
			log.Print(msg)
			return
		}
		if n < 0 {
			msg := "scrolloff: value should be a non-negative number"
			app.ui.message = msg
			log.Print(msg)
			return
		}
		max := app.ui.wins[0].h / 2
		if n > max {
			n = max
		}
		gOpts.scrolloff = n
	case "tabstop":
		n, err := strconv.Atoi(e.val)
		if err != nil {
			msg := fmt.Sprintf("tabstop: %s", err)
			app.ui.message = msg
			log.Print(msg)
			return
		}
		if n <= 0 {
			msg := "tabstop: value should be a positive number"
			app.ui.message = msg
			log.Print(msg)
			return
		}
		gOpts.tabstop = n
	case "ifs":
		gOpts.ifs = e.val
	case "previewer":
		gOpts.previewer = strings.Replace(e.val, "~", envHome, -1)
	case "shell":
		gOpts.shell = e.val
	case "showinfo":
		if e.val != "none" && e.val != "size" && e.val != "time" {
			msg := "showinfo should either be 'none', 'size' or 'time'"
			app.ui.message = msg
			log.Print(msg)
			return
		}
		gOpts.showinfo = e.val
	case "sortby":
		if e.val != "name" && e.val != "size" && e.val != "time" {
			msg := "sortby should either be 'name', 'size' or 'time'"
			app.ui.message = msg
			log.Print(msg)
			return
		}
		gOpts.sortby = e.val
		app.nav.renew(app.nav.height)
	case "ratios":
		toks := strings.Split(e.val, ":")
		var rats []int
		for _, s := range toks {
			i, err := strconv.Atoi(s)
			if err != nil {
				msg := fmt.Sprintf("ratios: %s", err)
				app.ui.message = msg
				log.Print(msg)
				return
			}
			rats = append(rats, i)
		}
		gOpts.ratios = rats
		app.ui = newUI()
		app.ui.loadFile(app.nav)
	default:
		msg := fmt.Sprintf("unknown option: %s", e.opt)
		app.ui.message = msg
		log.Print(msg)
	}
}

func (e *MapExpr) eval(app *App, args []string) {
	if e.expr == nil {
		delete(gOpts.keys, e.keys)
		return
	}
	gOpts.keys[e.keys] = e.expr
}

func (e *CmdExpr) eval(app *App, args []string) {
	if e.expr == nil {
		delete(gOpts.cmds, e.name)
		return
	}
	gOpts.cmds[e.name] = e.expr
}

func splitKeys(s string) (keys []string) {
	for i := 0; i < len(s); {
		c, w := utf8.DecodeRuneInString(s[i:])
		if c != '<' {
			keys = append(keys, s[i:i+w])
			i += w
		} else {
			j := i + w
			for c != '>' && j < len(s) {
				c, w = utf8.DecodeRuneInString(s[j:])
				j += w
			}
			keys = append(keys, s[i:j])
			i = j
		}
	}
	return
}

func (e *CallExpr) eval(app *App, args []string) {
	// TODO: check for extra toks in each case
	switch e.name {
	case "up":
		app.nav.up(1)
		app.ui.loadFile(app.nav)
	case "half-up":
		app.nav.up(app.nav.height / 2)
		app.ui.loadFile(app.nav)
	case "page-up":
		app.nav.up(app.nav.height)
		app.ui.loadFile(app.nav)
	case "down":
		app.nav.down(1)
		app.ui.loadFile(app.nav)
	case "half-down":
		app.nav.down(app.nav.height / 2)
		app.ui.loadFile(app.nav)
	case "page-down":
		app.nav.down(app.nav.height)
		app.ui.loadFile(app.nav)
	case "updir":
		if err := app.nav.updir(); err != nil {
			app.ui.message = err.Error()
			log.Print(err)
			return
		}
		app.ui.loadFile(app.nav)
	case "open":
		err := app.nav.open()
		if err == nil {
			app.ui.loadFile(app.nav)
			return
		}
		if err != ErrNotDir {
			app.ui.message = err.Error()
			log.Print(err)
			return
		}

		if gSelectionPath != "" {
			out, err := os.Create(gSelectionPath)
			if err != nil {
				log.Printf("opening selection file: %s", err)
				return
			}
			defer out.Close()

			var path string
			if len(app.nav.marks) != 0 {
				marks := app.nav.currMarks()
				path = strings.Join(marks, "\n")
			} else if curr, err := app.nav.currFile(); err == nil {
				path = curr.Path
			} else {
				return
			}

			_, err = out.WriteString(path)
			if err != nil {
				log.Printf("writing selection file: %s", err)
			}

			go func() { app.quit <- true }()

			return
		}

		if cmd, ok := gOpts.cmds["open-file"]; ok {
			cmd.eval(app, e.args)
		}
	case "quit":
		go func() { app.quit <- true }()
	case "bot":
		app.nav.bot()
		app.ui.loadFile(app.nav)
	case "top":
		app.nav.top()
		app.ui.loadFile(app.nav)
	case "read":
		s := app.ui.prompt(app.nav, ":")
		if len(s) == 0 {
			return
		}
		log.Printf("command: %s", s)
		p := newParser(strings.NewReader(s))
		for p.parse() {
			p.expr.eval(app, nil)
		}
		if p.err != nil {
			app.ui.message = p.err.Error()
			log.Print(p.err)
		}
	case "read-shell":
		s := app.ui.prompt(app.nav, "$")
		if len(s) == 0 {
			return
		}
		log.Printf("shell: %s", s)
		app.runShell(s, nil, false, false)
	case "read-shell-wait":
		s := app.ui.prompt(app.nav, "!")
		if len(s) == 0 {
			return
		}
		log.Printf("shell-wait: %s", s)
		app.runShell(s, nil, true, false)
	case "read-shell-async":
		s := app.ui.prompt(app.nav, "&")
		if len(s) == 0 {
			return
		}
		log.Printf("shell-async: %s", s)
		app.runShell(s, nil, false, true)
	case "search":
		s := app.ui.prompt(app.nav, "/")
		if len(s) == 0 {
			return
		}
		log.Printf("search: %s", s)
		app.ui.message = "sorry, search is not implemented yet!"
		// TODO: implement
	case "search-back":
		s := app.ui.prompt(app.nav, "?")
		if len(s) == 0 {
			return
		}
		log.Printf("search-back: %s", s)
		app.ui.message = "sorry, search-back is not implemented yet!"
		// TODO: implement
	case "toggle":
		app.nav.toggle()
	case "invert":
		app.nav.invert()
	case "yank":
		if err := app.nav.save(true); err != nil {
			msg := fmt.Sprintf("yank: %s", err)
			app.ui.message = msg
			log.Printf(msg)
			return
		}
		if len(app.nav.marks) == 0 {
			app.ui.message = "file saved for copy"
		} else {
			app.ui.message = fmt.Sprintf("%d files saved for copy", len(app.nav.marks))
		}
		app.nav.marks = make(map[string]bool)
	case "delete":
		if err := app.nav.save(false); err != nil {
			msg := fmt.Sprintf("delete: %s", err)
			app.ui.message = msg
			log.Printf(msg)
			return
		}
		if len(app.nav.marks) == 0 {
			app.ui.message = "file saved for move"
		} else {
			app.ui.message = fmt.Sprintf("%d files saved for move", len(app.nav.marks))
		}
		app.nav.marks = make(map[string]bool)
	case "put":
		if err := app.nav.put(); err != nil {
			msg := fmt.Sprintf("put: %s", err)
			app.ui.message = msg
			log.Printf(msg)
			return
		}
		app.nav.renew(app.nav.height)
		app.nav.save(false)
		app.nav.saves = make(map[string]bool)
		saveFiles(nil, false)
	case "renew":
		app.ui.sync()
		app.ui.renew()
		app.nav.renew(app.ui.wins[0].h)
	case "echo":
		app.ui.message = strings.Join(e.args, " ")
	case "cd":
		path := "~"
		if len(e.args) > 0 {
			path = e.args[0]
		}
		if err := app.nav.cd(path); err != nil {
			app.ui.message = err.Error()
			log.Print(err)
			return
		}
		app.ui.loadFile(app.nav)
	case "push":
		if len(e.args) > 0 {
			app.ui.keysbuf = append(app.ui.keysbuf, splitKeys(e.args[0])...)
		}
	default:
		cmd, ok := gOpts.cmds[e.name]
		if !ok {
			msg := fmt.Sprintf("command not found: %s", e.name)
			app.ui.message = msg
			log.Print(msg)
			return
		}
		cmd.eval(app, e.args)
	}
}

func (e *ExecExpr) eval(app *App, args []string) {
	switch e.pref {
	case "$":
		log.Printf("shell: %s -- %s", e, args)
		app.ui.clearMsg()
		app.runShell(e.expr, args, false, false)
		app.ui.loadFile(app.nav)
	case "!":
		log.Printf("shell-wait: %s -- %s", e, args)
		app.runShell(e.expr, args, true, false)
	case "&":
		log.Printf("shell-async: %s -- %s", e, args)
		app.runShell(e.expr, args, false, true)
	case "/":
		log.Printf("search: %s -- %s", e, args)
		// TODO: implement
	case "?":
		log.Printf("search-back: %s -- %s", e, args)
		// TODO: implement
	default:
		log.Printf("unknown execution prefix: %q", e.pref)
	}
}

func (e *ListExpr) eval(app *App, args []string) {
	for _, expr := range e.exprs {
		expr.eval(app, nil)
	}
}
<|endoftext|>


<commit_before>// Copyright 2015 The Tango Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package xsrf

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

	"github.com/go-xweb/uuid"
	"github.com/lunny/tango"
)

const (
	XSRF_TAG string = "_xsrf"
)

type Xsrfer interface {
	CheckXsrf() bool
}

type NoCheck struct {
}

func (NoCheck) InitXsrfer(*tango.Context, time.Duration) {}

func (NoCheck) CheckXsrf() bool {
	return false
}

var _ Xsrfer = NoCheck{}

type XsrfChecker interface {
	SetXsrf(string, *tango.Context, time.Duration)
}

type Checker struct {
	XsrfValue string
	ctx *tango.Context
	timeout time.Duration
}

func (Checker) CheckXsrf() bool {
	return true
}

func (c *Checker) SetXsrf(v string, ctx *tango.Context, timeout time.Duration) {
	c.XsrfValue = v
	c.ctx = ctx
	c.timeout = timeout
}

func (c *Checker) XsrfFormHtml() template.HTML {
	return template.HTML(fmt.Sprintf(`<input type="hidden" name="%v" value="%v" />`,
		XSRF_TAG, c.XsrfValue))
}

func (c *Checker) Renew() {
	var val = uuid.NewRandom().String()
	var cookie = newCookie(XSRF_TAG, val, int64(c.timeout.Seconds()))
	c.ctx.Header().Set("Set-Cookie", cookie.String())
}

var _ XsrfChecker = &Checker{}

func New(timeout time.Duration) tango.HandlerFunc {
	return func(ctx *tango.Context) {
		var action interface{}
		if action = ctx.Action(); action == nil {
			ctx.Next()
			return
		}

		// if action implements check xsrf option and ask not check then return
		if checker, ok := action.(Xsrfer); ok && !checker.CheckXsrf() {
			ctx.Next()
			return
		}

		var val string = ""
		cookie, err := ctx.Req().Cookie(XSRF_TAG)
		if err != nil {
			val = uuid.NewRandom().String()
			cookie = newCookie(XSRF_TAG, val, int64(timeout.Seconds()))
			ctx.Header().Set("Set-Cookie", cookie.String())
		} else {
			val = cookie.Value
		}

		if c, ok := action.(XsrfChecker); ok {
			c.SetXsrf(val, ctx, timeout)
		}

		if ctx.Req().Method == "POST" {
			res, err := ctx.Req().Cookie(XSRF_TAG)
			formVal := ctx.Req().FormValue(XSRF_TAG)

			if err != nil || res.Value == "" || res.Value != formVal {
				ctx.Abort(http.StatusInternalServerError, "xsrf token error.")
				ctx.Error("xsrf token error.")
				return
			}
		}

		ctx.Next()
	}
}

// NewCookie is a helper method that returns a new http.Cookie object.
// Duration is specified in seconds. If the duration is zero, the cookie is permanent.
// This can be used in conjunction with ctx.SetCookie.
func newCookie(name string, value string, age int64) *http.Cookie {
	var utctime time.Time
	if age == 0 {
		// 2^31 - 1 seconds (roughly 2038)
		utctime = time.Unix(2147483647, 0)
	} else {
		utctime = time.Unix(time.Now().Unix()+age, 0)
	}
	return &http.Cookie{Name: name, Value: value, Expires: utctime}
}<commit_msg>add manual check<commit_after>// Copyright 2015 The Tango Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package xsrf

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

	"github.com/go-xweb/uuid"
	"github.com/lunny/tango"
)

const (
	XSRF_TAG string = "_xsrf"
)

type Xsrfer interface {
	CheckXsrf() bool
}

type NoCheck struct {
}

func (NoCheck) InitXsrfer(*tango.Context, time.Duration) {}

func (NoCheck) CheckXsrf() bool {
	return false
}

var _ Xsrfer = NoCheck{}

type XsrfChecker interface {
	SetXsrf(string, *tango.Context, time.Duration)
	AutoCheck() bool
}

type Checker struct {
	XsrfValue string
	ctx       *tango.Context
	timeout   time.Duration
}

func (Checker) CheckXsrf() bool {
	return true
}

func (c *Checker) SetXsrf(v string, ctx *tango.Context, timeout time.Duration) {
	c.XsrfValue = v
	c.ctx = ctx
	c.timeout = timeout
}

func (c *Checker) AutoCheck() bool {
	return true
}

func (c *Checker) XsrfFormHtml() template.HTML {
	return template.HTML(fmt.Sprintf(`<input type="hidden" name="%v" value="%v" />`,
		XSRF_TAG, c.XsrfValue))
}

func (c *Checker) Renew() {
	var val = uuid.NewRandom().String()
	var cookie = newCookie(XSRF_TAG, val, int64(c.timeout.Seconds()))
	c.ctx.Header().Set("Set-Cookie", cookie.String())
}

func (c *Checker) IsValid() bool {
	if c.ctx.Req().Method == "POST" {
		res, err := c.ctx.Req().Cookie(XSRF_TAG)
		formVal := c.ctx.Req().FormValue(XSRF_TAG)

		if err != nil || res.Value == "" || res.Value != formVal {
			return false
		}
	}

	return true
}

var _ XsrfChecker = &Checker{}

func New(timeout time.Duration) tango.HandlerFunc {
	return func(ctx *tango.Context) {
		var action interface{}
		if action = ctx.Action(); action == nil {
			ctx.Next()
			return
		}

		// if action implements check xsrf option and ask not check then return
		if checker, ok := action.(Xsrfer); ok && !checker.CheckXsrf() {
			ctx.Next()
			return
		}

		var val string = ""
		cookie, err := ctx.Req().Cookie(XSRF_TAG)
		if err != nil {
			val = uuid.NewRandom().String()
			cookie = newCookie(XSRF_TAG, val, int64(timeout.Seconds()))
			ctx.Header().Set("Set-Cookie", cookie.String())
		} else {
			val = cookie.Value
		}

		if c, ok := action.(XsrfChecker); ok {
			c.SetXsrf(val, ctx, timeout)

			if c.AutoCheck() {
				if ctx.Req().Method == "POST" {
					res, err := ctx.Req().Cookie(XSRF_TAG)
					formVal := ctx.Req().FormValue(XSRF_TAG)

					if err != nil || res.Value == "" || res.Value != formVal {
						ctx.Abort(http.StatusInternalServerError, "xsrf token error.")
						ctx.Error("xsrf token error.")
						return
					}
				}
			}
		}

		ctx.Next()
	}
}

// NewCookie is a helper method that returns a new http.Cookie object.
// Duration is specified in seconds. If the duration is zero, the cookie is permanent.
// This can be used in conjunction with ctx.SetCookie.
func newCookie(name string, value string, age int64) *http.Cookie {
	var utctime time.Time
	if age == 0 {
		// 2^31 - 1 seconds (roughly 2038)
		utctime = time.Unix(2147483647, 0)
	} else {
		utctime = time.Unix(time.Now().Unix()+age, 0)
	}
	return &http.Cookie{Name: name, Value: value, Expires: utctime}
}
<|endoftext|>


<commit_before>package yara

// #include <stdio.h>
// #include <yara.h>
// #include "cgo.h"
import "C"

import (
	"fmt"
	"log"
	"unsafe"
)

var callback = (C.YR_CALLBACK_FUNC)(unsafe.Pointer(C.callback))

// Callback is a callback that gets called during a scan with a matching rule.
type Callback func(*Rule) CallbackStatus

// CallbackStatus is flag to indicate to libyara if it should continue or abort a scanning
// process.
type CallbackStatus int

const (
	// Coninue tells libyara to continue the scanning.
	Continue = CallbackStatus(C.CALLBACK_CONTINUE)

	// Abort tells libyara to abort the scanning.
	Abort = CallbackStatus(C.CALLBACK_ABORT)

	// Fail tells libyara that an error occured and it should abort the scanning.
	Fail = CallbackStatus(C.CALLBACK_ERROR)
)

// Error is an libyara error.
type Error int

// Error returns an human readable repsentation of the libyara error.
func (e Error) Error() string {
	return fmt.Sprintf("libyara: %d", e)
}

func init() {
	code := C.yr_initialize()
	if code != C.ERROR_SUCCESS {
		log.Fatalf("failed to initialize libyara!")
	}
}

func Finalize() error {
	code := C.yr_finalize()
	if code != C.ERROR_SUCCESS {
		return Error(code)
	}

	return nil
}

type Compiler struct {
	handle *C.YR_COMPILER
}

func NewCompiler() (*Compiler, error) {
	var handle *C.YR_COMPILER
	code := C.yr_compiler_create(&handle)
	if code != C.ERROR_SUCCESS {
		return nil, Error(code)
	}

	return &Compiler{handle}, nil
}

func (c *Compiler) Destroy() {
	C.yr_compiler_destroy(c.handle)
}

func (c *Compiler) AddFile(ns, path string) error {
	cpath := C.CString(path)
	cmode := C.CString("r")
	cns := C.CString(ns)

	defer C.free(unsafe.Pointer(cpath))
	defer C.free(unsafe.Pointer(cmode))
	defer C.free(unsafe.Pointer(cns))

	fd := C.fopen(cpath, cmode)
	if fd == nil {
		return fmt.Errorf("libyara: failed to open %q", path)
	}

	defer C.fclose(fd)

	errors := C.yr_compiler_add_file(c.handle, fd, nil, cpath)
	if errors > 0 {
		return fmt.Errorf("libyara: failed to compile %q", path)
	}

	return nil
}

func (c *Compiler) AddString(ns, rule string) error {
	cns := C.CString(ns)
	crule := C.CString(rule)
	errors := C.yr_compiler_add_string(c.handle, crule, cns)
	C.free(unsafe.Pointer(crule))
	C.free(unsafe.Pointer(cns))

	if errors > 0 {
		return fmt.Errorf("libyara: failed to compile rule")
	}

	return nil
}

func (c *Compiler) Rules() (*Rules, error) {
	var handle *C.YR_RULES
	code := C.yr_compiler_get_rules(c.handle, &handle)
	if code != C.ERROR_SUCCESS {
		return nil, Error(code)
	}

	return &Rules{
		handle: handle,
	}, nil
}

type Rules struct {
	handle *C.YR_RULES
}

func LoadFromFile(path string) (*Rules, error) {
	var handle *C.YR_RULES

	cpath := C.CString(path)
	code := C.yr_rules_load(cpath, &handle)
	C.free(unsafe.Pointer(cpath))

	if code != C.ERROR_SUCCESS {
		return nil, Error(code)
	}

	return &Rules{
		handle: handle,
	}, nil
}

func (r *Rules) Destroy() {
	C.yr_rules_destroy(r.handle)
}

func (r *Rules) Save(path string) error {
	cpath := C.CString(path)
	code := C.yr_rules_save(r.handle, cpath)
	C.free(unsafe.Pointer(cpath))

	if code != C.ERROR_SUCCESS {
		return Error(code)
	}

	return nil
}

func (r *Rules) ScanMemory(buffer []byte, fn Callback) error {
	data := (*C.uint8_t)(unsafe.Pointer(&buffer[0]))
	size := C.size_t(len(buffer))

	code := C.yr_rules_scan_mem(r.handle, data, size, 0, callback, *(*unsafe.Pointer)(unsafe.Pointer(&fn)), 0)

	if code != C.ERROR_SUCCESS {
		return Error(code)
	}

	return nil
}

func (r *Rules) ScanFile(path string, fn Callback) error {
	cpath := C.CString(path)
	code := C.yr_rules_scan_file(r.handle, cpath, 0, callback, *(*unsafe.Pointer)(unsafe.Pointer(&fn)), 0)
	C.free(unsafe.Pointer(cpath))

	if code != C.ERROR_SUCCESS {
		return Error(code)
	}

	return nil
}

type Rule struct {
	Identifier string
	Tags       []string
	Metadata   map[string]string
}

func NewRule() *Rule {
	return &Rule{
		Metadata: make(map[string]string),
	}
}
<commit_msg>added error code translation<commit_after>package yara

// #include <stdio.h>
// #include <yara.h>
// #include "cgo.h"
import "C"

import (
	"fmt"
	"log"
	"unsafe"
)

var callback = (C.YR_CALLBACK_FUNC)(unsafe.Pointer(C.callback))

// Callback is a callback that gets called during a scan with a matching rule.
type Callback func(*Rule) CallbackStatus

// CallbackStatus is flag to indicate to libyara if it should continue or abort a scanning
// process.
type CallbackStatus int

const (
	// Coninue tells libyara to continue the scanning.
	Continue = CallbackStatus(C.CALLBACK_CONTINUE)

	// Abort tells libyara to abort the scanning.
	Abort = CallbackStatus(C.CALLBACK_ABORT)

	// Fail tells libyara that an error occured and it should abort the scanning.
	Fail = CallbackStatus(C.CALLBACK_ERROR)
)

func init() {
	code := C.yr_initialize()
	if code != C.ERROR_SUCCESS {
		log.Fatalf("failed to initialize libyara!")
	}
}

func Finalize() error {
	code := C.yr_finalize()
	if code != C.ERROR_SUCCESS {
		return Error(code)
	}

	return nil
}

type Compiler struct {
	handle *C.YR_COMPILER
}

func NewCompiler() (*Compiler, error) {
	var handle *C.YR_COMPILER
	code := C.yr_compiler_create(&handle)
	if code != C.ERROR_SUCCESS {
		return nil, Error(code)
	}

	return &Compiler{handle}, nil
}

func (c *Compiler) Destroy() {
	C.yr_compiler_destroy(c.handle)
}

func (c *Compiler) AddFile(ns, path string) error {
	cpath := C.CString(path)
	cmode := C.CString("r")
	cns := C.CString(ns)

	defer C.free(unsafe.Pointer(cpath))
	defer C.free(unsafe.Pointer(cmode))
	defer C.free(unsafe.Pointer(cns))

	fd := C.fopen(cpath, cmode)
	if fd == nil {
		return fmt.Errorf("libyara: failed to open %q", path)
	}

	defer C.fclose(fd)

	errors := C.yr_compiler_add_file(c.handle, fd, nil, cpath)
	if errors > 0 {
		return fmt.Errorf("libyara: failed to compile %q", path)
	}

	return nil
}

func (c *Compiler) AddString(ns, rule string) error {
	cns := C.CString(ns)
	crule := C.CString(rule)
	errors := C.yr_compiler_add_string(c.handle, crule, cns)
	C.free(unsafe.Pointer(crule))
	C.free(unsafe.Pointer(cns))

	if errors > 0 {
		return fmt.Errorf("libyara: failed to compile rule")
	}

	return nil
}

func (c *Compiler) Rules() (*Rules, error) {
	var handle *C.YR_RULES
	code := C.yr_compiler_get_rules(c.handle, &handle)
	if code != C.ERROR_SUCCESS {
		return nil, Error(code)
	}

	return &Rules{
		handle: handle,
	}, nil
}

type Rules struct {
	handle *C.YR_RULES
}

func LoadFromFile(path string) (*Rules, error) {
	var handle *C.YR_RULES

	cpath := C.CString(path)
	code := C.yr_rules_load(cpath, &handle)
	C.free(unsafe.Pointer(cpath))

	if code != C.ERROR_SUCCESS {
		return nil, Error(code)
	}

	return &Rules{
		handle: handle,
	}, nil
}

func (r *Rules) Destroy() {
	C.yr_rules_destroy(r.handle)
}

func (r *Rules) Save(path string) error {
	cpath := C.CString(path)
	code := C.yr_rules_save(r.handle, cpath)
	C.free(unsafe.Pointer(cpath))

	if code != C.ERROR_SUCCESS {
		return Error(code)
	}

	return nil
}

func (r *Rules) ScanMemory(buffer []byte, fn Callback) error {
	data := (*C.uint8_t)(unsafe.Pointer(&buffer[0]))
	size := C.size_t(len(buffer))

	code := C.yr_rules_scan_mem(r.handle, data, size, 0, callback, *(*unsafe.Pointer)(unsafe.Pointer(&fn)), 0)

	if code != C.ERROR_SUCCESS {
		return Error(code)
	}

	return nil
}

func (r *Rules) ScanFile(path string, fn Callback) error {
	cpath := C.CString(path)
	code := C.yr_rules_scan_file(r.handle, cpath, 0, callback, *(*unsafe.Pointer)(unsafe.Pointer(&fn)), 0)
	C.free(unsafe.Pointer(cpath))

	if code != C.ERROR_SUCCESS {
		return Error(code)
	}

	return nil
}

type Rule struct {
	Identifier string
	Tags       []string
	Metadata   map[string]string
}

func NewRule() *Rule {
	return &Rule{
		Metadata: make(map[string]string),
	}
}

var errorcodes = map[Error]string{
	C.ERROR_COULD_NOT_OPEN_FILE:      "File could not be opened",
	C.ERROR_COULD_NOT_MAP_FILE:       "File could not be mapped into memory",
	C.ERROR_INVALID_FILE:             "File is not a valid rules file",
	C.ERROR_CORRUPT_FILE:             "Rules file is corrupt",
	C.ERROR_UNSUPPORTED_FILE_VERSION: "File was generated by a different YARA and can’t be loaded by this version",
	C.ERROR_TOO_MANY_SCAN_THREADS:    "Too many threads trying to use the same YR_RULES object simultaneosly",
	C.ERROR_SCAN_TIMEOUT:             "Scan timed out",
	C.ERROR_CALLBACK_ERROR:           "Callback returned an error",
	C.ERROR_TOO_MANY_MATCHES:         "Too many matches for some string in your rules",
}

// Error is an libyara error.
type Error int

// Error returns an human readable repsentation of the libyara error.
func (e Error) Error() string {
	if msg, ok := errorcodes[e]; ok {
		return fmt.Sprintf("libyara: %s (%d)", msg, e)
	} else {
		return fmt.Sprintf("libyara: Unknown error code (%d)", e)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"math/rand"
	"net/http"
	"net/url"
	"os"
	"strconv"
	"strings"
	"time"

	"github.com/JustinBeckwith/go-yelp/yelp"
	"github.com/guregu/null"
	"github.com/line/line-bot-sdk-go/linebot"
)

var o *yelp.AuthOptions

type UrlShortener struct {
	ShortUrl    string
	OriginalUrl string
}

func yelp_init() {
	rand.Seed(time.Now().UnixNano())

	// check environment variables
	o = &yelp.AuthOptions{
		ConsumerKey:       os.Getenv("CONSUMER_KEY"),
		ConsumerSecret:    os.Getenv("CONSUMER_SECRET"),
		AccessToken:       os.Getenv("ACCESS_TOKEN"),
		AccessTokenSecret: os.Getenv("ACCESS_TOKEN_SECRET"),
	}

	if o.ConsumerKey == "" || o.ConsumerSecret == "" || o.AccessToken == "" || o.AccessTokenSecret == "" {
		log.Fatal("Wrong environment setting about yelp-api-keys")
	}
}

func yelp_parse(bot *linebot.Client, token string, loc *linebot.LocationMessage, food string) {
	var err error

	// create a new yelp client with the auth keys
	client := yelp.New(o, nil)

	if loc == nil {
		// make a simple query for food and location
		results, err := client.DoSimpleSearch(food, "台北市通化街")
		if err == nil {
			yelp_parse_result(bot, token, results)
		}
	} else {
		// Build an advanced set of search criteria that include
		// general options, and coordinate options.
		s := yelp.SearchOptions{
			GeneralOptions: &yelp.GeneralOptions{
				Term: food,
			},
			CoordinateOptions: &yelp.CoordinateOptions{
				Latitude:  null.FloatFrom(loc.Latitude),
				Longitude: null.FloatFrom(loc.Longitude),
			},
		}

		// Perform the search using the search options
		results, err := client.DoSearch(s)
		if err == nil {
			yelp_parse_result(bot, token, results)
		}
	}
	if err != nil {
		log.Println(err)
		_, err = bot.ReplyMessage(token, linebot.NewTextMessage("查無資料！")).Do()
	}
}

func yelp_parse_result(bot *linebot.Client, token string, results yelp.SearchResult) {
	var err error
//	var msgs []linebot.Message

	for j := 0; j < 3; j++ {
		i := 0
		if results.Total >= 20 {
			i = rand.Intn(20)
		} else if results.Total >= 10 {
			i = rand.Intn(10)
		} else if results.Total > j {
			i = j
		} else if results.Total <= j && results.Total != 0 {
			_, err = bot.ReplyMessage(token, linebot.NewTextMessage("已無更多資料！")).Do()
			break
		}
		urlOrig := UrlShortener{}
		urlOrig.short(results.Businesses[i].MobileURL)
		address := strings.Join(results.Businesses[i].Location.DisplayAddress, ",")
		var largeImageURL = strings.Replace(results.Businesses[i].ImageURL, "ms.jpg", "l.jpg", 1)

		_, err = bot.ReplyMessage(token, linebot.NewImageMessage(largeImageURL, largeImageURL), linebot.NewTextMessage("店名："+results.Businesses[i].Name+"\n電話："+results.Businesses[i].Phone+"\n評比："+strconv.FormatFloat(float64(results.Businesses[i].Rating), 'f', 1, 64)+"\n更多資訊："+urlOrig.ShortUrl), linebot.NewLocationMessage(results.Businesses[i].Name+"\n", address, float64(results.Businesses[i].Location.Coordinate.Latitude), float64(results.Businesses[i].Location.Coordinate.Longitude)) ).Do()
//		msgs = append(msgs, linebot.NewImageMessage(largeImageURL, largeImageURL))
//		msgs = append(msgs, linebot.NewTextMessage("店名："+results.Businesses[i].Name+"\n電話："+results.Businesses[i].Phone+"\n評比："+strconv.FormatFloat(float64(results.Businesses[i].Rating), 'f', 1, 64)+"\n更多資訊："+urlOrig.ShortUrl))
//		msgs = append(msgs, linebot.NewLocationMessage(results.Businesses[i].Name+"\n", address, float64(results.Businesses[i].Location.Coordinate.Latitude), float64(results.Businesses[i].Location.Coordinate.Longitude)))
//		_, err = bot.ReplyMessage(token, linebot.NewImageMessage(largeImageURL, largeImageURL)).Do()
//		_, err = bot.ReplyMessage(token, linebot.NewTextMessage("店名："+results.Businesses[i].Name+"\n電話："+results.Businesses[i].Phone+"\n評比："+strconv.FormatFloat(float64(results.Businesses[i].Rating), 'f', 1, 64)+"\n更多資訊："+urlOrig.ShortUrl)).Do()
//		_, err = bot.ReplyMessage(token, linebot.NewLocationMessage(results.Businesses[i].Name+"\n", address, float64(results.Businesses[i].Location.Coordinate.Latitude), float64(results.Businesses[i].Location.Coordinate.Longitude))).Do()
	}

//	if len(msgs) > 0 {
//		_, err = bot.ReplyMessage(token, msgs).Do()
//	}
	if err != nil {
		log.Println(err)
	}
}

func getResponseData(urlOrig string) string {
	response, err := http.Get(urlOrig)
	if err != nil {
		log.Println(err)
	}
	defer response.Body.Close()
	contents, err := ioutil.ReadAll(response.Body)
	return string(contents)
}

func isGdShortener(urlOrig string) (string, string) {
	escapedUrl := url.QueryEscape(urlOrig)
	isGdUrl := fmt.Sprintf("http://is.gd/create.php?url=%s&format=simple", escapedUrl)
	return getResponseData(isGdUrl), urlOrig
}

func (u *UrlShortener) short(urlOrig string) *UrlShortener {
	shortUrl, originalUrl := isGdShortener(urlOrig)
	u.ShortUrl = shortUrl
	u.OriginalUrl = originalUrl
	return u
}
<commit_msg>test location<commit_after>package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"math/rand"
	"net/http"
	"net/url"
	"os"
	"strconv"
	"strings"
	"time"

	"github.com/JustinBeckwith/go-yelp/yelp"
	"github.com/guregu/null"
	"github.com/line/line-bot-sdk-go/linebot"
)

var o *yelp.AuthOptions

type UrlShortener struct {
	ShortUrl    string
	OriginalUrl string
}

func yelp_init() {
	rand.Seed(time.Now().UnixNano())

	// check environment variables
	o = &yelp.AuthOptions{
		ConsumerKey:       os.Getenv("CONSUMER_KEY"),
		ConsumerSecret:    os.Getenv("CONSUMER_SECRET"),
		AccessToken:       os.Getenv("ACCESS_TOKEN"),
		AccessTokenSecret: os.Getenv("ACCESS_TOKEN_SECRET"),
	}

	if o.ConsumerKey == "" || o.ConsumerSecret == "" || o.AccessToken == "" || o.AccessTokenSecret == "" {
		log.Fatal("Wrong environment setting about yelp-api-keys")
	}
}

func yelp_parse(bot *linebot.Client, token string, loc *linebot.LocationMessage, food string) {
	var err error

	// create a new yelp client with the auth keys
	client := yelp.New(o, nil)

	if loc == nil {
		// make a simple query for food and location
		results, err := client.DoSimpleSearch(food, "台北市通化街")
		if err == nil {
			log.Println("loc nil")
			yelp_parse_result(bot, token, results)
		}
	} else {
		// Build an advanced set of search criteria that include
		// general options, and coordinate options.
		s := yelp.SearchOptions{
			GeneralOptions: &yelp.GeneralOptions{
				Term: food,
			},
			CoordinateOptions: &yelp.CoordinateOptions{
				Latitude:  null.FloatFrom(loc.Latitude),
				Longitude: null.FloatFrom(loc.Longitude),
			},
		}

		// Perform the search using the search options
		results, err := client.DoSearch(s)
		if err == nil {
			log.Println("loc:")
			yelp_parse_result(bot, token, results)
		}
	}
	if err != nil {
		log.Println(err)
		_, err = bot.ReplyMessage(token, linebot.NewTextMessage("查無資料！")).Do()
	}
}

func yelp_parse_result(bot *linebot.Client, token string, results yelp.SearchResult) {
	var err error
//	var msgs []linebot.Message

	for i := 0; i < 3; i++ {
		//i := 0
		//if results.Total >= 20 {
		//	i = rand.Intn(20)
		//} else if results.Total >= 10 {
		//	i = rand.Intn(10)
		//} else if results.Total > j {
		//	i = j
		//} else if results.Total <= j && results.Total != 0 {
		if ( results.Total <= i) {
			_, err = bot.ReplyMessage(token, linebot.NewTextMessage("已無更多資料！")).Do()
			break
		}
		urlOrig := UrlShortener{}
		urlOrig.short(results.Businesses[i].MobileURL)
		address := strings.Join(results.Businesses[i].Location.DisplayAddress, ",")
		var largeImageURL = strings.Replace(results.Businesses[i].ImageURL, "ms.jpg", "l.jpg", 1)

		_, err = bot.ReplyMessage(token, linebot.NewImageMessage(largeImageURL, largeImageURL), linebot.NewTextMessage("店名："+results.Businesses[i].Name+"\n電話："+results.Businesses[i].Phone+"\n評比："+strconv.FormatFloat(float64(results.Businesses[i].Rating), 'f', 1, 64)+"\n更多資訊："+urlOrig.ShortUrl), linebot.NewLocationMessage(results.Businesses[i].Name+"\n", address, float64(results.Businesses[i].Location.Coordinate.Latitude), float64(results.Businesses[i].Location.Coordinate.Longitude)) ).Do()
//		msgs = append(msgs, linebot.NewImageMessage(largeImageURL, largeImageURL))
//		msgs = append(msgs, linebot.NewTextMessage("店名："+results.Businesses[i].Name+"\n電話："+results.Businesses[i].Phone+"\n評比："+strconv.FormatFloat(float64(results.Businesses[i].Rating), 'f', 1, 64)+"\n更多資訊："+urlOrig.ShortUrl))
//		msgs = append(msgs, linebot.NewLocationMessage(results.Businesses[i].Name+"\n", address, float64(results.Businesses[i].Location.Coordinate.Latitude), float64(results.Businesses[i].Location.Coordinate.Longitude)))
//		_, err = bot.ReplyMessage(token, linebot.NewImageMessage(largeImageURL, largeImageURL)).Do()
//		_, err = bot.ReplyMessage(token, linebot.NewTextMessage("店名："+results.Businesses[i].Name+"\n電話："+results.Businesses[i].Phone+"\n評比："+strconv.FormatFloat(float64(results.Businesses[i].Rating), 'f', 1, 64)+"\n更多資訊："+urlOrig.ShortUrl)).Do()
//		_, err = bot.ReplyMessage(token, linebot.NewLocationMessage(results.Businesses[i].Name+"\n", address, float64(results.Businesses[i].Location.Coordinate.Latitude), float64(results.Businesses[i].Location.Coordinate.Longitude))).Do()
	}

//	if len(msgs) > 0 {
//		_, err = bot.ReplyMessage(token, msgs).Do()
//	}
	if err != nil {
		log.Println(err)
	}
}

func getResponseData(urlOrig string) string {
	response, err := http.Get(urlOrig)
	if err != nil {
		log.Println(err)
	}
	defer response.Body.Close()
	contents, err := ioutil.ReadAll(response.Body)
	return string(contents)
}

func isGdShortener(urlOrig string) (string, string) {
	escapedUrl := url.QueryEscape(urlOrig)
	isGdUrl := fmt.Sprintf("http://is.gd/create.php?url=%s&format=simple", escapedUrl)
	return getResponseData(isGdUrl), urlOrig
}

func (u *UrlShortener) short(urlOrig string) *UrlShortener {
	shortUrl, originalUrl := isGdShortener(urlOrig)
	u.ShortUrl = shortUrl
	u.OriginalUrl = originalUrl
	return u
}
<|endoftext|>


<commit_before>package lua

var cmdRc = `
func _fallback(name, val)
    if type(val) == 'function' then
        val()
    else
        print val
    end
end

local _hook_types = {
	-- TODO: hook sys, map?
	code = cpu.HOOK_CODE,
	block = cpu.HOOK_BLOCK,
	intr = cpu.HOOK_INTR,
	read = cpu.HOOK_MEM_READ,
	write = cpu.HOOK_MEM_WRITE,
	fault = cpu.HOOK_MEM_ERR,
}

func _on_hook(name, fn, start, stop)
	local type = _hook_types[name]
	if type != nil then
		if start == nil then
			return u.hook_add(type, fn)
		else
			if stop == nil then stop = start end
			return u.hook_add(type, fn, start, stop)
		end
	end
	print 'unimplemented hook type %s' % name
    -- u.on_hook_add(name, fn, start, stop)
end

func off()
	if hh then
		u.hook_del(hh)
		hh = nil
	end
end

func read(addr, size)
	if size == nil then size = 16 end
	return u.mem_read(addr, size)
end

func write(addr, s)
	u.mem_write(addr, s)
end

func maps()
	print 'Memory map:'
	local m = us:Mappings()
	for i in m() do
	print m[i]:String()
	end
end

func map(addr, size, prot)
    if addr == nil then
		maps()
    else
        if prot == nil then prot = cpu.PROT_ALL end
        u.mem_map(addr, size, prot)
    end
end

func asm(src, addr)
	if addr == nil then addr = 0 end
	return u.asm(src, addr)
end

func patch(addr, src)
	local x = asm(src, addr)
	-- autonop
	local total = 0
	for _, ins in pairs(u.dis(addr, x:len() + 16)) do
		total = total + ins.bytes:len()
		if total == x:len() then break end
		if total > x:len() then
			x = x .. asm('nop', 0):rep(total - x:len())
			break
		end
	end
	write(addr, x)
end

func dis(addr, size, indent, count)
	if addr == nil then addr = pc end
	if size == nil then size = 16 end
	if indent == nil then indent = 0 end
	local pad = (' '):rep(indent)
	local d = u.dis(addr, size)
	local width = 0
	for i, ins in ipairs(d) do
		if count != nil and i > count then break end
		local fmt = pad .. '0x%x: %s %s'
		print fmt % {ins.addr, ins.name, ins.op_str}
	end
end

func s(steps)
	if steps == nil then steps = 1 end
	u.step(steps)
end

c = u.continue
func rewind(n)
	if n == nil then n = 1 end
	u.rewind_n(n)
end
rw = rewind
rwaddr = u.rewind_addr

func rwto(insto)
	repeat
		rw 1
	until ins.name == insto
end

func b(baddr)
	local hh = u.hook_add(cpu.HOOK_CODE, func()
		if bskip == baddr then
			bskip = nil
			return
		end
		bskip = baddr
		print 'Breakpoint N hit at 0x%x' % baddr
		u.stop()
	end, baddr, baddr)
	print 'Breakpoint N at 0x%x' % baddr
end

func runto(name)
    on code do
        if ins.name == name then
            print '[-] stopping at "%s"' % name
            dis pc 16 0 1
            u.stop()
            off
        end
    end
    c
end
`
<commit_msg>repl: add regs command (shorthand r)<commit_after>package lua

var cmdRc = `
func _fallback(name, val)
    if type(val) == 'function' then
        val()
    else
        print val
    end
end

local _hook_types = {
	-- TODO: hook sys, map?
	code = cpu.HOOK_CODE,
	block = cpu.HOOK_BLOCK,
	intr = cpu.HOOK_INTR,
	read = cpu.HOOK_MEM_READ,
	write = cpu.HOOK_MEM_WRITE,
	fault = cpu.HOOK_MEM_ERR,
}

func _on_hook(name, fn, start, stop)
	local type = _hook_types[name]
	if type != nil then
		if start == nil then
			return u.hook_add(type, fn)
		else
			if stop == nil then stop = start end
			return u.hook_add(type, fn, start, stop)
		end
	end
	print 'unimplemented hook type %s' % name
    -- u.on_hook_add(name, fn, start, stop)
end

func off()
	if hh then
		u.hook_del(hh)
		hh = nil
	end
end

func read(addr, size)
	if size == nil then size = 16 end
	return u.mem_read(addr, size)
end

func write(addr, s)
	u.mem_write(addr, s)
end

func maps()
	print 'Memory map:'
	local m = us:Mappings()
	for i in m() do
	print m[i]:String()
	end
end

func map(addr, size, prot)
    if addr == nil then
		maps()
    else
        if prot == nil then prot = cpu.PROT_ALL end
        u.mem_map(addr, size, prot)
    end
end

func asm(src, addr)
	if addr == nil then addr = 0 end
	return u.asm(src, addr)
end

func patch(addr, src)
	local x = asm(src, addr)
	-- autonop
	local total = 0
	for _, ins in pairs(u.dis(addr, x:len() + 16)) do
		total = total + ins.bytes:len()
		if total == x:len() then break end
		if total > x:len() then
			x = x .. asm('nop', 0):rep(total - x:len())
			break
		end
	end
	write(addr, x)
end

func dis(addr, size, indent, count)
	if addr == nil then addr = pc end
	if size == nil then size = 16 end
	if indent == nil then indent = 0 end
	local pad = (' '):rep(indent)
	local d = u.dis(addr, size)
	local width = 0
	for i, ins in ipairs(d) do
		if count != nil and i > count then break end
		local fmt = pad .. '0x%x: %s %s'
		print fmt % {ins.addr, ins.name, ins.op_str}
	end
end

func s(steps)
	if steps == nil then steps = 1 end
	u.step(steps)
end

c = u.continue
func rewind(n)
	if n == nil then n = 1 end
	u.rewind_n(n)
end
rw = rewind
rwaddr = u.rewind_addr

func rwto(insto)
	repeat
		rw 1
	until ins.name == insto
end

func b(baddr)
	local hh = u.hook_add(cpu.HOOK_CODE, func()
		if bskip == baddr then
			bskip = nil
			return
		end
		bskip = baddr
		print 'Breakpoint N hit at 0x%x' % baddr
		u.stop()
	end, baddr, baddr)
	print 'Breakpoint N at 0x%x' % baddr
end

func runto(name)
    on code do
        if ins.name == name then
            print '[-] stopping at "%s"' % name
            dis pc 16 0 1
            u.stop()
            off
        end
    end
    c
end

func regs(name)
	reglist, err = us:RegDump()
	for _, reg in reglist() do
		print reg.Name reg.Val
	end
end
r = regs
`
<|endoftext|>