<commit_before>package main

import (
	"flag"
	"fmt"
	"github.com/evolsnow/robot/conn"
	"golang.org/x/net/websocket"
	"log"
	"net"
	"net/http"
	"strconv"
	"strings"
	"time"
	"unicode"
)

func main() {
	var configFile string
	flag.StringVar(&configFile, "c", "config.json", "specify config file")
	flag.Parse()
	config, err := ParseConfig(configFile)
	if err != nil {
		log.Fatal("a vailid json config file must exist")
	}

	redisPort := strconv.Itoa(config.RedisPort)
	redisServer := net.JoinHostPort(config.RedisAddress, redisPort)
	if !conn.Ping(redisServer, config.RedisPassword) {
		log.Fatal("connect to redis server failed")
	}
	conn.Pool = conn.NewPool(redisServer, config.RedisPassword, config.RedisDB)
	robot := newRobot(config.RobotToken, config.RobotName, config.WebHookUrl)
	go robot.run()
	srvPort := strconv.Itoa(config.Port)
	http.Handle("/websocket", websocket.Handler(socketHandler))
	//	log.Fatal(http.ListenAndServe(net.JoinHostPort(config.Server, srvPort), nil))
	log.Fatal(http.ListenAndServeTLS(net.JoinHostPort(config.Server, srvPort), config.Cert, config.CertKey, nil))

}

//used for web samaritan robot
func socketHandler(ws *websocket.Conn) {
	for {
		var in, response string
		var ret []string
		sf := func(c rune) bool {
			return c == ',' || c == '，' || c == ';' || c == '。' || c == '.' || c == '？' || c == '?'
		}
		if err := websocket.Message.Receive(ws, &in); err != nil {
			log.Println(err)
			return
		}
		fmt.Printf("Received: %s\n", in)
		zh := false
		for _, r := range in {
			if unicode.Is(unicode.Scripts["Han"], r) {
				log.Println(in)
				zh = true
				break
			}
		}
		if zh {
			response = tlAI(in)
			// Separate into fields with func.
			ret = strings.FieldsFunc(response, sf)

		} else {
			response = mitAI(in)
			ret = strings.FieldsFunc(response, sf)
		}
		for i := range ret {
			websocket.Message.Send(ws, ret[i])
			time.Sleep(time.Second)
		}
		websocket.Message.Send(ws, "")
	}
}
<commit_msg>debug<commit_after>package main

import (
	"flag"
	"fmt"
	"github.com/evolsnow/robot/conn"
	"golang.org/x/net/websocket"
	"log"
	"net"
	"net/http"
	"strconv"
	"strings"
	"time"
	"unicode"
)

func main() {
	var configFile string
	var debug bool
	flag.StringVar(&configFile, "c", "config.json", "specify config file")
	flag.BoolVar(&debug, "v", false, "debug mode")

	flag.Parse()
	config, err := ParseConfig(configFile)
	if err != nil {
		log.Fatal("a vailid json config file must exist")
	}

	redisPort := strconv.Itoa(config.RedisPort)
	redisServer := net.JoinHostPort(config.RedisAddress, redisPort)
	if !conn.Ping(redisServer, config.RedisPassword) {
		log.Fatal("connect to redis server failed")
	}
	conn.Pool = conn.NewPool(redisServer, config.RedisPassword, config.RedisDB)
	robot := newRobot(config.RobotToken, config.RobotName, config.WebHookUrl)
	robot.bot.Debug = debug
	go robot.run()
	srvPort := strconv.Itoa(config.Port)
	http.Handle("/websocket", websocket.Handler(socketHandler))
	//	log.Fatal(http.ListenAndServe(net.JoinHostPort(config.Server, srvPort), nil))
	log.Fatal(http.ListenAndServeTLS(net.JoinHostPort(config.Server, srvPort), config.Cert, config.CertKey, nil))

}

//used for web samaritan robot
func socketHandler(ws *websocket.Conn) {
	for {
		var in, response string
		var ret []string
		sf := func(c rune) bool {
			return c == ',' || c == '，' || c == ';' || c == '。' || c == '.' || c == '？' || c == '?'
		}
		if err := websocket.Message.Receive(ws, &in); err != nil {
			log.Println(err)
			return
		}
		fmt.Printf("Received: %s\n", in)
		zh := false
		for _, r := range in {
			if unicode.Is(unicode.Scripts["Han"], r) {
				log.Println(in)
				zh = true
				break
			}
		}
		if zh {
			response = tlAI(in)
			// Separate into fields with func.
			ret = strings.FieldsFunc(response, sf)

		} else {
			response = mitAI(in)
			ret = strings.FieldsFunc(response, sf)
		}
		for i := range ret {
			websocket.Message.Send(ws, ret[i])
			time.Sleep(time.Second)
		}
		websocket.Message.Send(ws, "")
	}
}
<|endoftext|>


<commit_before>// Copyright 2017, TCN Inc.
// All rights reserved.

// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:

//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of TCN Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.

// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package main

import (
	"io/ioutil"
	"os"

	"github.com/Sirupsen/logrus"
	"github.com/golang/protobuf/proto"
	"github.com/golang/protobuf/protoc-gen-go/plugin"
	"github.com/tcncloud/protoc-gen-persist/generator"
)

func init() {
	if os.Getenv("DEBUG") != "" {
		logrus.SetLevel(logrus.DebugLevel)
	}
}

func Return(response *plugin_go.CodeGeneratorResponse) {
}

func main() {
	var req plugin_go.CodeGeneratorRequest

	data, err := ioutil.ReadAll(os.Stdin)
	if err != nil {
		logrus.Fatal("Can't read the stdin!")
	}

	if err := proto.Unmarshal(data, &req); err != nil {
		logrus.Fatal("Error parsing data!")
	}
	// DO processing
	g := generator.NewGenerator(&req)
	g.ProcessRequest()

	// Send back the results.
	data, err = proto.Marshal(g.GetResponse())
	if err != nil {
		logrus.Fatal("I can't serialize response")
	}
	_, err = os.Stdout.Write(data)
	if err != nil {
		logrus.Fatal("Can't send data to stdout!")
	}

}
<commit_msg>check arguments and print a help<commit_after>// Copyright 2017, TCN Inc.
// All rights reserved.

// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:

//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of TCN Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.

// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package main

import (
	"io/ioutil"
	"os"

	"fmt"

	"github.com/Sirupsen/logrus"
	"github.com/golang/protobuf/proto"
	"github.com/golang/protobuf/protoc-gen-go/plugin"
	"github.com/tcncloud/protoc-gen-persist/generator"
)

func init() {
	if os.Getenv("DEBUG") != "" {
		logrus.SetLevel(logrus.DebugLevel)
	}
}

func Return(response *plugin_go.CodeGeneratorResponse) {
}

func main() {
	if len(os.Args) > 1 {
		fmt.Println("This executable is ment to be used by protoc!\nGo to http://github.com/tcncloud/protoc-gen-persist for more info")
		os.Exit(-1)
	}
	var req plugin_go.CodeGeneratorRequest

	data, err := ioutil.ReadAll(os.Stdin)
	if err != nil {
		logrus.Fatal("Can't read the stdin!")
	}

	if err := proto.Unmarshal(data, &req); err != nil {
		logrus.Fatal("Error parsing data!")
	}
	// DO processing
	g := generator.NewGenerator(&req)
	g.ProcessRequest()

	// Send back the results.
	data, err = proto.Marshal(g.GetResponse())
	if err != nil {
		logrus.Fatal("I can't serialize response")
	}
	_, err = os.Stdout.Write(data)
	if err != nil {
		logrus.Fatal("Can't send data to stdout!")
	}

}
<|endoftext|>


<commit_before><commit_msg>this works like I want it to<commit_after>package main

import (
	"flag"
	"fmt"
	"log"

	"code.google.com/p/gcfg"
)

var configPath = flag.String("class", "fighter", "Value of class to build.  Default is: fighter")

//You can put the flag definitions in the init function as well.
//Nothings gets called until you call flag.Parse()

func main() {
	var cfg Config
	flag.Parse()
	configpath := fmt.Sprintf("config/%v.gcfg", *configPath)
	if err := gcfg.ReadFileInto(&cfg, configpath); err != nil {
		log.Println("Error: ", err)
	} else {
		character := NewCharacter(cfg)
		fmt.Printf("Character Info...\n%v\n", character)
	}

}
<|endoftext|>


<commit_before>package main;

import (
	"os"
	"fmt"
	"github.com/bwmarrin/discordgo"
	"encoding/binary"
	"io"
	"strings"
	"time"
	"math/rand"
	"io/ioutil"
	"path/filepath"
	"encoding/json"
	"runtime/debug"
	"regexp"
)

const DIRNAME = "Dank";
var sounds = make(map[string][][]byte, 0);
var images map[string]string;

var statuses = []string{
	"hidden object games",
	"Oh... Sir!",
	"Minecraft 1.0 ALPHA",
	"with your mother",
	"something",
	"something else",
	"bored",
	"dead"}

type Settings struct{
	playing bool
	commander string
}
var settings = make(map[string]*Settings);

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

	if(len(args) < 1){
		fmt.Println("No token provided!");
		return;
	}
	token := args[0];

	fmt.Println("Loading...");

	err := os.MkdirAll(DIRNAME, 0755);
	if(err != nil){
		printErr(err);
		return;
	}
	files, err := ioutil.ReadDir(DIRNAME);
	if(err != nil){
		printErr(err);
		return;
	}
	for _, file := range files{
		if(file.IsDir()){
			continue;
		}
		name := file.Name();
		if(!strings.HasSuffix(name, ".dca")){
			continue;
		}

		bytes := make([][]byte, 0);
		err = load(name, &bytes);
		if(err != nil){
			continue;
		}

		name = strings.ToLower(strings.TrimSuffix(name, ".dca"));
		sounds[name] = bytes;
	}

	data, err := ioutil.ReadFile("Dank/images.json");
	if(err != nil){
		printErr(err);
		images = make(map[string]string, 0);
	} else {
		err = json.Unmarshal(data, &images);
		if(err != nil){
			printErr(err);
			images = make(map[string]string, 0);
		}
	}

	fmt.Println("Starting...");
	session, err := discordgo.New("Bot " + token);
	if(err != nil){
		printErr(err);
		return;
	}
	session.AddHandler(messageCreate);
	session.AddHandler(messageUpdate);
	err = session.Open();

	if(err != nil){
		printErr(err);
		return;
	}

	go func(){
		c := time.Tick(time.Second * 5);

		for _ = range c{
			err := session.UpdateStatus(0, statuses[rand.Intn(len(statuses))]);
			if(err != nil){ printErr(err); return; }
		}
	}();
	fmt.Println("Started!");

	<-make(chan struct{});
}

func load(file string, buffer *[][]byte) error{
	f, err := os.Open(filepath.Join(DIRNAME, file));
	defer f.Close();
	if err != nil {
		printErr(err);
		return err;
	}

	var length int16;
	for {
		err := binary.Read(f, binary.LittleEndian, &length);

		if(err == io.EOF || err == io.ErrUnexpectedEOF){
			break;
		} else if(err != nil){
			printErr(err);
			return err;
		}

		buf := make([]byte, length);
		err = binary.Read(f, binary.LittleEndian, &buf);
		if(err != nil){
			printErr(err);
			return err;
		}

		*buffer = append(*buffer, buf);
	}
	return nil;
}

func play(buffer [][]byte, session *discordgo.Session, guild, channel string, s *Settings){
	s.playing = true;
	vc, err := session.ChannelVoiceJoin(guild, channel, false, true);
	if(err != nil){
		printErr(err);
		s.playing = false;
		return;
	}

	err = vc.Speaking(true);
	if(err != nil){
		printErr(err);
		s.playing = false;
		return;
	}

	for _, buf := range buffer {
		if(!s.playing){ break; }
		vc.OpusSend <- buf;
	}

	err = vc.Speaking(false);
	if(err != nil){
		printErr(err);
	}
	err = vc.Disconnect();
	if(err != nil){
		printErr(err);
	}
	s.playing = false;
}

func messageCreate(session *discordgo.Session, event *discordgo.MessageCreate){
	message(session, event.Message)
}
func messageUpdate(session *discordgo.Session, event *discordgo.MessageUpdate){
	message(session, event.Message)
}
func message(session *discordgo.Session, event *discordgo.Message){
	if(event.Author == nil){ return; }
	msg := strings.ToLower(strings.TrimSpace(event.Content));
	author := event.Author;

	if(msg == ""){
		return;
	}

	channel, err := session.Channel(event.ChannelID);
	if(err != nil){ printErr(err); return; }

	if(channel.IsPrivate){
		return;
	}

	guild, err := session.Guild(channel.GuildID);
	if(err != nil){ printErr(err); return; }

	s := settings[guild.ID];
	if(s == nil){
		s = &Settings{};
		settings[guild.ID] = s;
	}

	if(s.commander != "" && s.commander != author.ID){
		return;
	}

	buffer, ok := sounds[msg];
	if(ok){
		if(!s.playing){
			for _, state := range guild.VoiceStates{
				if state.UserID == event.Author.ID{
					go react(session, event);
					play(buffer, session, guild.ID, state.ChannelID, s);
					return;
				}
			}
		}
		return;
	}

	for keyword, url := range images{
		contains, err := regexp.MatchString("(?i)\\b" +
			regexp.QuoteMeta(keyword) + "\\b", msg);
		if(err != nil){
			printErr(err);
			return;
		}
		if(contains){
			go react(session, event);
			_, err = session.ChannelMessageSendEmbed(event.ChannelID,
				&discordgo.MessageEmbed{
					Image: &discordgo.MessageEmbedImage{
						URL: url,
					},
				});
			if(err != nil){
				printErr(err);
			}
			return;
		}
	}

	switch(msg){
		case "thx":
			s.playing = false;
		case "listen only to me plz":
			s.commander = author.ID;
		case "every1 owns u stopad robot":
			s.commander = "";
	}
}

