working, needs auth

This commit is contained in:
Neale Pickett 2014-07-24 03:15:04 +00:00
parent 5c178b38f9
commit fa18efdad9
4 changed files with 150 additions and 98 deletions

View File

@ -2,81 +2,20 @@
<html> <html>
<head> <head>
<title>LOL</title> <title>LOL</title>
<script type="application/javascript"> <script type="application/javascript" src="irc.js">
var msgRe = /([^ ]+) (<[^>]+>) (.*)/;
function addMessagePart(p, className, text) {
var e = document.createElement("span");
e.className = className;
e.appendChild(document.createTextNode(text));
p.appendChild(e);
p.appendChild(document.createTextNode(" "));
}
function addMessage(txt) {
var ts = txt.substr(0, 19);
var msg = txt.substr(20);
var a = document.getElementById("a");
var p = document.createElement("p");
m = msg.match(msgRe);
addMessagePart(p, "timestamp", ts);
if (m) {
addMessagePart(p, "forum", m[1]);
addMessagePart(p, "sender", m[2]);
addMessagePart(p, "text", m[3]);
} else {
addMessagePart(p, "raw", msg);
}
a.appendChild(p);
p.scrollIntoView(false);
}
function newmsg(event) {
msgs = event.data.split("\n");
for (var i = 0; i < msgs.length; i += 1) {
addMessage(msgs[i]);
}
}
function handleCommand(event) {
console.log(event);
window.evt = event;
var oReq = new XMLHttpRequest();
function reqListener() {
}
oReq.onload = reqListener;
oReq.open("POST", "chunktail.cgi?post=1", true);
oReq.send(new FormData(event.target));
event.target.reset();
return false;
}
function init() {
var source = new EventSource("chunktail.cgi");
source.onmessage = newmsg;
document.getElementById("command").onsubmit = handleCommand;
}
window.onload = init;
</script> </script>
<style type="text/css"> <style type="text/css">
#a { #a, #kiboze {
max-height: 20em; max-height: 20em;
overflow-y: scroll; overflow: scroll;
overflow-x: hidden;
} }
#a p { #a p, #kiboze p {
margin: 0em 0em 0em 4em; margin: 0em 0em 0em 10em;
text-indent: -4em; text-indent: -10em;
}
#kiboze {
background-color: #ddd;
max-height: 6em;
} }
.timestamp { .timestamp {
color: silver; color: silver;
@ -91,8 +30,11 @@ window.onload = init;
color: purple; color: purple;
} }
#command { input[name~=text] {
width: 75%; width: 60%;
}
input[name~=target] {
width: 8em;
} }
</style> </style>
</head> </head>
@ -100,8 +42,10 @@ window.onload = init;
<div id="a"></div> <div id="a"></div>
<form id="command"> <form id="command">
<input type="hidden" name="type" value="command"> <input type="hidden" name="type" value="command">
<input name="target" value="#tron">
<input name="text" autofocus> <input name="text" autofocus>
<input type="Submit" value="Send"> <input type="Submit" value="Send">
</form> </form>
<div id="kiboze"></div>
</body> </body>
</html> </html>

View File

