working, needs auth
This commit is contained in:
parent
5c178b38f9
commit
fa18efdad9
90
index.html
90
index.html
|
@ -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>
|
||||||
|
|
|
@ -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
71
irc.go
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
Loading…
Reference in New Issue