func react(session *discordgo.Session, event *discordgo.Message){
	err := session.MessageReactionAdd(event.ChannelID, event.ID, "👌");
	if(err != nil){
		printErr(err);
		return;
	}
	err = session.MessageReactionAdd(event.ChannelID, event.ID, "😂");
	if(err != nil){
		printErr(err);
	}
}

func printErr(err error){
	fmt.Fprintln(os.Stderr, "Error:", err);
	debug.PrintStack();
}
<commit_msg>US EXTRA LIBRARY CUZ YAY<commit_after>package main;

import (
	"os"
	"fmt"
	"github.com/bwmarrin/discordgo"
	"encoding/binary"
	"io"
	"strings"
	"time"
	"math/rand"
	"io/ioutil"
	"path/filepath"
	"encoding/json"
	"regexp"
	"github.com/legolord208/stdutil"
)

const DIRNAME = "Dank";
var sounds = make(map[string][][]byte, 0);
var images map[string]string;

var statuses = []string{
	"hidden object games",
	"Oh... Sir!",
	"Minecraft 1.0 ALPHA",
	"with your mother",
	"something",
	"something else",
	"bored",
	"dead"}

type Settings struct{
	playing bool
	commander string
}
var settings = make(map[string]*Settings);

func main(){
	stdutil.ShouldTrace = true;

	args := os.Args[1:];

	if(len(args) < 1){
		fmt.Println("No token provided!");
		return;
	}
	token := args[0];

	fmt.Println("Loading...");

	err := os.MkdirAll(DIRNAME, 0755);
	if(err != nil){
		stdutil.PrintErr("", err);
		return;
	}
	files, err := ioutil.ReadDir(DIRNAME);
	if(err != nil){
		stdutil.PrintErr("", err);
		return;
	}
	for _, file := range files{
		if(file.IsDir()){
			continue;
		}
		name := file.Name();
		if(!strings.HasSuffix(name, ".dca")){
			continue;
		}

		bytes := make([][]byte, 0);
		err = load(name, &bytes);
		if(err != nil){
			continue;
		}

		name = strings.ToLower(strings.TrimSuffix(name, ".dca"));
		sounds[name] = bytes;
	}

	data, err := ioutil.ReadFile("Dank/images.json");
	if(err != nil){
		stdutil.PrintErr("", err);
		images = make(map[string]string, 0);
	} else {
		err = json.Unmarshal(data, &images);
		if(err != nil){
			stdutil.PrintErr("", err);
			images = make(map[string]string, 0);
		}
	}

	fmt.Println("Starting...");
	session, err := discordgo.New("Bot " + token);
	if(err != nil){
		stdutil.PrintErr("", err);
		return;
	}
	session.AddHandler(messageCreate);
	session.AddHandler(messageUpdate);
	err = session.Open();

	if(err != nil){
		stdutil.PrintErr("", err);
		return;
	}

	go func(){
		c := time.Tick(time.Second * 5);

		for _ = range c{
			err := session.UpdateStatus(0, statuses[rand.Intn(len(statuses))]);
			if(err != nil){ stdutil.PrintErr("", err); return; }
		}
	}();
	fmt.Println("Started!");

	<-make(chan struct{});
}

func load(file string, buffer *[][]byte) error{
	f, err := os.Open(filepath.Join(DIRNAME, file));
	defer f.Close();
	if err != nil {
		stdutil.PrintErr("", err);
		return err;
	}

	var length int16;
	for {
		err := binary.Read(f, binary.LittleEndian, &length);

		if(err == io.EOF || err == io.ErrUnexpectedEOF){
			break;
		} else if(err != nil){
			stdutil.PrintErr("", err);
			return err;
		}

		buf := make([]byte, length);
		err = binary.Read(f, binary.LittleEndian, &buf);
		if(err != nil){
			stdutil.PrintErr("", err);
			return err;
		}

		*buffer = append(*buffer, buf);
	}
	return nil;
}

func play(buffer [][]byte, session *discordgo.Session, guild, channel string, s *Settings){
	s.playing = true;
	vc, err := session.ChannelVoiceJoin(guild, channel, false, true);
	if(err != nil){
		stdutil.PrintErr("", err);
		s.playing = false;
		return;
	}

	err = vc.Speaking(true);
	if(err != nil){
		stdutil.PrintErr("", err);
		s.playing = false;
		return;
	}

	for _, buf := range buffer {
		if(!s.playing){ break; }
		vc.OpusSend <- buf;
	}

	err = vc.Speaking(false);
	if(err != nil){
		stdutil.PrintErr("", err);
	}
	err = vc.Disconnect();
	if(err != nil){
		stdutil.PrintErr("", err);
	}
	s.playing = false;
}

func messageCreate(session *discordgo.Session, event *discordgo.MessageCreate){
	message(session, event.Message)
}
func messageUpdate(session *discordgo.Session, event *discordgo.MessageUpdate){
	message(session, event.Message)
}
func message(session *discordgo.Session, event *discordgo.Message){
	if(event.Author == nil){ return; }
	msg := strings.ToLower(strings.TrimSpace(event.Content));
	author := event.Author;

	if(msg == ""){
		return;
	}

	channel, err := session.Channel(event.ChannelID);
	if(err != nil){ stdutil.PrintErr("", err); return; }

	if(channel.IsPrivate){
		return;
	}

	guild, err := session.Guild(channel.GuildID);
	if(err != nil){ stdutil.PrintErr("", err); return; }

	s := settings[guild.ID];
	if(s == nil){
		s = &Settings{};
		settings[guild.ID] = s;
	}

	if(s.commander != "" && s.commander != author.ID){
		return;
	}

	buffer, ok := sounds[msg];
	if(ok){
		if(!s.playing){
			for _, state := range guild.VoiceStates{
				if state.UserID == event.Author.ID{
					go react(session, event);
					play(buffer, session, guild.ID, state.ChannelID, s);
					return;
				}
			}
		}
		return;
	}

	for keyword, url := range images{
		contains, err := regexp.MatchString("(?i)\\b" +
			regexp.QuoteMeta(keyword) + "\\b", msg);
		if(err != nil){
			stdutil.PrintErr("", err);
			return;
		}
		if(contains){
			go react(session, event);
			_, err = session.ChannelMessageSendEmbed(event.ChannelID,
				&discordgo.MessageEmbed{
					Image: &discordgo.MessageEmbedImage{
						URL: url,
					},
				});
			if(err != nil){
				stdutil.PrintErr("", err);
			}
			return;
		}
	}

	switch(msg){
		case "thx":
			s.playing = false;
		case "listen only to me plz":
			s.commander = author.ID;
		case "every1 owns u stopad robot":
			s.commander = "";
	}
}

func react(session *discordgo.Session, event *discordgo.Message){
	err := session.MessageReactionAdd(event.ChannelID, event.ID, "👌");
	if(err != nil){
		stdutil.PrintErr("", err);
		return;
	}
	err = session.MessageReactionAdd(event.ChannelID, event.ID, "😂");
	if(err != nil){
		stdutil.PrintErr("", err);
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"log"
	"time"
    "github.com/joho/godotenv"
	"github.com/whitef0x0/TrendingGithub/flags"
	"github.com/whitef0x0/TrendingGithub/storage"
	"github.com/whitef0x0/TrendingGithub/twitter"
	"github.com/whitef0x0/TrendingGithub/expvar"
	"github.com/whitef0x0/TrendingGithub/tweets"
)

const (
	// Version of @TrendingGithub
	Version = "0.4.0"
)

func main() {
	envErr := godotenv.Load()
	if envErr != nil {
		log.Fatal("Error loading .env file")
	}

	var (
		// Twitter
		twitterConsumerKey       = flags.String("twitter-consumer-key", "TRENDINGGITHUB_TWITTER_CONSUMER_KEY", "", "Twitter-API: Consumer key. Env var: TRENDINGGITHUB_TWITTER_CONSUMER_KEY")
		twitterConsumerSecret    = flags.String("twitter-consumer-secret", "TRENDINGGITHUB_TWITTER_CONSUMER_SECRET", "", "Twitter-API: Consumer secret. Env var: TRENDINGGITHUB_TWITTER_CONSUMER_SECRET")
		twitterAccessToken       = flags.String("twitter-access-token", "TRENDINGGITHUB_TWITTER_ACCESS_TOKEN", "", "Twitter-API: Access token. Env var: TRENDINGGITHUB_TWITTER_ACCESS_TOKEN")
		twitterAccessTokenSecret = flags.String("twitter-access-token-secret", "TRENDINGGITHUB_TWITTER_ACCESS_TOKEN_SECRET", "", "Twitter-API: Access token secret. Env var: TRENDINGGITHUB_TWITTER_ACCESS_TOKEN_SECRET")
		twitterFollowNewPerson   = flags.Bool("twitter-follow-new-person", "TRENDINGGITHUB_TWITTER_FOLLOW_NEW_PERSON", false, "Twitter: Follows a friend of one of our followers. Env var: TRENDINGGITHUB_TWITTER_FOLLOW_NEW_PERSON")

		// Timings
		tweetTime                = flags.Duration("twitter-tweet-time", "TRENDINGGITHUB_TWITTER_TWEET_TIME", 5*time.Second, "Twitter: Time interval to search a new project and tweet it. Env var: TRENDINGGITHUB_TWITTER_TWEET_TIME")
		configurationRefreshTime = flags.Duration("twitter-conf-refresh-time", "TRENDINGGITHUB_TWITTER_CONF_REFRESH_TIME", 24*time.Hour, "Twitter: Time interval to refresh the configuration of twitter (e.g. char length for short url). Env var: TRENDINGGITHUB_TWITTER_CONF_REFRESH_TIME")
		followNewPersonTime      = flags.Duration("twitter-follow-new-person-time", "TRENDINGGITHUB_TWITTER_FOLLOW_NEW_PERSON_TIME", 45*time.Minute, "Growth hack: Time interval to search for a new person to follow. Env var: TRENDINGGITHUB_TWITTER_FOLLOW_NEW_PERSON_TIME")

		// Redis storage
		storageURL  = flags.String("storage-url", "TRENDINGGITHUB_STORAGE_URL", ":6379", "Storage URL (e.g. 1.2.3.4:6379 or :6379). Env var: TRENDINGGITHUB_STORAGE_URL")
		storageAuth = flags.String("storage-auth", "TRENDINGGITHUB_STORAGE_AUTH", "", "Storage Auth (e.g. myPassword or <empty>). Env var: TRENDINGGITHUB_STORAGE_AUTH")

		expVarPort  = flags.Int("expvar-port", "TRENDINGGITHUB_EXPVAR_PORT", 8123, "Port which will be used for the expvar TCP server. Env var: TRENDINGGITHUB_EXPVAR_PORT")
		showVersion = flags.Bool("version", "TRENDINGGITHUB_VERSION", false, "Outputs the version number and exit. Env var: TRENDINGGITHUB_VERSION")
		debugMode   = flags.Bool("debug", "TRENDINGGITHUB_DEBUG", false, "Outputs the tweet instead of tweet it (useful for development). Env var: TRENDINGGITHUB_DEBUG")
	)
	flag.Parse()

	// Output the version and exit
	if *showVersion {
		fmt.Printf("@TrendingGithub v%s\n", Version)
		return
	}

	log.Println("Hey, nice to meet you. My name is @GitlabTrending. Lets get ready to tweet some trending content!")
	defer log.Println("Nice sesssion. A lot of knowledge was tweeted. Good work and see you next time!")

	// Prepare the twitter client
	twitterClient := twitter.NewClient(*twitterConsumerKey, *twitterConsumerSecret, *twitterAccessToken, *twitterAccessTokenSecret, *debugMode)

	// When we are running in a debug mode, we are running with a debug configuration.
	// So we don`t need to load the configuration from twitter here.
	if *debugMode == false {
		err := twitterClient.LoadConfiguration()
		if err != nil {
			log.Fatalf("Twitter Configuration initialisation failed: %s", err)
		}
		log.Printf("Twitter Configuration initialisation success: ShortUrlLength %d\n", twitterClient.Configuration.ShortUrlLength)
		twitterClient.SetupConfigurationRefresh(*configurationRefreshTime)
	}

	// Activate our growth hack feature
	// Checkout the README for details or read the code (suggested).
	if *twitterFollowNewPerson {
		log.Println("Growth hack \"Follow a friend of a friend\" activated")
		twitterClient.SetupFollowNewPeopleScheduling(*followNewPersonTime)
	}

	// Request a storage backend
	storageBackend := storage.NewBackend(*storageURL, *storageAuth, *debugMode)
	defer storageBackend.Close()
	log.Println("Storage backend initialisation success")

	// Start the exvar server
	err := expvar_server.StartExpvarServer(*expVarPort)
	if err != nil {
		log.Fatalf("Expvar initialisation failed: %s", err)
	}
	log.Println("Expvar initialisation started ...")

	// Let the party begin
	tweets.StartTweeting(twitterClient, storageBackend, *tweetTime)
}
<commit_msg>fixed default twitter post time<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"time"
    "github.com/joho/godotenv"
	"github.com/whitef0x0/TrendingGithub/flags"
	"github.com/whitef0x0/TrendingGithub/storage"
	"github.com/whitef0x0/TrendingGithub/twitter"
	"github.com/whitef0x0/TrendingGithub/expvar"
	"github.com/whitef0x0/TrendingGithub/tweets"
)

