Initial commit

master
dsc 2 years ago
commit ac877be2ae

@ -0,0 +1,10 @@
```text
virtualenv -p /usr/bin/python3 venv
source venv/bin/activate
pip install -r requirements.txt
# edit settings.py
ufw allow 7000
python3 run.py
```

@ -0,0 +1,40 @@
import os
import re
import asyncio
from typing import Set
from datetime import datetime
import json
from quart import Quart, render_template, request, redirect
import bottom
import settings
irc_bot = None
connected_websockets: Set[asyncio.Queue] = set()
async def _setup_irc(app: Quart):
global irc_bot
loop = asyncio.get_event_loop()
irc_bot = bottom.Client(host=settings.IRC_HOST, port=settings.IRC_PORT, ssl=settings.IRC_SSL, loop=loop)
from ircserver.irc import start
start()
#asyncio.create_task(message_worker())
async def process_loop():
while True:
await asyncio.sleep(1)
def create_app():
global app
app = Quart(__name__)
@app.before_serving
async def startup():
await _setup_irc(app)
import ircserver.routes
return app

@ -0,0 +1,70 @@
from typing import List, Optional
from datetime import datetime
import os
import time
import asyncio
import random
from ircserver.factory import connected_websockets
from ircserver.factory import irc_bot as bot
import settings
msg_queue = asyncio.Queue()
messages = []
@bot.on('CLIENT_CONNECT')
async def connect(**kwargs):
bot.send('NICK', nick=settings.IRC_NICK)
bot.send('USER', user=settings.IRC_NICK, realname=settings.IRC_REALNAME)
# Don't try to join channels until server sent MOTD
done, pending = await asyncio.wait(
[bot.wait("RPL_ENDOFMOTD"), bot.wait("ERR_NOMOTD")],
loop=bot.loop,
return_when=asyncio.FIRST_COMPLETED
)
# Cancel whichever waiter's event didn't come in.
for future in pending:
future.cancel()
bot.send('JOIN', channel=settings.IRC_CHANNEL)
@bot.on('PING')
def keepalive(message, **kwargs):
bot.send('PONG', message=message)
@bot.on('client_disconnect')
def reconnect(**kwargs):
from quart import current_app as app
app.logger.warning("Lost IRC server connection")
time.sleep(3)
bot.loop.create_task(bot.connect())
app.logger.warning("Reconnecting to IRC server")
@bot.on('PRIVMSG')
async def message(nick, target, message, **kwargs):
if nick == settings.IRC_NICK:
return
if target == settings.IRC_NICK:
target = nick
msg = message
now = datetime.now()
now = time.mktime(now.timetuple())
data = {"nick": nick, "message": msg, "date": now}
for ws in connected_websockets:
await ws.put({"data": [data]})
messages.append(data)
if len(messages) > 20:
messages.pop(0)
def start():
bot.loop.create_task(bot.connect())

@ -0,0 +1,48 @@
import asyncio
import json
import time
from datetime import datetime
from quart import websocket
from quart import current_app as app
import settings
from ircserver.utils import collect_websocket
@app.websocket('/ws')
@collect_websocket
async def ws(queue):
from ircserver.irc import messages
from ircserver.factory import irc_bot as bot
if messages:
await websocket.send(json.dumps({"data": messages}).encode())
async def rx():
while True:
buffer = await websocket.receive()
try:
if buffer:
bot.send("PRIVMSG", target=settings.IRC_CHANNEL, message=buffer.decode())
now = datetime.now()
now = time.mktime(now.timetuple())
messages.append({"nick": "d4irc", "message": buffer.decode(), "now": now})
if len(messages) > 20:
messages.pop(0)
except Exception as ex:
continue
async def tx():
while True:
data = await queue.get()
payload = json.dumps(data).encode()
await websocket.send(payload)
consumer_task = asyncio.ensure_future(rx())
producer_task = asyncio.ensure_future(tx())
try:
await asyncio.gather(consumer_task, producer_task)
finally:
consumer_task.cancel()
producer_task.cancel()

@ -0,0 +1,25 @@
import re
import json
import asyncio
import os
import random
from datetime import datetime
from collections import Counter
from functools import wraps
from typing import List, Union
from io import BytesIO
import settings
def collect_websocket(func):
@wraps(func)
async def wrapper(*args, **kwargs):
from ircserver.factory import connected_websockets
queue = asyncio.Queue()
connected_websockets.add(queue)
try:
return await func(queue, *args, **kwargs)
finally:
connected_websockets.remove(queue)
return wrapper

@ -0,0 +1,2 @@
quart
bottom

@ -0,0 +1,5 @@
from ircserver.factory import create_app
import settings
app = create_app()
app.run(settings.BIND_HOST, 7000, debug=settings.DEBUG)

@ -0,0 +1,9 @@
IRC_HOST = "94.125.182.252"
IRC_PORT = 6667
IRC_SSL = False
IRC_NICK = "d4irc"
IRC_CHANNEL = "#maemo-leste"
IRC_REALNAME = "d4irc"
DEBUG = True
URL = '/'
BIND_HOST = "135.125.235.26"
Loading…
Cancel
Save