3 Commits

6 changed files with 62 additions and 16 deletions
Split View
  1. +7
    -3
      paircd/client.py
  2. +18
    -0
      paircd/handler/away.py
  3. +9
    -7
      paircd/handler/join.py
  4. +16
    -5
      paircd/handler/privmsg.py
  5. +2
    -0
      paircd/handlers.py
  6. +10
    -1
      paircd/reply.py

+ 7
- 3
paircd/client.py View File

@ -2,7 +2,7 @@ from asyncio import StreamReader, StreamWriter, Queue
from dataclasses import dataclass, field
from datetime import datetime
from logging import log, INFO
from paircd.reply import RPL_CREATED, RPL_WELCOME, RPL_YOURHOST
from paircd.reply import RPL_CREATED, RPL_MYINFO, RPL_WELCOME, RPL_YOURHOST
from paircd.message import Message
from typing import Set
@ -18,6 +18,7 @@ class Client:
username: str = ""
realname: str = ""
registered: bool = False
away: str = ""
channels: Set[str] = field(default_factory=set)
@ -50,6 +51,9 @@ class Client:
self.write_message(RPL_WELCOME(self.nickname, self.id()))
self.write_message(RPL_YOURHOST(self.nickname, "localhost", "paircd-0.0.1"))
# TODO: Pull timestamp from Server instance
# TODO: Pull timestamp from server instance
self.write_message(RPL_CREATED(self.nickname, datetime.utcnow()))
# TODO: Display list of supported user & channel modes
self.write_message(
RPL_MYINFO(self.nickname, "localhost", "paircd-0.0.1", "", "")
)

+ 18
- 0
paircd/handler/away.py View File

@ -0,0 +1,18 @@
from paircd.client import Client
from paircd.command_handler import CommandHandler
from paircd.message import Message
from paircd.reply import RPL_NOWAWAY, RPL_UNAWAY
from paircd.server import Server
class AwayHandler(CommandHandler):
def __init__(self) -> None:
super().__init__("AWAY")
async def handle(self, server: Server, client: Client, msg: Message) -> None:
if len(msg.args) == 0 or len(msg.args[0]) == 0:
client.away = ""
client.write_message(RPL_UNAWAY(client.nickname))
else:
client.away = msg.args[0]
client.write_message(RPL_NOWAWAY(client.nickname))

+ 9
- 7
paircd/handler/join.py View File

@ -1,5 +1,11 @@
import logging
from paircd.reply import JOIN, RPL_ENDOFNAMES, RPL_NAMREPLY, RPL_TOPIC
from paircd.reply import (
ERR_NOSUCHCHANNEL,
ERR_NOTREGISTERED,
JOIN,
RPL_ENDOFNAMES,
RPL_NAMREPLY,
RPL_TOPIC,
)
from paircd.client import Client
from paircd.command_handler import CommandHandler
@ -12,13 +18,9 @@ class JoinHandler(CommandHandler):
super().__init__("JOIN", 1)
async def handle(self, server: Server, client: Client, msg: Message) -> None:
if not client.registered:
client.log("join: not registered", level=logging.WARN)
return
channel_name = msg.args[0]
if not channel_name.startswith("#"):
client.log("tried to join invalid channel", level=logging.WARN)
client.write_message(ERR_NOSUCHCHANNEL(client.nickname, channel_name))
return
channel = server.get_channel_by_name(channel_name)

+ 16
- 5
paircd/handler/privmsg.py View File

@ -1,9 +1,13 @@
import logging
from paircd.client import Client
from paircd.command_handler import CommandHandler
from paircd.message import Message
from paircd.reply import PRIVMSG
from paircd.reply import (
ERR_NOSUCHNICK,
ERR_NOTEXTTOSEND,
ERR_NOTREGISTERED,
PRIVMSG,
RPL_AWAY,
)
from paircd.server import Server
@ -13,10 +17,17 @@ class PrivmsgHandler(CommandHandler):
async def handle(self, server: Server, client: Client, msg: Message) -> None:
recipient, raw_msg = msg.args
out = PRIVMSG(recipient, raw_msg, prefix=client.id())
if len(raw_msg) == 0:
client.write_message(ERR_NOTEXTTOSEND(client.nickname))
return
out = PRIVMSG(recipient, raw_msg, prefix=client.id())
for name, other_client in server.clients_by_nick.items():
if name == recipient:
if other_client.away:
client.write_message(
RPL_AWAY(client.nickname, name, other_client.away)
)
other_client.write_message(out)
return
@ -25,4 +36,4 @@ class PrivmsgHandler(CommandHandler):
channel.write_message(out)
return
client.log("unknown recipient", level=logging.WARN)
client.write_message(ERR_NOSUCHNICK(client.nickname, recipient))

+ 2
- 0
paircd/handlers.py View File

@ -1,4 +1,5 @@
from logging import WARN
from paircd.handler.away import AwayHandler
from typing import Dict
from paircd.client import Client
@ -15,6 +16,7 @@ from paircd.handler.user import UserHandler
from paircd.handler.who import WhoHandler
HANDLER_CLASSES = [
AwayHandler,
JoinHandler,
ModeHandler,
NickHandler,

+ 10
- 1
paircd/reply.py View File

@ -31,12 +31,21 @@ PRIVMSG = cmd_fn("PRIVMSG", "{0} :{1}")
# Error replies
ERR_NOSUCHNICK = reply_fn(401, "{0} :No such nick/channel")
ERR_NOSUCHSERVER = reply_fn(402, "{0}: No such server")
ERR_NOSUCHSERVER = reply_fn(402, "{0} :No such server")
ERR_NOSUCHCHANNEL = reply_fn(403, "{0} :No such channel")
ERR_CANNOTSENDTOCHAN = reply_fn(404, "{0} :Cannot send to channel")
ERR_TOOMANYCHANNELS = reply_fn(405, "{0} :You have joined too many channels")
ERR_NOTEXTTOSEND = reply_fn(412, ":No text to send")
ERR_NOTREGISTERED = reply_fn(451, ":You have not registered")
# Command responses
RPL_WELCOME = reply_fn("001", "Welcome to the Internet Relay Network {0}")
RPL_YOURHOST = reply_fn("002", "Your host is {0}, running version {1}")
RPL_CREATED = reply_fn("003", "This server was created {0}")
RPL_MYINFO = reply_fn("004", "{0} {1} {2} {3}")
RPL_AWAY = reply_fn(301, "{0} :{1}")
RPL_UNAWAY = reply_fn(305, ":You are no longer marked as being away")
RPL_NOWAWAY = reply_fn(306, ":You have been marked as being away")
RPL_WHOISUSER = reply_fn(311, "{0} {1} {2} * :{3}")
RPL_ENDOFWHO = reply_fn(315, "{0} :End of /WHO list")
RPL_ENDOFWHOIS = reply_fn(318, "{0} :End of /WHOIS list")

Loading…
Cancel
Save