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…
Reference in new issue