6.NUR/nur/irc_notify.py
2020-07-15 20:06:11 +01:00

75 lines
1.8 KiB
Python

import socket
import ssl
from typing import List, Optional
from urllib.parse import urlparse
def notify_irc(
server: str,
nick: str,
password: Optional[str],
channel: str,
tls: bool = True,
port: int = 6697,
messages: List[str] = [],
) -> None:
if not messages:
return
sock = socket.socket()
if tls:
sock = ssl.wrap_socket(
sock, cert_reqs=ssl.CERT_NONE, ssl_version=ssl.PROTOCOL_TLSv1_2
)
def _send(command: str) -> int:
return sock.send((f"{command}\r\n").encode())
sock.connect((server, port))
if password:
_send(f"PASS {password}")
_send(f"NICK {nick}")
_send(f"USER {nick} {server} bla :{nick}")
_send(f"JOIN :{channel}")
for m in messages:
_send(f"PRIVMSG {channel} :{m}")
_send("INFO")
while True:
data = sock.recv(4096)
if not data:
raise RuntimeError("Received empty data")
# Assume INFO reply means we are done
if b"End of /INFO list" in data:
break
if data.startswith(b"PING"):
sock.send(data.replace(b"PING", b"PONG"))
sock.send(b"QUIT")
sock.close()
def send(url: str, notifications: List[str]) -> None:
parsed = urlparse(f"http://{url}")
username = parsed.username or "nur-bot"
server = parsed.hostname or "chat.freenode.de"
if parsed.path != "/" or parsed.path == "":
channel = f"#{parsed.path[1:]}"
else:
channel = "#nixos-nur"
port = parsed.port or 6697
password = parsed.password
if len(notifications) == 0:
return
notify_irc(
server=server,
nick=username,
password=password,
channel=channel,
port=port,
messages=notifications,
)