const (
	// Version of @TrendingGithub
	Version = "0.4.0"
)

func main() {
	envErr := godotenv.Load()
	if envErr != nil {
		log.Fatal("Error loading .env file")
	}

	var (
		// Twitter
		twitterConsumerKey       = flags.String("twitter-consumer-key", "TRENDINGGITHUB_TWITTER_CONSUMER_KEY", "", "Twitter-API: Consumer key. Env var: TRENDINGGITHUB_TWITTER_CONSUMER_KEY")
		twitterConsumerSecret    = flags.String("twitter-consumer-secret", "TRENDINGGITHUB_TWITTER_CONSUMER_SECRET", "", "Twitter-API: Consumer secret. Env var: TRENDINGGITHUB_TWITTER_CONSUMER_SECRET")
		twitterAccessToken       = flags.String("twitter-access-token", "TRENDINGGITHUB_TWITTER_ACCESS_TOKEN", "", "Twitter-API: Access token. Env var: TRENDINGGITHUB_TWITTER_ACCESS_TOKEN")
		twitterAccessTokenSecret = flags.String("twitter-access-token-secret", "TRENDINGGITHUB_TWITTER_ACCESS_TOKEN_SECRET", "", "Twitter-API: Access token secret. Env var: TRENDINGGITHUB_TWITTER_ACCESS_TOKEN_SECRET")
		twitterFollowNewPerson   = flags.Bool("twitter-follow-new-person", "TRENDINGGITHUB_TWITTER_FOLLOW_NEW_PERSON", false, "Twitter: Follows a friend of one of our followers. Env var: TRENDINGGITHUB_TWITTER_FOLLOW_NEW_PERSON")

		// Timings
		tweetTime                = flags.Duration("twitter-tweet-time", "TRENDINGGITHUB_TWITTER_TWEET_TIME", 60*time.Minute, "Twitter: Time interval to search a new project and tweet it. Env var: TRENDINGGITHUB_TWITTER_TWEET_TIME")
		configurationRefreshTime = flags.Duration("twitter-conf-refresh-time", "TRENDINGGITHUB_TWITTER_CONF_REFRESH_TIME", 24*time.Hour, "Twitter: Time interval to refresh the configuration of twitter (e.g. char length for short url). Env var: TRENDINGGITHUB_TWITTER_CONF_REFRESH_TIME")
		followNewPersonTime      = flags.Duration("twitter-follow-new-person-time", "TRENDINGGITHUB_TWITTER_FOLLOW_NEW_PERSON_TIME", 45*time.Minute, "Growth hack: Time interval to search for a new person to follow. Env var: TRENDINGGITHUB_TWITTER_FOLLOW_NEW_PERSON_TIME")

		// Redis storage
		storageURL  = flags.String("storage-url", "TRENDINGGITHUB_STORAGE_URL", ":6379", "Storage URL (e.g. 1.2.3.4:6379 or :6379). Env var: TRENDINGGITHUB_STORAGE_URL")
		storageAuth = flags.String("storage-auth", "TRENDINGGITHUB_STORAGE_AUTH", "", "Storage Auth (e.g. myPassword or <empty>). Env var: TRENDINGGITHUB_STORAGE_AUTH")

		expVarPort  = flags.Int("expvar-port", "TRENDINGGITHUB_EXPVAR_PORT", 8123, "Port which will be used for the expvar TCP server. Env var: TRENDINGGITHUB_EXPVAR_PORT")
		showVersion = flags.Bool("version", "TRENDINGGITHUB_VERSION", false, "Outputs the version number and exit. Env var: TRENDINGGITHUB_VERSION")
		debugMode   = flags.Bool("debug", "TRENDINGGITHUB_DEBUG", false, "Outputs the tweet instead of tweet it (useful for development). Env var: TRENDINGGITHUB_DEBUG")
	)
	flag.Parse()

	// Output the version and exit
	if *showVersion {
		fmt.Printf("@TrendingGithub v%s\n", Version)
		return
	}

	log.Println("Hey, nice to meet you. My name is @GitlabTrending. Lets get ready to tweet some trending content!")
	defer log.Println("Nice sesssion. A lot of knowledge was tweeted. Good work and see you next time!")

	// Prepare the twitter client
	twitterClient := twitter.NewClient(*twitterConsumerKey, *twitterConsumerSecret, *twitterAccessToken, *twitterAccessTokenSecret, *debugMode)

	// When we are running in a debug mode, we are running with a debug configuration.
	// So we don`t need to load the configuration from twitter here.
	if *debugMode == false {
		err := twitterClient.LoadConfiguration()
		if err != nil {
			log.Fatalf("Twitter Configuration initialisation failed: %s", err)
		}
		log.Printf("Twitter Configuration initialisation success: ShortUrlLength %d\n", twitterClient.Configuration.ShortUrlLength)
		twitterClient.SetupConfigurationRefresh(*configurationRefreshTime)
	}

	// Activate our growth hack feature
	// Checkout the README for details or read the code (suggested).
	if *twitterFollowNewPerson {
		log.Println("Growth hack \"Follow a friend of a friend\" activated")
		twitterClient.SetupFollowNewPeopleScheduling(*followNewPersonTime)
	}

	// Request a storage backend
	storageBackend := storage.NewBackend(*storageURL, *storageAuth, *debugMode)
	defer storageBackend.Close()
	log.Println("Storage backend initialisation success")

	// Start the exvar server
	err := expvar_server.StartExpvarServer(*expVarPort)
	if err != nil {
		log.Fatalf("Expvar initialisation failed: %s", err)
	}
	log.Println("Expvar initialisation started ...")

	// Let the party begin
	tweets.StartTweeting(twitterClient, storageBackend, *tweetTime)
}
<|endoftext|>


<commit_before>package main

import "text/scanner"
import (
	"os"
	"fmt"
	"strings"
	"strconv"
	"io"
	"flag"
)

type Function struct {
	Exists bool
	Args []bool
	Returns []bool
}

var variables = make( map[string]bool)
var functions = make( map[string]Function)
var unique int

func shunt(name string, s *scanner.Scanner, output io.Writer) string {
		s.Scan()
		switch s.TokenText() {
			case ")", ",", "\n", "]":
				return name
			case "/":
				unique++
				output.Write([]byte("VAR i+shunt+"+fmt.Sprint(unique)+"\n"))
				s.Scan()
				output.Write([]byte("DIV i+shunt+"+fmt.Sprint(unique)+" "+name+" "+expression(s, output)+"\n"))
				return "i+shunt+"+fmt.Sprint(unique)
			case "+":
				unique++
				output.Write([]byte("VAR i+shunt+"+fmt.Sprint(unique)+"\n"))
				s.Scan()
				output.Write([]byte("ADD i+shunt+"+fmt.Sprint(unique)+" "+name+" "+expression(s, output)+"\n"))
				return "i+shunt+"+fmt.Sprint(unique)
			case "²":
				unique++
				output.Write([]byte("VAR i+shunt+"+fmt.Sprint(unique)+"\n"))
				s.Scan()
				output.Write([]byte("MUL i+shunt+"+fmt.Sprint(unique)+" "+name+" "+name+"\n"))
				return "i+shunt+"+fmt.Sprint(unique)
			default:
				println(name, s.TokenText())

		}
		return ""
}

func expression(s *scanner.Scanner, output io.Writer) string {

	//Turn string literals into numeric strings.
	//For example string arguments to a function
	//eg. output("A")
	// ->
	// STRING i+tmp+id
	// PUSH 'A' i+tmp+id
	// PUSHSTRING i+tmp+id
	// RUN output
	if s.TokenText()[0] == '"' {

		unique++
		var newarg string = "STRING i+tmp+"+fmt.Sprint(unique)+"\n"
		var j int
		var arg = s.TokenText()[1:]

		stringloop:
		arg = strings.Replace(arg, "\\n", "\n", -1)
		for _, v := range arg {
			if v == '"' {
				goto end
			}
			newarg += "PUSH "+strconv.Itoa(int(v))+" i+tmp+"+fmt.Sprint(unique)+"\n"
		}
		if len(arg) == 0 {
			goto end
		}
		newarg += "PUSH "+strconv.Itoa(int(' '))+" i+tmp+"+fmt.Sprint(unique)+"\n"
		j++
		//println(arg)
		arg = string(s.TokenText()[j])
		goto stringloop
		end:
		//println(newarg)
		output.Write([]byte(newarg))
		s.Scan()
		return "i+tmp+"+fmt.Sprint(unique)
	}

	if len(s.TokenText()) == 3 && s.TokenText()[0] == '\'' && s.TokenText()[2] == '\'' {
		defer s.Scan()
		return strconv.Itoa(int(s.TokenText()[1]))
	} else if s.TokenText() == `'\n'` {
		defer s.Scan()
		return strconv.Itoa(int('\n'))
	}

	//Is it a literal number?
	if _, err := strconv.Atoi(s.TokenText()); err == nil {
		return shunt(s.TokenText(), s, output)
	} else {

		var name = s.TokenText()

		if functions[name].Exists  {

			var i int
			for tok := s.Scan(); tok != scanner.EOF; {

				s.Scan()
				if s.TokenText() == ")" {
					break
				}

				if len(functions[name].Args) > i {
					if functions[name].Args[i] {
						output.Write([]byte("PUSHSTRING "+expression(s, output)+"\n"))
					} else {
						output.Write([]byte("PUSH "+expression(s, output)+"\n"))
					}
				}

				if s.TokenText() == ")" {
					break
				}
				if s.TokenText() != "," {
					fmt.Println(s.Pos(), "Expecting , found ", s.TokenText())
					os.Exit(1)
				}

			}
			s.Scan()
			unique++
			output.Write([]byte("RUN "+name+"\n"))
			if len(functions[name].Returns) > 0 {
				if functions[name].Returns[0] {
					output.Write([]byte("POPSTRING i+output+"+fmt.Sprint(unique)+"\n"))
				} else {
					output.Write([]byte("POP i+output+"+fmt.Sprint(unique)+"\n"))
				}
			}
			return "i+output+"+fmt.Sprint(unique)
		}

		//Is it a variable?
		if variables[s.TokenText()] {
			return shunt(s.TokenText(), s, output)

		} else {

			// a=2; b=4; ab
			if variables[string(rune(s.TokenText()[0]))] {
				if len(s.TokenText()) == 2 {
					if variables[string(rune(s.TokenText()[1]))] {
						unique++
						output.Write([]byte("VAR i+tmp+"+s.TokenText()+fmt.Sprint(unique)+"\n"))
						output.Write([]byte("MUL i+tmp+"+s.TokenText()+fmt.Sprint(unique)+" "+
							string(rune(s.TokenText()[0]))+" "+
							string(rune(s.TokenText()[1]))+"\n"))

						return shunt("i+tmp+"+s.TokenText()+fmt.Sprint(unique), s, output)
					}
				}
			}

		}

	}
	return shunt(s.TokenText(), s, output)
}

func main() {
	flag.Parse()

	file, err := os.Open(flag.Arg(0))
	if err != nil {
		return
	}

	output, err := os.Create(flag.Arg(0)+".u")
	if err != nil {
		return
	}

	//Add builtin functions.
	builtin(output)

	var s scanner.Scanner
	s.Init(file)
	s.Whitespace= 1<<'\t' | 1<<'\r' | 1<<' '

	var tok rune
	for tok != scanner.EOF {
		tok = s.Scan()

		switch s.TokenText() {
			case "\n":

			case "}":
				output.Write([]byte("END\n"))

			//Inline universal assembly.
			case ".":
				s.Scan()
				output.Write([]byte(strings.ToUpper(s.TokenText()+" ")))
				for tok = s.Scan(); tok != scanner.EOF; {
					if s.TokenText() == "\n" {
						output.Write([]byte("\n"))
						break
					}
					output.Write([]byte(s.TokenText()))
					s.Scan()
				}

			case "return":
				s.Scan()
				output.Write([]byte("PUSH "+expression(&s, output)+"\n"))

			case "software":
				output.Write([]byte("ROUTINE\n"))
				s.Scan()
				if s.TokenText() != "{" {
					fmt.Println(s.Pos(), "Expecting { found ", s.TokenText())
					return
				}
				s.Scan()
				if s.TokenText() != "\n" {
					fmt.Println(s.Pos(), "Expecting newline found ", s.TokenText())
					return
				}

			//Compiles function declerations.
			case "function":
				var name string
				var function Function

				// function name(param1, param2) returns {
				output.Write([]byte("SUBROUTINE "))
				s.Scan()
				output.Write([]byte(s.TokenText()+"\n"))
				name = s.TokenText()
				s.Scan()
				if s.TokenText() != "(" {
					fmt.Println(s.Pos(), "Expecting ( found ", s.TokenText())
					return
				}

				//We need to reverse the POP's because of stack pain.
				var toReverse []string
				for tok = s.Scan(); tok != scanner.EOF; {
					var popstring string
					if s.TokenText() == ")" {
						break
					}
					if s.TokenText() == "[" {

						//Update our function definition with a string argument.
						function.Args = append(function.Args, true)

						popstring += "POPSTRING "
						s.Scan()
						if s.TokenText() != "]" {
							fmt.Println(s.Pos(), "Expecting ] found ", s.TokenText())
							return
						}
						s.Scan()
					} else {
						//Update our function definition with a numeric argument.
						function.Args = append(function.Args, false)

						popstring += "POP "
					}
					popstring += s.TokenText()+"\n"
					toReverse = append(toReverse, popstring)
					s.Scan()
					if s.TokenText() == ")" {
						break
					}
					if s.TokenText() != "," {
						fmt.Println(s.Pos(), "Expecting , found ", s.TokenText())
						return
					}
					s.Scan()
				}
				for i := len(toReverse)-1; i>=0; i-- {
					output.Write([]byte(toReverse[i]))
				}
				s.Scan()
				if s.TokenText() != "{" {
					if s.TokenText() != "[" {
						function.Returns = append(function.Returns, false)
					} else {
						function.Returns = append(function.Returns, true)
						s.Scan()
						if s.TokenText() != "]" {
							fmt.Println(s.Pos(), "Expecting ] found ", s.TokenText())
							return
						}
					}
					s.Scan()
					if s.TokenText() != "{" {
						fmt.Println(s.Pos(), "Expecting { found ", s.TokenText())
						return
					}
				}
				s.Scan()
				if s.TokenText() != "\n" {
					fmt.Println(s.Pos(), "Expecting newline found ", s.TokenText())
					return
				}

				function.Exists = true
				functions[name] = function
			default:

				var name = s.TokenText()
				if functions[name].Exists {
					expression(&s, output)
					continue
				}

				s.Scan()
				switch s.TokenText() {
					case "=":
						// a =
						s.Scan()
						if s.TokenText() == "[" {
							//a = [12,32,92]
							output.Write([]byte("STRING "+name+"\n"))

							for tok = s.Scan(); tok != scanner.EOF; {

								if s.TokenText() == "]" {
									break
								}

								output.Write([]byte("PUSH "+expression(&s, output)+" "+name+"\n"))

								if s.TokenText() == "]" {
									break
								}

								if s.TokenText() != "," {
									fmt.Println(s.Pos(), "Expecting , found ", s.TokenText())
									return
								}
								s.Scan()
							}

						} else {
							variables[name] = true
							output.Write([]byte("VAR "+name+" "+expression(&s, output)+"\n"))
						}
					default:
						fmt.Println(s.Pos(), "Unexpected ", name)
						return
				}

		}
	}
}
<commit_msg>Add other maths operators<commit_after>package main