@ -17,7 +17,7 @@ type Handler struct {
func tail(w http.ResponseWriter, pos int) { func tail(w http.ResponseWriter, pos int) {
f, err := os.Open("/home/neale/bot/neale/log/log") f, err := os.Open("/home/neale/public_html/irc/log")
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
@ -38,7 +38,7 @@ func tail(w http.ResponseWriter, pos int) {
} }
func handleCommand(w http.ResponseWriter, text string) { func handleCommand(w http.ResponseWriter, text string) {
fn := fmt.Sprintf("/home/neale/bot/neale/outq/cgi.%d", time.Now().Unix()) fn := fmt.Sprintf("/home/neale/public_html/irc/outq/cgi.%d", time.Now().Unix())
f, err := os.Create(fn) f, err := os.Create(fn)
if err != nil { if err != nil {
fmt.Fprintln(w, "NO") fmt.Fprintln(w, "NO")

71
irc.go
View File

@ -12,8 +12,6 @@ import (
"time" "time"
) )
var running bool = true
type Message struct { type Message struct {
Command string Command string
FullSender string FullSender string
@ -23,14 +21,32 @@ type Message struct {
Text string Text string
} }
func (m Message) String() string { var running bool = true
a := append([]string{m.FullSender}, m.Args...) var logq chan Message
args := strings.Join(a, " ")
return fmt.Sprintf("%s %s %s %s %s", m.Command, m.Sender, m.Forum, args, m.Text) func isChannel(s string) bool {
switch s[0] {
case '#', '&', '!', '+', '.', '-':
return true
default:
return false
}
} }
func Log(m Message) { func (m Message) String() string {
fmt.Printf("%d %s\n", time.Now().Unix(), m.String()) args := strings.Join(m.Args, " ")
return fmt.Sprintf("%s %s %s %s %s :%s", m.FullSender, m.Command, m.Sender, m.Forum, args, m.Text)
}
func logLoop() {
logf, err := os.OpenFile("log", os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666)
if err != nil {
log.Fatal(err)
}
defer logf.Close()
for m := range logq {
fmt.Fprintf(logf, "%d %s\n", time.Now().Unix(), m.String())
}
} }
func nuhost(s string) (string, string, string) { func nuhost(s string) (string, string, string) {
@ -69,7 +85,8 @@ func readLoop(conn net.Conn, inq chan<- string) {
func writeLoop(conn net.Conn, outq <-chan string) { func writeLoop(conn net.Conn, outq <-chan string) {
for v := range outq { for v := range outq {
fmt.Println(v) m, _ := parse(v)
logq <- m
fmt.Fprintln(conn, v) fmt.Fprintln(conn, v)
} }
} }
@ -79,7 +96,6 @@ func parse(v string) (Message, error) {
var parts []string var parts []string
var lhs string var lhs string
fmt.Println(v)
parts = strings.SplitN(v, " :", 2) parts = strings.SplitN(v, " :", 2)
if len(parts) == 2 { if len(parts) == 2 {
lhs = parts[0] lhs = parts[0]
@ -107,11 +123,10 @@ func parse(v string) (Message, error) {
m.Command = strings.ToUpper(parts[0]) m.Command = strings.ToUpper(parts[0])
switch m.Command { switch m.Command {
case "PRIVMSG", "NOTICE": case "PRIVMSG", "NOTICE":
n, u, _ := nuhost(parts[1]) if isChannel(parts[1]) {
if u == "" { m.Forum = parts[1]
m.Forum = m.Sender
} else { } else {
m.Forum = n m.Forum = m.Sender
} }
case "PART", "MODE", "TOPIC", "KICK": case "PART", "MODE", "TOPIC", "KICK":
m.Forum = parts[1] m.Forum = parts[1]
@ -130,15 +145,21 @@ func parse(v string) (Message, error) {
m.Forum = parts[2] m.Forum = parts[2]
} }
case "NICK": case "NICK":
m.FullSender = parts[1] log.Print(v)
m.Forum = m.FullSender if len(parts) > 1 {
m.Sender = parts[1]
} else {
m.Sender = m.Text
m.Text = ""
}
m.Forum = m.Sender
} }
return m, nil return m, nil
} }
func dispatch(outq chan<- string, m Message) { func dispatch(outq chan<- string, m Message) {
Log(m) logq <- m
switch m.Command { switch m.Command {
case "PING": case "PING":
outq <- "PONG :" + m.Text outq <- "PONG :" + m.Text
@ -147,14 +168,15 @@ func dispatch(outq chan<- string, m Message) {
func handleInfile(path string, outq chan<- string) { func handleInfile(path string, outq chan<- string) {
f, err := os.Open(path) f, err := os.Open(path)
if (err != nil) { if err != nil {
return return
} }
defer f.Close() defer f.Close()
os.Remove(path) os.Remove(path)
inf := bufio.NewScanner(f) inf := bufio.NewScanner(f)
for inf.Scan() { for inf.Scan() {
outq <- inf.Text() txt := inf.Text()
outq <- txt
} }
} }
@ -185,7 +207,6 @@ func usage() {
} }
func main() { func main() {
log.SetFlags(log.LstdFlags | log.Lshortfile)
dotls := flag.Bool("notls", true, "Disable TLS security") dotls := flag.Bool("notls", true, "Disable TLS security")
outqdir := flag.String("outq", "outq", "Output queue directory") outqdir := flag.String("outq", "outq", "Output queue directory")
@ -194,13 +215,13 @@ func main() {
fmt.Fprintln(os.Stderr, "Error: must specify host") fmt.Fprintln(os.Stderr, "Error: must specify host")
os.Exit(69) os.Exit(69)
} }
dir, err := os.Open(*outqdir) dir, err := os.Open(*outqdir)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
defer dir.Close() defer dir.Close()
conn, err := connect(flag.Arg(0), *dotls) conn, err := connect(flag.Arg(0), *dotls)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
@ -208,6 +229,8 @@ func main() {
inq := make(chan string) inq := make(chan string)
outq := make(chan string) outq := make(chan string)
logq = make(chan Message)
go logLoop()
go readLoop(conn, inq) go readLoop(conn, inq)
go writeLoop(conn, outq) go writeLoop(conn, outq)
go monitorDirectory(*outqdir, dir, outq) go monitorDirectory(*outqdir, dir, outq)
@ -221,8 +244,10 @@ func main() {
} }
dispatch(outq, p) dispatch(outq, p)
} }
running = false running = false
close(outq) close(outq)
close(logq)
close(inq)
} }

83
irc.js Normal file
View File

@ -0,0 +1,83 @@
var msgRe = /([^ ]+) (<[^>]+>) (.*)/;
var kibozeRe = "neal";
function addMessagePart(p, className, text) {
var e = document.createElement("span");
e.className = className;
e.appendChild(document.createTextNode(text));
p.appendChild(e);
p.appendChild(document.createTextNode(" "));
}
function addMessage(txt) {
var lhs = txt.split(" :", 1)[0]
var parts = lhs.split(' ')
var ts = new Date(parts[0] * 1000);
var fullSender = parts[1];
var command = parts[2];
var sender = parts[3];
var forum = parts[4];
var args = parts.slice(5);
var msg = txt.substr(lhs.length + 2)
var a = document.getElementById("a");
var p = document.createElement("p");
addMessagePart(p, "timestamp", ts.toLocaleTimeString());
switch (command) {
case "PING":
case "PONG":
return;
break;
case "PRIVMSG":
addMessagePart(p, "forum", forum);
addMessagePart(p, "sender", sender);
addMessagePart(p, "text", msg);
if (-1 != msg.search(kibozeRe)) {
var k = document.getElementById("kiboze");
var p2 = p.cloneNode(true);
k.insertBefore(p2, k.firstChild);
}
break;
default:
addMessagePart(p, "forum", forum);
addMessagePart(p, "sender", sender);
addMessagePart(p, "raw", command + " " + args + " " + msg);
break;
}
a.appendChild(p);
p.scrollIntoView(false);
}
function newmsg(event) {
msgs = event.data.split("\n");
for (var i = 0; i < msgs.length; i += 1) {
addMessage(msgs[i]);
}
}
function handleCommand(event) {
window.evt = event;
var oReq = new XMLHttpRequest();
function reqListener() {
}
oReq.onload = reqListener;
oReq.open("POST", "chunktail.cgi?post=1", true);
oReq.send(new FormData(event.target));
event.target.reset();
return false;
}
function init() {
var source = new EventSource("chunktail.cgi");
source.onmessage = newmsg;
document.getElementById("command").onsubmit = handleCommand;
}
window.onload = init;