lelegram: stuckness fixes, timeout

Change-Id: I3c1ad4e589ea66db846a56aab8a2c1698bdee539
diff --git a/hswaw/kube/teleimg.libsonnet b/hswaw/kube/teleimg.libsonnet
index 84d5d19..49101b2 100644
--- a/hswaw/kube/teleimg.libsonnet
+++ b/hswaw/kube/teleimg.libsonnet
@@ -8,7 +8,7 @@
         },
         image: {
             teleimg: "registry.k0.hswaw.net/q3k/teleimg:1578259776-a07688fe74efe1e190d58092a9f50d4275a15e3d",
-            lelegram: "registry.k0.hswaw.net/q3k/lelegram:1578255597-a885488fd0f9fcd271f6a02416aae5bb3fd9c9ac",
+            lelegram: "registry.k0.hswaw.net/q3k/lelegram:1579785132-a2ee865a0cb74f88ba4b9861598e1efe78c4f066",
         },
         bridge: {
             telegram: "-1001345766954",
diff --git a/personal/q3k/lelegram/irc/conn.go b/personal/q3k/lelegram/irc/conn.go
index 7f130ca..9f1f4ef 100644
--- a/personal/q3k/lelegram/irc/conn.go
+++ b/personal/q3k/lelegram/irc/conn.go
@@ -4,6 +4,7 @@
 	"context"
 	"fmt"
 	"net"
+	"regexp"
 	"strings"
 	"sync"
 	"sync/atomic"
@@ -52,6 +53,8 @@
 	connected int64
 }
 
+var reIRCNick = regexp.MustCompile(`[^a-z0-09]`)
+
 // Say is called by the Manager when a message should be sent out by the
 // connection.
 func (i *ircconn) Say(msg *controlMessage) {
@@ -100,10 +103,14 @@
 	}
 
 	// Generate IRC nick from username.
-	nick := user
+	nick := reIRCNick.ReplaceAllString(user, "")
 	if len(nick) > 13 {
 		nick = nick[:13]
 	}
+	if len(nick) == 0 {
+		glog.Errorf("Could not create IRC nick for %q", user)
+		nick = "wtf"
+	}
 	nick += "[t]"
 
 	// Configure IRC client to populate the IRC Queue.
@@ -186,7 +193,7 @@
 			})
 			if err != nil {
 				glog.Errorf("IRC/%s: WriteMessage: %v", i.user, err)
-				die()
+				die(err)
 				s.done <- err
 				return
 			}
diff --git a/personal/q3k/lelegram/irc/manager_control.go b/personal/q3k/lelegram/irc/manager_control.go
index 68e9002..4e6b0b7 100644
--- a/personal/q3k/lelegram/irc/manager_control.go
+++ b/personal/q3k/lelegram/irc/manager_control.go
@@ -8,16 +8,23 @@
 )
 
 // Control: send a message to IRC.
-func (m *Manager) SendMessage(user, text string) error {
+func (m *Manager) SendMessage(ctx context.Context, user, text string) error {
 	done := make(chan error)
-	m.ctrl <- &control{
+
+	msg := &control{
 		message: &controlMessage{
 			from:    user,
 			message: text,
 			done:    done,
 		},
 	}
-	return <-done
+
+	select {
+	case <-ctx.Done():
+		return ctx.Err()
+	case m.ctrl <- msg:
+		return <-done
+	}
 }
 
 // Control: subscribe to notifiactions.
diff --git a/personal/q3k/lelegram/main.go b/personal/q3k/lelegram/main.go
index ef1ce37..f4360a9 100644
--- a/personal/q3k/lelegram/main.go
+++ b/personal/q3k/lelegram/main.go
@@ -6,6 +6,7 @@
 	"fmt"
 	"strconv"
 	"strings"
+	"time"
 
 	"code.hackerspace.pl/hscloud/go/mirko"
 
@@ -155,12 +156,14 @@
 			// This blocks until success or failure, making sure the log stays
 			// totally ordered in the face of some of our IRC connections being
 			// dead/slow.
-			err := s.mgr.SendMessage(m.user, text)
+			ctxT, cancel := context.WithTimeout(ctx, 15*time.Second)
+			err := s.mgr.SendMessage(ctxT, m.user, text)
 			if err != nil {
 				glog.Warningf("Attempting redelivery of %v after error: %v...", m, err)
-				err = s.mgr.SendMessage(m.user, text)
+				err = s.mgr.SendMessage(ctx, m.user, text)
 				glog.Errorf("Redelivery of %v failed: %v...", m, err)
 			}
+			cancel()
 
 		case n := <-s.ircLog:
 			// Notification from IRC (message or new nickmap)
diff --git a/personal/q3k/lelegram/telegram.go b/personal/q3k/lelegram/telegram.go
index bfb5df9..e6b673c 100644
--- a/personal/q3k/lelegram/telegram.go
+++ b/personal/q3k/lelegram/telegram.go
@@ -38,6 +38,11 @@
 					glog.Infof("[ignored group %d] <%s> %v", u.Message.Chat.ID, u.Message.From, u.Message.Text)
 					continue
 				}
+				date := time.Unix(int64(u.Message.Date), 0)
+				if time.Since(date) > 2*time.Minute {
+					glog.Infof("[old message] <%s> %v", u.Message.From, u.Message.Text)
+					continue
+				}
 				if msg := plainFromTelegram(s.tel.Self.ID, &u); msg != nil {
 					s.telLog <- msg
 				}