import "text/scanner"
import (
	"os"
	"fmt"
	"strings"
	"strconv"
	"io"
	"flag"
)

type Function struct {
	Exists bool
	Args []bool
	Returns []bool
}

var variables = make( map[string]bool)
var functions = make( map[string]Function)
var unique int

func shunt(name string, s *scanner.Scanner, output io.Writer) string {
		s.Scan()
		switch s.TokenText() {
			case ")", ",", "\n", "]":
				return name
			case "/":
				unique++
				output.Write([]byte("VAR i+shunt+"+fmt.Sprint(unique)+"\n"))
				s.Scan()
				output.Write([]byte("DIV i+shunt+"+fmt.Sprint(unique)+" "+name+" "+expression(s, output)+"\n"))
				return "i+shunt+"+fmt.Sprint(unique)
			case "+":
				unique++
				output.Write([]byte("VAR i+shunt+"+fmt.Sprint(unique)+"\n"))
				s.Scan()
				output.Write([]byte("ADD i+shunt+"+fmt.Sprint(unique)+" "+name+" "+expression(s, output)+"\n"))
				return "i+shunt+"+fmt.Sprint(unique)
			case "-":
				unique++
				output.Write([]byte("VAR i+shunt+"+fmt.Sprint(unique)+"\n"))
				s.Scan()
				output.Write([]byte("SUB i+shunt+"+fmt.Sprint(unique)+" "+name+" "+expression(s, output)+"\n"))
				return "i+shunt+"+fmt.Sprint(unique)
			case "*":
				unique++
				output.Write([]byte("VAR i+shunt+"+fmt.Sprint(unique)+"\n"))
				s.Scan()
				output.Write([]byte("MUL i+shunt+"+fmt.Sprint(unique)+" "+name+" "+expression(s, output)+"\n"))
				return "i+shunt+"+fmt.Sprint(unique)
			case "mod":
				unique++
				output.Write([]byte("VAR i+shunt+"+fmt.Sprint(unique)+"\n"))
				s.Scan()
				output.Write([]byte("MOD i+shunt+"+fmt.Sprint(unique)+" "+name+" "+expression(s, output)+"\n"))
				return "i+shunt+"+fmt.Sprint(unique)
			case "²":
				unique++
				output.Write([]byte("VAR i+shunt+"+fmt.Sprint(unique)+"\n"))
				s.Scan()
				output.Write([]byte("MUL i+shunt+"+fmt.Sprint(unique)+" "+name+" "+name+"\n"))
				return "i+shunt+"+fmt.Sprint(unique)
			default:
				println(name, s.TokenText())

		}
		return ""
}

func expression(s *scanner.Scanner, output io.Writer) string {

	//Turn string literals into numeric strings.
	//For example string arguments to a function
	//eg. output("A")
	// ->
	// STRING i+tmp+id
	// PUSH 'A' i+tmp+id
	// PUSHSTRING i+tmp+id
	// RUN output
	if s.TokenText()[0] == '"' {

		unique++
		var newarg string = "STRING i+tmp+"+fmt.Sprint(unique)+"\n"
		var j int
		var arg = s.TokenText()[1:]

		stringloop:
		arg = strings.Replace(arg, "\\n", "\n", -1)
		for _, v := range arg {
			if v == '"' {
				goto end
			}
			newarg += "PUSH "+strconv.Itoa(int(v))+" i+tmp+"+fmt.Sprint(unique)+"\n"
		}
		if len(arg) == 0 {
			goto end
		}
		newarg += "PUSH "+strconv.Itoa(int(' '))+" i+tmp+"+fmt.Sprint(unique)+"\n"
		j++
		//println(arg)
		arg = string(s.TokenText()[j])
		goto stringloop
		end:
		//println(newarg)
		output.Write([]byte(newarg))
		s.Scan()
		return "i+tmp+"+fmt.Sprint(unique)
	}

	if len(s.TokenText()) == 3 && s.TokenText()[0] == '\'' && s.TokenText()[2] == '\'' {
		defer s.Scan()
		return strconv.Itoa(int(s.TokenText()[1]))
	} else if s.TokenText() == `'\n'` {
		defer s.Scan()
		return strconv.Itoa(int('\n'))
	}

	//Is it a literal number?
	if _, err := strconv.Atoi(s.TokenText()); err == nil {
		return shunt(s.TokenText(), s, output)
	} else {

		var name = s.TokenText()

		if functions[name].Exists  {

			var i int
			for tok := s.Scan(); tok != scanner.EOF; {

				s.Scan()
				if s.TokenText() == ")" {
					break
				}

				if len(functions[name].Args) > i {
					if functions[name].Args[i] {
						output.Write([]byte("PUSHSTRING "+expression(s, output)+"\n"))
					} else {
						output.Write([]byte("PUSH "+expression(s, output)+"\n"))
					}
				}

				if s.TokenText() == ")" {
					break
				}
				if s.TokenText() != "," {
					fmt.Println(s.Pos(), "Expecting , found ", s.TokenText())
					os.Exit(1)
				}

			}
			s.Scan()
			unique++
			output.Write([]byte("RUN "+name+"\n"))
			if len(functions[name].Returns) > 0 {
				if functions[name].Returns[0] {
					output.Write([]byte("POPSTRING i+output+"+fmt.Sprint(unique)+"\n"))
				} else {
					output.Write([]byte("POP i+output+"+fmt.Sprint(unique)+"\n"))
				}
			}
			return "i+output+"+fmt.Sprint(unique)
		}

		//Is it a variable?
		if variables[s.TokenText()] {
			return shunt(s.TokenText(), s, output)

		} else {

			// a=2; b=4; ab
			if variables[string(rune(s.TokenText()[0]))] {
				if len(s.TokenText()) == 2 {
					if variables[string(rune(s.TokenText()[1]))] {
						unique++
						output.Write([]byte("VAR i+tmp+"+s.TokenText()+fmt.Sprint(unique)+"\n"))
						output.Write([]byte("MUL i+tmp+"+s.TokenText()+fmt.Sprint(unique)+" "+
							string(rune(s.TokenText()[0]))+" "+
							string(rune(s.TokenText()[1]))+"\n"))

						return shunt("i+tmp+"+s.TokenText()+fmt.Sprint(unique), s, output)
					}
				}
			}

		}

	}
	return shunt(s.TokenText(), s, output)
}

func main() {
	flag.Parse()

	file, err := os.Open(flag.Arg(0))
	if err != nil {
		return
	}

	output, err := os.Create(flag.Arg(0)+".u")
	if err != nil {
		return
	}

	//Add builtin functions.
	builtin(output)

	var s scanner.Scanner
	s.Init(file)
	s.Whitespace= 1<<'\t' | 1<<'\r' | 1<<' '

	var tok rune
	for tok != scanner.EOF {
		tok = s.Scan()

		switch s.TokenText() {
			case "\n":

			case "}":
				output.Write([]byte("END\n"))

			//Inline universal assembly.
			case ".":
				s.Scan()
				output.Write([]byte(strings.ToUpper(s.TokenText()+" ")))
				for tok = s.Scan(); tok != scanner.EOF; {
					if s.TokenText() == "\n" {
						output.Write([]byte("\n"))
						break
					}
					output.Write([]byte(s.TokenText()))
					s.Scan()
				}

			case "return":
				s.Scan()
				output.Write([]byte("PUSH "+expression(&s, output)+"\n"))

			case "software":
				output.Write([]byte("ROUTINE\n"))
				s.Scan()
				if s.TokenText() != "{" {
					fmt.Println(s.Pos(), "Expecting { found ", s.TokenText())
					return
				}
				s.Scan()
				if s.TokenText() != "\n" {
					fmt.Println(s.Pos(), "Expecting newline found ", s.TokenText())
					return
				}

			//Compiles function declerations.
			case "function":
				var name string
				var function Function

				// function name(param1, param2) returns {
				output.Write([]byte("SUBROUTINE "))
				s.Scan()
				output.Write([]byte(s.TokenText()+"\n"))
				name = s.TokenText()
				s.Scan()
				if s.TokenText() != "(" {
					fmt.Println(s.Pos(), "Expecting ( found ", s.TokenText())
					return
				}

				//We need to reverse the POP's because of stack pain.
				var toReverse []string
				for tok = s.Scan(); tok != scanner.EOF; {
					var popstring string
					if s.TokenText() == ")" {
						break
					}
					if s.TokenText() == "[" {

						//Update our function definition with a string argument.
						function.Args = append(function.Args, true)

						popstring += "POPSTRING "
						s.Scan()
						if s.TokenText() != "]" {
							fmt.Println(s.Pos(), "Expecting ] found ", s.TokenText())
							return
						}
						s.Scan()
					} else {
						//Update our function definition with a numeric argument.
						function.Args = append(function.Args, false)

						popstring += "POP "
					}
					popstring += s.TokenText()+"\n"
					toReverse = append(toReverse, popstring)
					s.Scan()
					if s.TokenText() == ")" {
						break
					}
					if s.TokenText() != "," {
						fmt.Println(s.Pos(), "Expecting , found ", s.TokenText())
						return
					}
					s.Scan()
				}
				for i := len(toReverse)-1; i>=0; i-- {
					output.Write([]byte(toReverse[i]))
				}
				s.Scan()
				if s.TokenText() != "{" {
					if s.TokenText() != "[" {
						function.Returns = append(function.Returns, false)
					} else {
						function.Returns = append(function.Returns, true)
						s.Scan()
						if s.TokenText() != "]" {
							fmt.Println(s.Pos(), "Expecting ] found ", s.TokenText())
							return
						}
					}
					s.Scan()
					if s.TokenText() != "{" {
						fmt.Println(s.Pos(), "Expecting { found ", s.TokenText())
						return
					}
				}
				s.Scan()
				if s.TokenText() != "\n" {
					fmt.Println(s.Pos(), "Expecting newline found ", s.TokenText())
					return
				}

				function.Exists = true
				functions[name] = function
			default:

				var name = s.TokenText()
				if functions[name].Exists {
					expression(&s, output)
					continue
				}

				s.Scan()
				switch s.TokenText() {
					case "=":
						// a =
						s.Scan()
						if s.TokenText() == "[" {
							//a = [12,32,92]
							output.Write([]byte("STRING "+name+"\n"))

							for tok = s.Scan(); tok != scanner.EOF; {

								if s.TokenText() == "]" {
									break
								}

								output.Write([]byte("PUSH "+expression(&s, output)+" "+name+"\n"))

								if s.TokenText() == "]" {
									break
								}

								if s.TokenText() != "," {
									fmt.Println(s.Pos(), "Expecting , found ", s.TokenText())
									return
								}
								s.Scan()
							}

						} else {
							variables[name] = true
							output.Write([]byte("VAR "+name+" "+expression(&s, output)+"\n"))
						}
					default:
						fmt.Println(s.Pos(), "Unexpected ", name)
						return
				}

		}
	}
}
<|endoftext|>


