Merge pull request #251 from nix-community/fix-irc

This commit is contained in:
Jörg Thalheim 2020-07-16 23:10:08 +01:00 committed by GitHub
commit e32b34c635
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 53 additions and 74 deletions

View file

@ -11,6 +11,7 @@ from typing import Dict, List, Optional, Tuple
from .fileutils import chdir, write_json_file
from .manifest import Repo, load_manifest, update_lock_file
from .path import LOCK_PATH, MANIFEST_PATH, ROOT
from .irc_notify import send
logger = logging.getLogger(__name__)
@ -186,12 +187,6 @@ def combine_command(args: Namespace) -> None:
notifications = update_combined(combined_path)
if args.irc_notify:
try:
from .irc_notify import send
except ImportError as e:
print(f"failed to import irc_notify, skipping notification: {e}")
return
try:
send(args.irc_notify, notifications)
except Exception as e:

View file

@ -1,13 +1,56 @@
import socket
import ssl
from typing import List, Optional
from urllib.parse import urlparse
from irc.client import Connection, Event, Reactor, ServerConnectionError, is_channel
from irc.connection import Factory
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
class Exit(SystemExit):
pass
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:
@ -22,65 +65,11 @@ def send(url: str, notifications: List[str]) -> None:
password = parsed.password
if len(notifications) == 0:
return
_send(
notifications=notifications,
nickname=username,
password=password,
notify_irc(
server=server,
nick=username,
password=password,
channel=channel,
port=port,
messages=notifications,
)
class _send:
def __init__(
self,
notifications: List[str],
server: str,
nickname: str,
port: int,
channel: str,
password: Optional[str] = None,
use_ssl: bool = True,
) -> None:
self.notifications = notifications
self.channel = channel
ssl_factory = None
if use_ssl:
ssl_factory = Factory(wrapper=ssl.wrap_socket)
reactor = Reactor()
try:
s = reactor.server()
c = s.connect(
server, port, nickname, password=password, connect_factory=ssl_factory
)
except ServerConnectionError as e:
print(f"error sending irc notification {e}")
return
c.add_global_handler("welcome", self.on_connect)
c.add_global_handler("join", self.on_join)
c.add_global_handler("disconnect", self.on_disconnect)
try:
reactor.process_forever()
except Exit:
pass
def on_connect(self, connection: Connection, event: Event) -> None:
if is_channel(self.channel):
connection.join(self.channel)
return
self.main_loop(connection)
def on_join(self, connection: Connection, event: Event) -> None:
self.main_loop(connection)
def on_disconnect(self, connection: Connection, event: Event) -> None:
raise Exit()
def main_loop(self, connection: Connection) -> None:
for notification in self.notifications:
connection.privmsg(self.channel, notification)
connection.quit("Bye")

View file

@ -1,6 +1,5 @@
[tool.black]
line-length = 88
py36 = true
include = '\.pyi?$'
exclude = '''
/(

View file

@ -6,11 +6,7 @@ python3Packages.buildPythonApplication {
name = "nur";
src = ./.;
# FIXME: uncomment after the next nixpkgs channel bump
#propagatedBuildInputs = [ python3Packages.irc ];
# import irc does not work right now.
doCheck = false;
doCheck = true;
makeWrapperArgs = [
"--prefix" "PATH" ":" "${stdenv.lib.makeBinPath [ nix-prefetch-git git nix ]}"