From d07ddadedb8a92e4efde64cd0236754a3b9192bf Mon Sep 17 00:00:00 2001
From: raylu <raylu@cmu.edu>
Date: Tue, 26 Oct 2010 23:56:10 -0400
Subject: [PATCH] Intial calc. Need to handle html unescape and superscripts

---
 cmd-google.go | 41 +++++++++++++++++++++++++++++++++++++++++
 handler.go    |  1 +
 2 files changed, 42 insertions(+)

diff --git a/cmd-google.go b/cmd-google.go
index 5430a5b..6eebcde 100644
--- a/cmd-google.go
+++ b/cmd-google.go
@@ -3,12 +3,15 @@ package main
 import (
 	"irc"
 	"fmt"
+	"os"
 	"strings"
 	"http"
 	"json"
 	"io/ioutil"
 	"container/vector"
 	"html"
+	"regexp"
+	"strconv"
 )
 
 const googleAPIKey = "ABQIAAAA6-N_jl4ETgtMf2M52JJ_WRQjQjNunkAJHIhTdFoxe8Di7fkkYhRRcys7ZxNbH3MIy_MKKcEO4-9_Ag"
@@ -79,3 +82,41 @@ func sayTr(conn *irc.Conn, target string, data interface{}) {
 		say(conn, target, html.UnescapeString(trText))
 	}
 }
+
+func calc(conn *irc.Conn, nick *irc.Nick, args, target string) {
+	if args == "" {
+		return
+	}
+	url := fmt.Sprintf("http://www.google.com/ig/calculator?hl=en&q=%s&key=%s", http.URLEscape(args), googleAPIKey)
+	response, _, err := http.Get(url)
+	defer response.Body.Close()
+	if err != nil {
+		say(conn, target, "%s: Error while requesting calculation", nick.Nick); return
+	}
+
+	b, err := ioutil.ReadAll(response.Body)
+	if err != nil {
+		say(conn, target, "%s: Error while downloading calculation", nick.Nick); return
+	}
+
+	re := regexp.MustCompile(`{lhs: "(.*)",rhs: "(.*)",error: "(.*)",icc: (true|false)}`)
+	result := re.FindSubmatch(b)
+	if len(result) != 5 || len(result[3]) > 1 {
+		say(conn, target, "%s: Error while calculating.", nick.Nick); return
+	}
+
+	str := fmt.Sprintf("%s = %s", result[1], result[2])
+	output := ""
+	// decode unicode escapes
+	for str != "" {
+		var err os.Error
+		var rune int
+		rune, _, str, err = strconv.UnquoteChar(str, 0)
+		if err != nil {
+			say(conn, target, "%s: Error while decoding.", nick.Nick); return
+		}
+		output += string(rune)
+	}
+	output = html.UnescapeString(output)
+	say(conn, target, output)
+}
diff --git a/handler.go b/handler.go
index 3679489..c69005d 100644
--- a/handler.go
+++ b/handler.go
@@ -35,6 +35,7 @@ var commands = map [string]func(*irc.Conn, *irc.Nick, string, string) {
 
 	// google
 	"tr": translate,
+	"calc": calc,
 }
 
 func handlePrivmsg(conn *irc.Conn, line *irc.Line) {