<commit_before>/*
   Copyright 2011-2012 gtalent2@gmail.com

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
package main

import (
	"fmt"
	"io/ioutil"
	"strings"
)

func findLicense(dir string) (string, error) {
	d, err := ioutil.ReadDir(dir)
	if err != nil {
		return "", err
	}
	for _, v := range d {
		if v.Name() == ".liccor" || v.Name() == ".copyright" {
			licenseData, err := ioutil.ReadFile(dir + "/" + v.Name())
			return string(licenseData), err
		}
	}

	//in the event that it finds no license in the higher level
	//directory, the program conveniently and silently crashes
	//from a stack overflow
	return findLicense(dir + "./.")
}

func findSrcFiles(dir string) ([]string, error) {
	l, err := ioutil.ReadDir(dir)
	if err != nil {
		return nil, err
	}
	output := make([]string, 0)
	for _, v := range l {
		if v.IsDir() {
			files, err := findSrcFiles(dir + "/" + v.Name())
			if err != nil {
				return output, err
			}
			for _, v2 := range files {
				output = append(output, v2)
			}
		} else {
			pt := strings.LastIndex(v.Name(), ".")
			//determine how to format the license
			if pt == -1 {
				continue
			}
			switch v.Name()[pt:] {
			case ".go", ".c", ".cpp", ".cxx", ".h", ".hpp", ".java":
				output = append(output, dir+"/"+v.Name())
			}
		}
	}
	return output, err
}

func main() {
	licenseData, err := findLicense(".")
	if err != nil {
		return
	}
	licenseData = licenseData[0 : len(licenseData)-1]
	lics := make(map[string]string)
	lics["c-like"] = "/*\n * " + strings.Replace(string(licenseData), "\n", "\n * ", -1) + "\n */\n"
	lics["go"] = func() string {
		golic := "/*\n   " + strings.Replace(string(licenseData), "\n", "\n   ", -1) + "\n*/\n"
		golic = strings.Replace(golic, "\n   \n", "\n\n", -1)
		return golic
	}()
	files, err := findSrcFiles(".")
	if err != nil {
		return
	}
	for i := 0; i < len(files); i++ {
		pt := strings.LastIndex(files[i], ".")
		lic := ""
		//determine how to format the license
		switch files[i][pt:] {
		case ".go":
			lic = lics["go"]
		case ".c", ".cpp", ".cxx", ".h", ".hpp", ".java":
			fmt.Print("Correcting ", files[i], "...")
			lic = lics["c-like"]
		}
		changed, err := correct(files[i], lic)
		if changed {
			if err != nil {
				fmt.Println("Correcting", files[i][2:]+"...\tFailure!")
			} else {
				fmt.Println("Correcting", files[i][2:]+"...\tSuccess!")
			}
		}
	}
}

func hasLicense(file string) (bool, int) {
	for i, c := range file {
		switch c {
		case ' ', '\t', '\n':
			continue
		case '/':
			i++
			if len(file) > i && file[i] == '*' {
				return true, i
			}
		default:
			return false, -1
		}
	}
	return false, -1
}

func correct(path, license string) (bool, error) {
	input, err := ioutil.ReadFile(path)
	if err != nil {
		return false, err
	}
	file := string(input)
	orig := file
	if hasLicense, licenseStart := hasLicense(file); hasLicense {
		//remove old license
		for i := licenseStart; i < len(file); i++ {
			if file[i] == '*' && file[i+1] == '/' {
				i += 2
				if file[i] == '\n' {
					i += 1
				}
				file = file[i:len(file)]
				break
			}
		}
	}
	file = license + file
	output := []byte(file)
	if file != orig {
		err = ioutil.WriteFile(path, output, 0)
		return true, err
	}
	return false, nil
}
<commit_msg>Removed a line of debug code that executes when run for C, C++, or Java.<commit_after>/*
   Copyright 2011-2012 gtalent2@gmail.com

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
package main

import (
	"fmt"
	"io/ioutil"
	"strings"
)

func findLicense(dir string) (string, error) {
	d, err := ioutil.ReadDir(dir)
	if err != nil {
		return "", err
	}
	for _, v := range d {
		if v.Name() == ".liccor" || v.Name() == ".copyright" {
			licenseData, err := ioutil.ReadFile(dir + "/" + v.Name())
			return string(licenseData), err
		}
	}

	//in the event that it finds no license in the higher level
	//directory, the program conveniently and silently crashes
	//from a stack overflow
	return findLicense(dir + "./.")
}

func findSrcFiles(dir string) ([]string, error) {
	l, err := ioutil.ReadDir(dir)
	if err != nil {
		return nil, err
	}
	output := make([]string, 0)
	for _, v := range l {
		if v.IsDir() {
			files, err := findSrcFiles(dir + "/" + v.Name())
			if err != nil {
				return output, err
			}
			for _, v2 := range files {
				output = append(output, v2)
			}
		} else {
			pt := strings.LastIndex(v.Name(), ".")
			if pt == -1 {
				continue
			}
			switch v.Name()[pt:] {
			case ".go", ".c", ".cpp", ".cxx", ".h", ".hpp", ".java":
				output = append(output, dir+"/"+v.Name())
			}
		}
	}
	return output, err
}

func main() {
	licenseData, err := findLicense(".")
	if err != nil {
		return
	}
	licenseData = licenseData[0 : len(licenseData)-1]
	lics := make(map[string]string)
	lics["c-like"] = "/*\n * " + strings.Replace(string(licenseData), "\n", "\n * ", -1) + "\n */\n"
	lics["go"] = func() string {
		golic := "/*\n   " + strings.Replace(string(licenseData), "\n", "\n   ", -1) + "\n*/\n"
		golic = strings.Replace(golic, "\n   \n", "\n\n", -1)
		return golic
	}()
	files, err := findSrcFiles(".")
	if err != nil {
		return
	}
	for i := 0; i < len(files); i++ {
		pt := strings.LastIndex(files[i], ".")
		lic := ""
		//determine how to format the license
		switch files[i][pt:] {
		case ".go":
			lic = lics["go"]
		case ".c", ".cpp", ".cxx", ".h", ".hpp", ".java":
			lic = lics["c-like"]
		}
		changed, err := correct(files[i], lic)
		if changed {
			if err != nil {
				fmt.Println("Correcting", files[i][2:]+"...\tFailure!")
			} else {
				fmt.Println("Correcting", files[i][2:]+"...\tSuccess!")
			}
		}
	}
}

func hasLicense(file string) (bool, int) {
	for i, c := range file {
		switch c {
		case ' ', '\t', '\n':
			continue
		case '/':
			i++
			if len(file) > i && file[i] == '*' {
				return true, i
			}
		default:
			return false, -1
		}
	}
	return false, -1
}

func correct(path, license string) (bool, error) {
	input, err := ioutil.ReadFile(path)
	if err != nil {
		return false, err
	}
	file := string(input)
	orig := file
	if hasLicense, licenseStart := hasLicense(file); hasLicense {
		//remove old license
		for i := licenseStart; i < len(file); i++ {
			if file[i] == '*' && file[i+1] == '/' {
				i += 2
				if file[i] == '\n' {
					i += 1
				}
				file = file[i:len(file)]
				break
			}
		}
	}
	file = license + file
	output := []byte(file)
	if file != orig {
		err = ioutil.WriteFile(path, output, 0)
		return true, err
	}
	return false, nil
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/csv"
	"fmt"
	"strconv"
	"log"
	"os"
	"strings"
	"time"
)

const (
	SELLWIRE_TIMESTAMP_FORMAT = "2006-01-02 15:04:05"
	SELLWIRE_TRANSACTION_COLUMN_STATUS=16
	SELLWIRE_TRANSACTION_COLUMN_TRANSACTION_ID=2
	SELLWIRE_TRANSACTION_COLUMN_TIMESTAMP=12
	SELLWIRE_TRANSACTION_COLUMN_CUSTOMER_NAME=3
	SELLWIRE_TRANSACTION_COLUMN_CUSTOMER_TAX=6
	SELLWIRE_TRANSACTION_COLUMN_CUSTOMER_AMOUNT=7
	SELLWIRE_TRANSACTION_COLUMN_CUSTOMER_IS_EU=9
	SELLWIRE_TRANSACTION_COLUMN_CUSTOMER_COUNTRY_CODE=10
	SELLWIRE_TRANSACTION_COLUMN_CUSTOMER_TAX_NUMBER=11
	PAYPAL_DATE_OUTPUT_FORMAT = "02.01.2006"
	STRIPE_TRANSFER_DATE_FORMAT = "2006-01-02 15:04"
	STRIPE_TRANSFER_COLUMN_STATUS=3
	STRIPE_TRANSFER_COLUMN_DATE=0
	STRIPE_TRANSFER_COLUMN_TRANSFER_ID=1
	STRIPE_TRANSFER_COLUMND_AMOUNT=5
	STRIPE_PAYMENT_COLUMN_PAYMENT_ID=0
	STRIPE_PAYMENT_COLUMN_PAYMENT_DATE=2
	STRIPE_PAYMENT_COLUMN_TRANSFER_ID=45
	STRIPE_PAYMENT_COLUMN_STATUS=12
)

type TransactionType string

const (
	TransactionTypePaypal TransactionType = "paypal"
	TransactionTypeStripe TransactionType = "stripe"
)

type Amount struct {
	Dollars int64
	Cents int64
}

func (a Amount) IsZero() bool {
	return a.Dollars == 0 && a.Cents == 0
}

func (a Amount) ToStringGermany() string {
	if a.Dollars == 0 && a.Cents == 0 {
		return ""
	}
	return fmt.Sprintf("%d,%02d",a.Dollars, a.Cents)
}

// VAT % of total amount (including VAT)
func (a Amount) VATPercentOfAsStringGermany(other Amount) string {
	totalCentsA := a.Dollars * 100 + a.Cents
	totalCentsB := other.Dollars * 100 + other.Cents - totalCentsA
	percentage := float64(totalCentsA) * 100.0 / float64(totalCentsB)
	percentageRounded := int64(percentage + 0.5)
	if percentageRounded == 0 {
		return ""
	}
	return fmt.Sprintf("%d%%", percentageRounded)
}

type SellwireTransaction struct {
	TransactionType TransactionType
	TransactionId string
	Timestamp time.Time
	CustomerName string
	Amount Amount
	TaxAmount Amount
	IsEU bool
	IsPrivate bool
	CountryCode string
	TaxNumber string
	IsRefund bool
}

type StripeTransfer struct {
	TransferId string
	Date time.Time
	Amount Amount
	Status string
}

var transactions []SellwireTransaction
var stripeTransfersByTransactionId map[string]StripeTransfer
var vatCorrections map[string]string // from broken number to corrected number (including country prefix)

func main() {
	importVatCorrections()
	importSellwireTransactions()
	importStripeTransferMap()
	outputPaypalTransactions()
	outputStripeTransactions()
}

func importSellwireTransactions() {
	sellwireOrdersFile, err := os.Open("input/SellwireOrders.csv")
	if err != nil {
		log.Fatal(err)
	}
	r := csv.NewReader(sellwireOrdersFile)

	records, err := r.ReadAll()
	if err != nil {
		log.Fatal(err)
	}

	for _, record := range records[1:] {
		status := record[SELLWIRE_TRANSACTION_COLUMN_STATUS]
		if status != "complete" && status != "refunded" {
			continue
		}
		timestampStr := record[SELLWIRE_TRANSACTION_COLUMN_TIMESTAMP]
		timestamp, err := time.Parse(SELLWIRE_TIMESTAMP_FORMAT, timestampStr)
		if err != nil {
			log.Fatal(err)
		}

		countryCode := record[SELLWIRE_TRANSACTION_COLUMN_CUSTOMER_COUNTRY_CODE]
		if countryCode == "" {
			countryCode = "US"
		}
		taxNumber := strings.ToUpper(record[SELLWIRE_TRANSACTION_COLUMN_CUSTOMER_TAX_NUMBER])

		if taxNumber != "" && !strings.HasPrefix(taxNumber, countryCode) {
			taxNumber = fmt.Sprintf("%s%s", countryCode, taxNumber)
		}

		if correction, ok := vatCorrections[taxNumber]; ok {
			taxNumber = correction
		}

		isEU, _ := strconv.ParseBool(record[SELLWIRE_TRANSACTION_COLUMN_CUSTOMER_IS_EU])

		amount := parseAmount(record[SELLWIRE_TRANSACTION_COLUMN_CUSTOMER_AMOUNT])
		taxAmount := parseAmount(record[SELLWIRE_TRANSACTION_COLUMN_CUSTOMER_TAX])

		transactionId := record[SELLWIRE_TRANSACTION_COLUMN_TRANSACTION_ID]

		transactionType := TransactionTypePaypal
		if strings.HasPrefix(transactionId, "ch_") {
			transactionType = TransactionTypeStripe
		}

		if amount.IsZero() {
			continue
		}
		sellwireRecord := SellwireTransaction{
			TransactionType: transactionType,
			TransactionId: transactionId,
			Timestamp: timestamp,
			CustomerName: strings.Title(strings.ToLower(record[SELLWIRE_TRANSACTION_COLUMN_CUSTOMER_NAME])),
			Amount: amount,
			TaxAmount: taxAmount,
			IsEU: isEU,
			IsPrivate: isEU && taxNumber == "",
			CountryCode: countryCode,
			TaxNumber: taxNumber,
			IsRefund: status == "refunded",
		}

		transactions = append(transactions, sellwireRecord)
	}
}

