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