func parseAmount(amountStr string) Amount {
			var amount Amount
			amountStrStripped := strings.Replace(amountStr, ",", "", -1)
			amountParts := strings.Split(amountStrStripped, ".")
			if len(amountParts) > 2 {
				log.Fatalf("Invalid amount found: %s", amountStr)
			}
			if len(amountParts) > 0 {
				dollars, err := strconv.ParseInt(amountParts[0], 10, 64)
				if err != nil {
					log.Fatal(err)
				}
				amount.Dollars = dollars
				if len(amountParts) > 1 {
					cents, err  := strconv.ParseInt(amountParts[1], 10, 64)
					if cents < 10 { // 9.8 is 9 dollar 80 cents and not 9 dollar 8 cents
						cents *= 10
					}
					if err != nil {
						log.Fatal(err)
					}
					amount.Cents = cents
				}
			}
			return amount
		}

func importStripeTransferMap() {
	stripeTransfersByTransferId := make(map[string]StripeTransfer)

	stripeTransfersFile, err := os.Open("input/transfers.csv")
	if err != nil {
		log.Fatal(err)
	}
	r := csv.NewReader(stripeTransfersFile)

	transferRecords, err := r.ReadAll()
	if err != nil {
		log.Fatal(err)
	}

	for _, record := range transferRecords[1:] {
		status := record[STRIPE_TRANSFER_COLUMN_STATUS]

		dateStr := record[STRIPE_TRANSFER_COLUMN_DATE]
		date, err := time.Parse(STRIPE_TRANSFER_DATE_FORMAT, dateStr)
		if err != nil {
			log.Fatal(err)
		}

		var amount Amount
		amountStr := record[STRIPE_TRANSFER_COLUMND_AMOUNT]
		amountStrStripped := strings.Replace(amountStr, ".", "", -1)
		amountParts := strings.Split(amountStrStripped, ",")
		if len(amountParts) > 2 {
			log.Fatalf("Invalid amount found: %s", amountStr)
		}
		if len(amountParts) > 0 {
			dollars, err := strconv.ParseInt(amountParts[0], 10, 64)
			if err != nil {
				log.Fatal(err)
			}
			amount.Dollars = dollars
			if len(amountParts) > 1 {
				cents, err  := strconv.ParseInt(amountParts[1], 10, 64)
				if err != nil {
					log.Fatal(err)
				}
				amount.Cents = cents
			}
		}

		transferId := record[STRIPE_TRANSFER_COLUMN_TRANSFER_ID]

		transferRecord := StripeTransfer{
			TransferId: transferId,
			Date: date,
			Amount: amount,
			Status: status,
		}

		stripeTransfersByTransferId[transferId] = transferRecord
	}

	stripePaymentsFile, err := os.Open("input/payments.csv")
	if err != nil {
		log.Fatal(err)
	}
	r2 := csv.NewReader(stripePaymentsFile)

	paymentRecords, err := r2.ReadAll()
	if err != nil {
		log.Fatal(err)
	}

	stripeTransfersByTransactionId = make(map[string]StripeTransfer)

	for _, record := range paymentRecords[1:] {
		paymentId := record[STRIPE_PAYMENT_COLUMN_PAYMENT_ID]
		transferId := record[STRIPE_PAYMENT_COLUMN_TRANSFER_ID]
		status := record[STRIPE_PAYMENT_COLUMN_STATUS]
		paymentDate := record[STRIPE_PAYMENT_COLUMN_PAYMENT_DATE]

		if status != "Paid" && status != "Refunded" {
			continue
		}

		transfer, ok := stripeTransfersByTransferId[transferId]
		if !ok {
			log.Printf("transfer id %s no transfer found for payment id %s from date %v", transferId, paymentId, paymentDate)
		}
		stripeTransfersByTransactionId[paymentId] = transfer
	}
}

func importVatCorrections() {
	vatCorrections = make(map[string]string)

	correctionsFile, err := os.Open("input/vat_corrections.csv")
	if err != nil {
		log.Fatal(err)
	}
	r := csv.NewReader(correctionsFile)

	corrections, err := r.ReadAll()
	if err != nil {
		log.Fatal(err)
	}

	for _, record := range corrections {
		vatCorrections[record[0]] = record[1]
	}
}

func outputPaypalTransactions() {
	paypalOutput := [][]string{
		{"Datum", "Kundenname", "Betrag USD", "VAT USD", "VAT", "Land", "EU", "Privat", "USt-ID", "Rückerstattet"},
	}

	for _, tx := range transactions {
		if tx.TransactionType != TransactionTypePaypal {
			continue
		}

		isEU := ""
		if tx.IsEU {
			isEU = "x"
		}

		isPrivate := ""
		if tx.IsPrivate {
			isPrivate = "x"
		}
		if !tx.IsEU {
			isPrivate = "-"
		}

		isRefund := ""
		if tx.IsRefund {
			isRefund = "x"
		}

		record := []string{
			tx.Timestamp.Format(PAYPAL_DATE_OUTPUT_FORMAT),
			tx.CustomerName,
			tx.Amount.ToStringGermany(),
			tx.TaxAmount.ToStringGermany(),
			tx.TaxAmount.VATPercentOfAsStringGermany(tx.Amount),
			tx.CountryCode,
			isEU,
			isPrivate,
			tx.TaxNumber,
			isRefund,
		}
		paypalOutput = append(paypalOutput, record)
	}

	outputFile, err := os.Create("output/Paypal.csv")
	if err != nil {
		log.Fatal(err)
	}

	w := csv.NewWriter(outputFile)
	w.WriteAll(paypalOutput)

	if err := w.Error(); err != nil {
		log.Fatalln("error writing paypal output csv: %v", err)
	}
}

func outputStripeTransactions() {
	stripeOutput := [][]string{
		{"Datum", "Kundenname", "Betrag USD", "VAT USD", "VAT", "Land", "EU", "Privat", "USt-ID", "Datum Transfer", "Gesamtbetrag Transfer EUR", "Rückerstattet"},
	}

	for _, tx := range transactions {
		if tx.TransactionType != TransactionTypeStripe {
			continue
		}

		isEU := ""
		if tx.IsEU {
			isEU = "x"
		}

		isPrivate := ""
		if tx.IsPrivate {
			isPrivate = "x"
		}
		if !tx.IsEU {
			isPrivate = "-"
		}

		isRefund := ""
		if tx.IsRefund {
			isRefund = "x"
		}

		transfer := stripeTransfersByTransactionId[tx.TransactionId]

		record := []string{
			tx.Timestamp.Format(PAYPAL_DATE_OUTPUT_FORMAT),
			tx.CustomerName,
			tx.Amount.ToStringGermany(),
			tx.TaxAmount.ToStringGermany(),
			tx.TaxAmount.VATPercentOfAsStringGermany(tx.Amount),
			tx.CountryCode,
			isEU,
			isPrivate,
			tx.TaxNumber,
			transfer.Date.Format(PAYPAL_DATE_OUTPUT_FORMAT),
			transfer.Amount.ToStringGermany(),
			isRefund,
		}
		stripeOutput = append(stripeOutput, record)
	}

	outputFile, err := os.Create("output/Stripe.csv")
	if err != nil {
		log.Fatal(err)
	}

	w := csv.NewWriter(outputFile)
	w.WriteAll(stripeOutput)

	if err := w.Error(); err != nil {
		log.Fatalln("error writing stripe output csv: %v", err)
	}
}
<commit_msg>Stripe transfers were renamed to payouts<commit_after>package main

import (
	"encoding/csv"
	"fmt"
	"strconv"
	"log"
	"os"
	"strings"
	"time"
)

const (
	SELLWIRE_TIMESTAMP_FORMAT = "2006-01-02 15:04:05"
	SELLWIRE_TRANSACTION_COLUMN_STATUS=16
	SELLWIRE_TRANSACTION_COLUMN_TRANSACTION_ID=2
	SELLWIRE_TRANSACTION_COLUMN_TIMESTAMP=12
	SELLWIRE_TRANSACTION_COLUMN_CUSTOMER_NAME=3
	SELLWIRE_TRANSACTION_COLUMN_CUSTOMER_TAX=6
	SELLWIRE_TRANSACTION_COLUMN_CUSTOMER_AMOUNT=7
	SELLWIRE_TRANSACTION_COLUMN_CUSTOMER_IS_EU=9
	SELLWIRE_TRANSACTION_COLUMN_CUSTOMER_COUNTRY_CODE=10
	SELLWIRE_TRANSACTION_COLUMN_CUSTOMER_TAX_NUMBER=11
	PAYPAL_DATE_OUTPUT_FORMAT = "02.01.2006"
	STRIPE_TRANSFER_DATE_FORMAT = "2006-01-02 15:04"
	STRIPE_TRANSFER_COLUMN_STATUS=3
	STRIPE_TRANSFER_COLUMN_DATE=0
	STRIPE_TRANSFER_COLUMN_TRANSFER_ID=1
	STRIPE_TRANSFER_COLUMND_AMOUNT=5
	STRIPE_PAYMENT_COLUMN_PAYMENT_ID=0
	STRIPE_PAYMENT_COLUMN_PAYMENT_DATE=2
	STRIPE_PAYMENT_COLUMN_TRANSFER_ID=45
	STRIPE_PAYMENT_COLUMN_STATUS=12
)

type TransactionType string

const (
	TransactionTypePaypal TransactionType = "paypal"
	TransactionTypeStripe TransactionType = "stripe"
)

type Amount struct {
	Dollars int64
	Cents int64
}

func (a Amount) IsZero() bool {
	return a.Dollars == 0 && a.Cents == 0
}

func (a Amount) ToStringGermany() string {
	if a.Dollars == 0 && a.Cents == 0 {
		return ""
	}
	return fmt.Sprintf("%d,%02d",a.Dollars, a.Cents)
}

// VAT % of total amount (including VAT)
func (a Amount) VATPercentOfAsStringGermany(other Amount) string {
	totalCentsA := a.Dollars * 100 + a.Cents
	totalCentsB := other.Dollars * 100 + other.Cents - totalCentsA
	percentage := float64(totalCentsA) * 100.0 / float64(totalCentsB)
	percentageRounded := int64(percentage + 0.5)
	if percentageRounded == 0 {
		return ""
	}
	return fmt.Sprintf("%d%%", percentageRounded)
}

type SellwireTransaction struct {
	TransactionType TransactionType
	TransactionId string
	Timestamp time.Time
	CustomerName string
	Amount Amount
	TaxAmount Amount
	IsEU bool
	IsPrivate bool
	CountryCode string
	TaxNumber string
	IsRefund bool
}

type StripeTransfer struct {
	TransferId string
	Date time.Time
	Amount Amount
	Status string
}

var transactions []SellwireTransaction
var stripeTransfersByTransactionId map[string]StripeTransfer
var vatCorrections map[string]string // from broken number to corrected number (including country prefix)

func main() {
	importVatCorrections()
	importSellwireTransactions()
	importStripeTransferMap()
	outputPaypalTransactions()
	outputStripeTransactions()
}

func importSellwireTransactions() {
	sellwireOrdersFile, err := os.Open("input/SellwireOrders.csv")
	if err != nil {
		log.Fatal(err)
	}
	r := csv.NewReader(sellwireOrdersFile)

	records, err := r.ReadAll()
	if err != nil {
		log.Fatal(err)
	}

	for _, record := range records[1:] {
		status := record[SELLWIRE_TRANSACTION_COLUMN_STATUS]
		if status != "complete" && status != "refunded" {
			continue
		}
		timestampStr := record[SELLWIRE_TRANSACTION_COLUMN_TIMESTAMP]
		timestamp, err := time.Parse(SELLWIRE_TIMESTAMP_FORMAT, timestampStr)
		if err != nil {
			log.Fatal(err)
		}

		countryCode := record[SELLWIRE_TRANSACTION_COLUMN_CUSTOMER_COUNTRY_CODE]
		if countryCode == "" {
			countryCode = "US"
		}
		taxNumber := strings.ToUpper(record[SELLWIRE_TRANSACTION_COLUMN_CUSTOMER_TAX_NUMBER])

		if taxNumber != "" && !strings.HasPrefix(taxNumber, countryCode) {
			taxNumber = fmt.Sprintf("%s%s", countryCode, taxNumber)
		}

		if correction, ok := vatCorrections[taxNumber]; ok {
			taxNumber = correction
		}

		isEU, _ := strconv.ParseBool(record[SELLWIRE_TRANSACTION_COLUMN_CUSTOMER_IS_EU])

		amount := parseAmount(record[SELLWIRE_TRANSACTION_COLUMN_CUSTOMER_AMOUNT])
		taxAmount := parseAmount(record[SELLWIRE_TRANSACTION_COLUMN_CUSTOMER_TAX])

		transactionId := record[SELLWIRE_TRANSACTION_COLUMN_TRANSACTION_ID]

		transactionType := TransactionTypePaypal
		if strings.HasPrefix(transactionId, "ch_") {
			transactionType = TransactionTypeStripe
		}

		if amount.IsZero() {
			continue
		}
		sellwireRecord := SellwireTransaction{
			TransactionType: transactionType,
			TransactionId: transactionId,
			Timestamp: timestamp,
			CustomerName: strings.Title(strings.ToLower(record[SELLWIRE_TRANSACTION_COLUMN_CUSTOMER_NAME])),
			Amount: amount,
			TaxAmount: taxAmount,
			IsEU: isEU,
			IsPrivate: isEU && taxNumber == "",
			CountryCode: countryCode,
			TaxNumber: taxNumber,
			IsRefund: status == "refunded",
		}

		transactions = append(transactions, sellwireRecord)
	}
}

func parseAmount(amountStr string) Amount {
			var amount Amount
			amountStrStripped := strings.Replace(amountStr, ",", "", -1)
			amountParts := strings.Split(amountStrStripped, ".")
			if len(amountParts) > 2 {
				log.Fatalf("Invalid amount found: %s", amountStr)
			}
			if len(amountParts) > 0 {
				dollars, err := strconv.ParseInt(amountParts[0], 10, 64)
				if err != nil {
					log.Fatal(err)
				}
				amount.Dollars = dollars
				if len(amountParts) > 1 {
					cents, err  := strconv.ParseInt(amountParts[1], 10, 64)
					if cents < 10 { // 9.8 is 9 dollar 80 cents and not 9 dollar 8 cents
						cents *= 10
					}
					if err != nil {
						log.Fatal(err)
					}
					amount.Cents = cents
				}
			}
			return amount
		}

func importStripeTransferMap() {
	stripeTransfersByTransferId := make(map[string]StripeTransfer)

	stripeTransfersFile, err := os.Open("input/payouts.csv")
	if err != nil {
		log.Fatal(err)
	}
	r := csv.NewReader(stripeTransfersFile)

	transferRecords, err := r.ReadAll()
	if err != nil {
		log.Fatal(err)
	}

	for _, record := range transferRecords[1:] {
		status := record[STRIPE_TRANSFER_COLUMN_STATUS]

		dateStr := record[STRIPE_TRANSFER_COLUMN_DATE]
		date, err := time.Parse(STRIPE_TRANSFER_DATE_FORMAT, dateStr)
		if err != nil {
			log.Fatal(err)
		}

		var amount Amount
		amountStr := record[STRIPE_TRANSFER_COLUMND_AMOUNT]
		amountStrStripped := strings.Replace(amountStr, ".", "", -1)
		amountParts := strings.Split(amountStrStripped, ",")
		if len(amountParts) > 2 {
			log.Fatalf("Invalid amount found: %s", amountStr)
		}
		if len(amountParts) > 0 {
			dollars, err := strconv.ParseInt(amountParts[0], 10, 64)
			if err != nil {
				log.Fatal(err)
			}
			amount.Dollars = dollars
			if len(amountParts) > 1 {
				cents, err  := strconv.ParseInt(amountParts[1], 10, 64)
				if err != nil {
					log.Fatal(err)
				}
				amount.Cents = cents
			}
		}

		transferId := record[STRIPE_TRANSFER_COLUMN_TRANSFER_ID]

		transferRecord := StripeTransfer{
			TransferId: transferId,
			Date: date,
			Amount: amount,
			Status: status,
		}

		stripeTransfersByTransferId[transferId] = transferRecord
	}

	stripePaymentsFile, err := os.Open("input/payments.csv")
	if err != nil {
		log.Fatal(err)
	}
	r2 := csv.NewReader(stripePaymentsFile)

	paymentRecords, err := r2.ReadAll()
	if err != nil {
		log.Fatal(err)
	}

	stripeTransfersByTransactionId = make(map[string]StripeTransfer)

	for _, record := range paymentRecords[1:] {
		paymentId := record[STRIPE_PAYMENT_COLUMN_PAYMENT_ID]
		transferId := record[STRIPE_PAYMENT_COLUMN_TRANSFER_ID]
		status := record[STRIPE_PAYMENT_COLUMN_STATUS]
		paymentDate := record[STRIPE_PAYMENT_COLUMN_PAYMENT_DATE]

		if status != "Paid" && status != "Refunded" {
			continue
		}

		transfer, ok := stripeTransfersByTransferId[transferId]
		if !ok {
			log.Printf("transfer id %s no transfer found for payment id %s from date %v", transferId, paymentId, paymentDate)
		}
		stripeTransfersByTransactionId[paymentId] = transfer
	}
}

func importVatCorrections() {
	vatCorrections = make(map[string]string)

	correctionsFile, err := os.Open("input/vat_corrections.csv")
	if err != nil {
		log.Fatal(err)
	}
	r := csv.NewReader(correctionsFile)

	corrections, err := r.ReadAll()
	if err != nil {
		log.Fatal(err)
	}

	for _, record := range corrections {
		vatCorrections[record[0]] = record[1]
	}
}

func outputPaypalTransactions() {
	paypalOutput := [][]string{
		{"Datum", "Kundenname", "Betrag USD", "VAT USD", "VAT", "Land", "EU", "Privat", "USt-ID", "Rückerstattet"},
	}

	for _, tx := range transactions {
		if tx.TransactionType != TransactionTypePaypal {
			continue
		}

		isEU := ""
		if tx.IsEU {
			isEU = "x"
		}

		isPrivate := ""
		if tx.IsPrivate {
			isPrivate = "x"
		}
		if !tx.IsEU {
			isPrivate = "-"
		}

		isRefund := ""
		if tx.IsRefund {
			isRefund = "x"
		}

		record := []string{
			tx.Timestamp.Format(PAYPAL_DATE_OUTPUT_FORMAT),
			tx.CustomerName,
			tx.Amount.ToStringGermany(),
			tx.TaxAmount.ToStringGermany(),
			tx.TaxAmount.VATPercentOfAsStringGermany(tx.Amount),
			tx.CountryCode,
			isEU,
			isPrivate,
			tx.TaxNumber,
			isRefund,
		}
		paypalOutput = append(paypalOutput, record)
	}

	outputFile, err := os.Create("output/Paypal.csv")
	if err != nil {
		log.Fatal(err)
	}

	w := csv.NewWriter(outputFile)
	w.WriteAll(paypalOutput)

	if err := w.Error(); err != nil {
		log.Fatalln("error writing paypal output csv: %v", err)
	}
}

func outputStripeTransactions() {
	stripeOutput := [][]string{
		{"Datum", "Kundenname", "Betrag USD", "VAT USD", "VAT", "Land", "EU", "Privat", "USt-ID", "Datum Transfer", "Gesamtbetrag Transfer EUR", "Rückerstattet"},
	}

	for _, tx := range transactions {
		if tx.TransactionType != TransactionTypeStripe {
			continue
		}

		isEU := ""
		if tx.IsEU {
			isEU = "x"
		}

		isPrivate := ""
		if tx.IsPrivate {
			isPrivate = "x"
		}
		if !tx.IsEU {
			isPrivate = "-"
		}

		isRefund := ""
		if tx.IsRefund {
			isRefund = "x"
		}

		transfer := stripeTransfersByTransactionId[tx.TransactionId]

		record := []string{
			tx.Timestamp.Format(PAYPAL_DATE_OUTPUT_FORMAT),
			tx.CustomerName,
			tx.Amount.ToStringGermany(),
			tx.TaxAmount.ToStringGermany(),
			tx.TaxAmount.VATPercentOfAsStringGermany(tx.Amount),
			tx.CountryCode,
			isEU,
			isPrivate,
			tx.TaxNumber,
			transfer.Date.Format(PAYPAL_DATE_OUTPUT_FORMAT),
			transfer.Amount.ToStringGermany(),
			isRefund,
		}
		stripeOutput = append(stripeOutput, record)
	}

	outputFile, err := os.Create("output/Stripe.csv")
	if err != nil {
		log.Fatal(err)
	}

	w := csv.NewWriter(outputFile)
	w.WriteAll(stripeOutput)

	if err := w.Error(); err != nil {
		log.Fatalln("error writing stripe output csv: %v", err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"database/sql"
	"encoding/json"
	"github.com/gorilla/mux"
	_ "github.com/mattn/go-sqlite3"
	"html"
	"html/template"
	"log"
	"net/http"
	"net/url"
	"os"
	"strconv"
	"strings"
	"time"
)

var dbHandle *sql.DB
var templates = template.Must(template.ParseFiles("index.html"))
var debugLogger *log.Logger
var trackers = "&tr=udp://zer0day.to:1337/announce&tr=udp://tracker.leechers-paradise.org:6969&tr=udp://explodie.org:6969&tr=udp://tracker.opentrackr.org:1337&tr=udp://tracker.coppersurfer.tk:6969"

type Record struct {
	Category         string    `json: "category"`
	Records          []Records `json: "records"`
	QueryRecordCount int       `json: "queryRecordCount"`
	TotalRecordCount int       `json: "totalRecordCount"`
}

type Records struct {
	Id     string       `json: "id"`
	Name   string       `json: "name"`
	Hash   string       `json: "hash"`
	Magnet template.URL `json: "magnet"`
}

func getDBHandle() *sql.DB {
	db, err := sql.Open("sqlite3", "./nyaa.db")
	checkErr(err)
	return db
}

func checkErr(err error) {
	if err != nil {
		debugLogger.Println("   " + err.Error())
		os.Exit(1)
	}
}

func apiHandler(w http.ResponseWriter, r *http.Request) {

	vars := mux.Vars(r)
	page := vars["page"]
	pagenum, _ := strconv.Atoi(html.EscapeString(page))
	b := Record{Records: []Records{}}
	rows, err := dbHandle.Query("select torrent_id, torrent_name, torrent_hash from torrents ORDER BY torrent_id DESC LIMIT 50 offset ?", 50*pagenum-1)
	for rows.Next() {
		var id, name, hash, magnet string
		rows.Scan(&id, &name, &hash)
		magnet = "magnet:?xt=urn:btih:" + hash + "&dn=" + url.QueryEscape(name) + trackers
		res := Records{
			Id:     id,
			Name:   name,
			Hash:   hash,
			Magnet: safe(magnet)}

		b.Records = append(b.Records, res)

	}
	b.QueryRecordCount = 50
	b.TotalRecordCount = 1473098
	rows.Close()
	w.Header().Set("Content-Type", "application/json")
	err = json.NewEncoder(w).Encode(b)

	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
}
func singleapiHandler(w http.ResponseWriter, r *http.Request) {

	vars := mux.Vars(r)
	id := vars["id"]
	b := Record{Records: []Records{}}
	rows, err := dbHandle.Query("select torrent_id, torrent_name, torrent_hash from torrents where torrent_id = ? ORDER BY torrent_id DESC", html.EscapeString(id))
	for rows.Next() {
		var id, name, hash, magnet string
		rows.Scan(&id, &name, &hash)
		magnet = "magnet:?xt=urn:btih:" + hash + "&dn=" + url.QueryEscape(name) + trackers
		res := Records{
			Id:     id,
			Name:   name,
			Hash:   hash,
			Magnet: safe(magnet)}

		b.Records = append(b.Records, res)

	}
	b.QueryRecordCount = 1
	b.TotalRecordCount = 1473098
	rows.Close()
	w.Header().Set("Content-Type", "application/json")
	err = json.NewEncoder(w).Encode(b)

	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
}

func searchHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	page := vars["page"]
	pagenum, _ := strconv.Atoi(html.EscapeString(page))
	param1 := r.URL.Query().Get("q")
	cat := r.URL.Query().Get("c")
	param2 := strings.Split(cat, "_")[0]
	param3 := strings.Split(cat, "_")[1]
	b := Record{Category: cat, Records: []Records{}}
	rows, err := dbHandle.Query("select torrent_id, torrent_name, torrent_hash from torrents "+
		"where torrent_name LIKE ? AND category_id LIKE ? AND sub_category_id LIKE ? "+
		"ORDER BY torrent_id DESC LIMIT 50 offset ?",
		"%"+html.EscapeString(param1)+"%", html.EscapeString(param2)+"%", html.EscapeString(param3)+"%", 50*pagenum-1)
	for rows.Next() {
		var id, name, hash, magnet string
		rows.Scan(&id, &name, &hash)
		magnet = "magnet:?xt=urn:btih:" + hash + "&dn=" + url.QueryEscape(name) + trackers
		res := Records{
			Id:     id,
			Name:   name,
			Hash:   hash,
			Magnet: safe(magnet)}

		b.Records = append(b.Records, res)

	}
	rows.Close()

	err = templates.ExecuteTemplate(w, "index.html", &b)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}
func safe(s string) template.URL {
	return template.URL(s)
}

func rootHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	page := vars["page"]
	pagenum, _ := strconv.Atoi(html.EscapeString(page))
	b := Record{Category: "_", Records: []Records{}}
	rows, err := dbHandle.Query("select torrent_id, torrent_name, torrent_hash from torrents ORDER BY torrent_id DESC LIMIT 50 offset ?", 50*pagenum-1)
	for rows.Next() {
		var id, name, hash, magnet string
		rows.Scan(&id, &name, &hash)
		magnet = "magnet:?xt=urn:btih:" + hash + "&dn=" + url.QueryEscape(name) + trackers
		res := Records{
			Id:     id,
			Name:   name,
			Hash:   hash,
			Magnet: safe(magnet)}

		b.Records = append(b.Records, res)

	}
	b.QueryRecordCount = 50
	b.TotalRecordCount = 1473098
	rows.Close()
	err = templates.ExecuteTemplate(w, "index.html", &b)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

}

func main() {

	dbHandle = getDBHandle()
	router := mux.NewRouter()

	// Routes,
	router.HandleFunc("/", rootHandler)
	router.HandleFunc("/page/{page}", rootHandler)
	router.HandleFunc("/search", searchHandler)
	router.HandleFunc("/search/{page}", searchHandler)
	router.HandleFunc("/api/{page}", apiHandler).Methods("GET")
	router.HandleFunc("/api/torrent/{id}", singleapiHandler).Methods("GET")
	// Set up server,
	srv := &http.Server{
		Handler:      router,
		Addr:         "localhost:9999",
		WriteTimeout: 15 * time.Second,
		ReadTimeout:  15 * time.Second,
	}

	err := srv.ListenAndServe()
	checkErr(err)
}
<commit_msg>ghetto fix<commit_after>package main

import (
	"database/sql"
	"encoding/json"
	"github.com/gorilla/mux"
	_ "github.com/mattn/go-sqlite3"
	"html"
	"html/template"
	"log"
	"net/http"
	"net/url"
	"os"
	"strconv"
	"strings"
	"time"
)

var dbHandle *sql.DB
var templates = template.Must(template.ParseFiles("index.html"))
var debugLogger *log.Logger
var trackers = "&tr=udp://zer0day.to:1337/announce&tr=udp://tracker.leechers-paradise.org:6969&tr=udp://explodie.org:6969&tr=udp://tracker.opentrackr.org:1337&tr=udp://tracker.coppersurfer.tk:6969"

type Record struct {
	Category         string    `json: "category"`
	Records          []Records `json: "records"`
	QueryRecordCount int       `json: "queryRecordCount"`
	TotalRecordCount int       `json: "totalRecordCount"`
}

type Records struct {
	Id     string       `json: "id"`
	Name   string       `json: "name"`
	Hash   string       `json: "hash"`
	Magnet template.URL `json: "magnet"`
}

func getDBHandle() *sql.DB {
	db, err := sql.Open("sqlite3", "./nyaa.db")
	checkErr(err)
	return db
}

func checkErr(err error) {
	if err != nil {
		debugLogger.Println("   " + err.Error())
	}
}

func apiHandler(w http.ResponseWriter, r *http.Request) {

	vars := mux.Vars(r)
	page := vars["page"]
	pagenum, _ := strconv.Atoi(html.EscapeString(page))
	b := Record{Records: []Records{}}
	rows, err := dbHandle.Query("select torrent_id, torrent_name, torrent_hash from torrents ORDER BY torrent_id DESC LIMIT 50 offset ?", 50*pagenum-1)
	for rows.Next() {
		var id, name, hash, magnet string
		rows.Scan(&id, &name, &hash)
		magnet = "magnet:?xt=urn:btih:" + hash + "&dn=" + url.QueryEscape(name) + trackers
		res := Records{
			Id:     id,
			Name:   name,
			Hash:   hash,
			Magnet: safe(magnet)}

		b.Records = append(b.Records, res)

	}
	b.QueryRecordCount = 50
	b.TotalRecordCount = 1473098
	rows.Close()
	w.Header().Set("Content-Type", "application/json")
	err = json.NewEncoder(w).Encode(b)

	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
}
func singleapiHandler(w http.ResponseWriter, r *http.Request) {

	vars := mux.Vars(r)
	id := vars["id"]
	b := Record{Records: []Records{}}
	rows, err := dbHandle.Query("select torrent_id, torrent_name, torrent_hash from torrents where torrent_id = ? ORDER BY torrent_id DESC", html.EscapeString(id))
	for rows.Next() {
		var id, name, hash, magnet string
		rows.Scan(&id, &name, &hash)
		magnet = "magnet:?xt=urn:btih:" + hash + "&dn=" + url.QueryEscape(name) + trackers
		res := Records{
			Id:     id,
			Name:   name,
			Hash:   hash,
			Magnet: safe(magnet)}

		b.Records = append(b.Records, res)

	}
	b.QueryRecordCount = 1
	b.TotalRecordCount = 1473098
	rows.Close()
	w.Header().Set("Content-Type", "application/json")
	err = json.NewEncoder(w).Encode(b)

	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
}

func searchHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	page := vars["page"]
	pagenum, _ := strconv.Atoi(html.EscapeString(page))
	param1 := r.URL.Query().Get("q")
	cat := r.URL.Query().Get("c")
	param2 := strings.Split(cat, "_")[0]
	param3 := strings.Split(cat, "_")[1]
	b := Record{Category: cat, Records: []Records{}}
	rows, err := dbHandle.Query("select torrent_id, torrent_name, torrent_hash from torrents "+
		"where torrent_name LIKE ? AND category_id LIKE ? AND sub_category_id LIKE ? "+
		"ORDER BY torrent_id DESC LIMIT 50 offset ?",
		"%"+html.EscapeString(param1)+"%", html.EscapeString(param2)+"%", html.EscapeString(param3)+"%", 50*pagenum-1)
	for rows.Next() {
		var id, name, hash, magnet string
		rows.Scan(&id, &name, &hash)
		magnet = "magnet:?xt=urn:btih:" + hash + "&dn=" + url.QueryEscape(name) + trackers
		res := Records{
			Id:     id,
			Name:   name,
			Hash:   hash,
			Magnet: safe(magnet)}

		b.Records = append(b.Records, res)

	}
	rows.Close()

	err = templates.ExecuteTemplate(w, "index.html", &b)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}
func safe(s string) template.URL {
	return template.URL(s)
}

func rootHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	page := vars["page"]
	pagenum, _ := strconv.Atoi(html.EscapeString(page))
	b := Record{Category: "_", Records: []Records{}}
	rows, err := dbHandle.Query("select torrent_id, torrent_name, torrent_hash from torrents ORDER BY torrent_id DESC LIMIT 50 offset ?", 50*pagenum-1)
	for rows.Next() {
		var id, name, hash, magnet string
		rows.Scan(&id, &name, &hash)
		magnet = "magnet:?xt=urn:btih:" + hash + "&dn=" + url.QueryEscape(name) + trackers
		res := Records{
			Id:     id,
			Name:   name,
			Hash:   hash,
			Magnet: safe(magnet)}

		b.Records = append(b.Records, res)

	}
	b.QueryRecordCount = 50
	b.TotalRecordCount = 1473098
	rows.Close()
	err = templates.ExecuteTemplate(w, "index.html", &b)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

}

func main() {

	dbHandle = getDBHandle()
	router := mux.NewRouter()

	// Routes,
	router.HandleFunc("/", rootHandler)
	router.HandleFunc("/page/{page}", rootHandler)
	router.HandleFunc("/search", searchHandler)
	router.HandleFunc("/search/{page}", searchHandler)
	router.HandleFunc("/api/{page}", apiHandler).Methods("GET")
	router.HandleFunc("/api/torrent/{id}", singleapiHandler).Methods("GET")
	// Set up server,
	srv := &http.Server{
		Handler:      router,
		Addr:         "localhost:9999",
		WriteTimeout: 15 * time.Second,
		ReadTimeout:  15 * time.Second,
	}

	err := srv.ListenAndServe()
	checkErr(err)
}
<|endoftext|>


<commit_before>package main

import (
    "os"
    "os/exec"

    "io/ioutil"

    "log"

//    "fmt"
    "strings"
    "runtime"
    "strconv" // For Itoa
//    "encoding/csv"
    "encoding/json"

    "github.com/go-martini/martini"
)

func main() {
    m := martini.Classic()

    // CPU count
    m.Get("/sh/numberofcores.php", func () ([]byte, error) {
        return json.Marshal(runtime.NumCPU())
    })

    // Server's hostname
    m.Get("/sh/hostname.php", func () ([]byte, error) {
        host, err := os.Hostname()

        if err != nil {
            return nil, err
        }

        return json.Marshal(host)
    })

    // PS
    m.Get("/sh/ps.php", func () ([]byte, error) {
        // Run uptime command
        rawOutput, err := exec.Command("ps", "aux").Output()

        if err != nil {
            return nil, err
        }

        return json.Marshal(parseCommandTable(rawOutput))
    })

    m.Get("/sh/df.php", func () ([]byte, error) {
        // Run uptime command
        rawOutput, err := exec.Command("df", "-Ph").Output()

        if err != nil {
            return nil, err
        }

        return json.Marshal(parseCommandTable(rawOutput))
    })

    m.Get("/sh/time.php", func () ([]byte, error) {
        raw, err := exec.Command("date").Output()

        if err != nil {
            return nil, err
        }

        return json.Marshal(string(raw[:]))
    })

    m.Get("/sh/issue.php", func () ([]byte, error) {
        raw, err := exec.Command("uname", "-rsm").Output()

        if err != nil {
            return nil, err
        }

        return json.Marshal(string(raw[:]))
    })

    m.Get("/sh/users.php", func () ([]byte, error) {
        data, err := ioutil.ReadFile("/etc/passwd")

        if err != nil {
            return nil, err
        }

        lines := strings.Split(string(data), "\n")

        // Output records
        var records [][]string

        for _, line := range lines {
            parts := strings.Split(line, ":")

            // Skip bad or empty lines
            if len(parts) != 7 {
                log.Println(len(parts))
                continue
            }

            // Parse base 10, 16 bit UID integer
            uid, err := strconv.ParseInt(parts[2], 10, 16)

            // Error parsing UID
            if err != nil {
                continue
            }

            userType := "user"

            // Check if system user
            if uid <= 499 {
                userType = "system"
            }

            user := []string{
                // User type
                userType,
                // Username
                parts[0],
                // Home directory
                parts[6],
            }

            records = append(records, user)
        }

        return json.Marshal(records)
    })

    m.Get("/sh/online.php", func () ([]byte, error) {
        raw, err := exec.Command("w").Output()

        if err != nil {
            return nil, err
        }

        lines := strings.Split(string(raw[:]), "\n")

        // We'll add all the parsed lines here
        var entries [][]string

        // Skip first and last line of output
        for _, str := range lines[2:len(lines)-1] {
            fields := strings.Fields(str)
            entries = append(entries, []string{
                // User
                fields[0],
                // From
                fields[2],
                // Login at
                fields[3],
                // Idle
                fields[4],
            })
        }

        return json.Marshal(entries)
    })

    // Serve static files
    m.Get("/.*", martini.Static(""))

    m.Run()
}

func parseCommandTable(rawOutput []byte) [][]string {
    // Convert output to a string (it's not binary data, so this is ok)
    output := string(rawOutput[:])

    // We'll add all the parsed lines here
    var entries [][]string

    // Lines of output
    lines := strings.Split(output, "\n")

    // Skip first and last line of output
    for _, str := range lines[1:len(lines)-1] {
        entries = append(entries, strings.Fields(str))
    }

    return entries
}<commit_msg>Add newline add end of file<commit_after>package main

import (
    "os"
    "os/exec"

    "io/ioutil"

    "log"

//    "fmt"
    "strings"
    "runtime"
    "strconv" // For Itoa
//    "encoding/csv"
    "encoding/json"

    "github.com/go-martini/martini"
)

func main() {
    m := martini.Classic()

    // CPU count
    m.Get("/sh/numberofcores.php", func () ([]byte, error) {
        return json.Marshal(runtime.NumCPU())
    })

    // Server's hostname
    m.Get("/sh/hostname.php", func () ([]byte, error) {
        host, err := os.Hostname()

        if err != nil {
            return nil, err
        }

        return json.Marshal(host)
    })

    // PS
    m.Get("/sh/ps.php", func () ([]byte, error) {
        // Run uptime command
        rawOutput, err := exec.Command("ps", "aux").Output()

        if err != nil {
            return nil, err
        }

        return json.Marshal(parseCommandTable(rawOutput))
    })

    m.Get("/sh/df.php", func () ([]byte, error) {
        // Run uptime command
        rawOutput, err := exec.Command("df", "-Ph").Output()

        if err != nil {
            return nil, err
        }

        return json.Marshal(parseCommandTable(rawOutput))
    })

    m.Get("/sh/time.php", func () ([]byte, error) {
        raw, err := exec.Command("date").Output()

        if err != nil {
            return nil, err
        }

        return json.Marshal(string(raw[:]))
    })

    m.Get("/sh/issue.php", func () ([]byte, error) {
        raw, err := exec.Command("uname", "-rsm").Output()

        if err != nil {
            return nil, err
        }

        return json.Marshal(string(raw[:]))
    })

    m.Get("/sh/users.php", func () ([]byte, error) {
        data, err := ioutil.ReadFile("/etc/passwd")

        if err != nil {
            return nil, err
        }

        lines := strings.Split(string(data), "\n")

        // Output records
        var records [][]string

        for _, line := range lines {
            parts := strings.Split(line, ":")

            // Skip bad or empty lines
            if len(parts) != 7 {
                log.Println(len(parts))
                continue
            }

            // Parse base 10, 16 bit UID integer
            uid, err := strconv.ParseInt(parts[2], 10, 16)

            // Error parsing UID
            if err != nil {
                continue
            }

            userType := "user"

            // Check if system user
            if uid <= 499 {
                userType = "system"
            }

            user := []string{
                // User type
                userType,
                // Username
                parts[0],
                // Home directory
                parts[6],
            }

            records = append(records, user)
        }

        return json.Marshal(records)
    })

    m.Get("/sh/online.php", func () ([]byte, error) {
        raw, err := exec.Command("w").Output()

        if err != nil {
            return nil, err
        }

        lines := strings.Split(string(raw[:]), "\n")

        // We'll add all the parsed lines here
        var entries [][]string

        // Skip first and last line of output
        for _, str := range lines[2:len(lines)-1] {
            fields := strings.Fields(str)
            entries = append(entries, []string{
                // User
                fields[0],
                // From
                fields[2],
                // Login at
                fields[3],
                // Idle
                fields[4],
            })
        }

        return json.Marshal(entries)
    })

    // Serve static files
    m.Get("/.*", martini.Static(""))

    m.Run()
}

func parseCommandTable(rawOutput []byte) [][]string {
    // Convert output to a string (it's not binary data, so this is ok)
    output := string(rawOutput[:])

    // We'll add all the parsed lines here
    var entries [][]string

    // Lines of output
    lines := strings.Split(output, "\n")

    // Skip first and last line of output
    for _, str := range lines[1:len(lines)-1] {
        entries = append(entries, strings.Fields(str))
    }

    return entries
}
<|endoftext|>