Browse Source

Quasiment fonctionnel mais quelques trucs à réglèw

master
hadware 8 years ago
parent
commit
626da2c594
  1. 5
      cocobot.py
  2. 1
      requirements.txt
  3. 45
      tools/base.py
  4. 14
      tools/coco/client.py
  5. 2
      tools/coco/tools.py
  6. 5
      tools/processors/messages.py

5
cocobot.py

@ -4,7 +4,6 @@ import argparse
import asyncio import asyncio
import logging import logging
from tools.coco
from tools.base import CoboBot from tools.base import CoboBot
from tools.processors import MessageDispatcher, CommandsDispatcherProcessor, ConnectionDispatcher from tools.processors import MessageDispatcher, CommandsDispatcherProcessor, ConnectionDispatcher
from tools.processors.messages import * from tools.processors.messages import *
@ -35,11 +34,11 @@ root_messages_dispatcher = MessageDispatcher([coco_commands])
connections_dispatcher = ConnectionDispatcher([]) connections_dispatcher = ConnectionDispatcher([])
if __name__ == "__main__": if __name__ == "__main__":
logging.getLogger().setLevel(logging.INFO) logging.getLogger().setLevel(logging.DEBUG)
args = parser.parse_args() args = parser.parse_args()
cocobot = CoboBot(args.cookie, args.channel, args.domain, args.port, args.method, cocobot = CoboBot(args.cookie, args.channel, args.domain, args.port, args.method,
root_messages_dispatcher, connections_dispatcher) root_messages_dispatcher, connections_dispatcher, cococlient)
asyncio.get_event_loop().run_until_complete(cocobot.listen()) asyncio.get_event_loop().run_until_complete(cocobot.listen())

1
requirements.txt

@ -1 +1,2 @@
bidict bidict
websockets

45
tools/base.py

@ -2,17 +2,22 @@ import html
import json import json
import logging import logging
from asyncio import sleep, gather
import websockets import websockets
from tools.coco.client import CocoClient
from tools.commons import AbstractResponse, Message, BotMessage, AttackCommand, Sound, UserList from tools.commons import AbstractResponse, Message, BotMessage, AttackCommand, Sound, UserList
from tools.processors import MessageDispatcher, ConnectionDispatcher from tools.processors import MessageDispatcher, ConnectionDispatcher
class CoboBot: class CoboBot:
COCO_PULSE_TICK = 1 # number of seconds between each check
def __init__(self, cookie: str, channel: str, domain: str, port: int, method: str, def __init__(self, cookie: str, channel: str, domain: str, port: int, method: str,
messages_dispatcher: MessageDispatcher, messages_dispatcher: MessageDispatcher,
connect_dispatcher : ConnectionDispatcher): connect_dispatcher: ConnectionDispatcher,
cococlient: CocoClient):
# setting up variables required by the server. The default is a Kabutops on the main lou server, I think # setting up variables required by the server. The default is a Kabutops on the main lou server, I think
self.cookie = cookie self.cookie = cookie
@ -23,6 +28,7 @@ class CoboBot:
self.msg_dispatch = messages_dispatcher self.msg_dispatch = messages_dispatcher
self.cnt_dispatch = connect_dispatcher self.cnt_dispatch = connect_dispatcher
self.user_list = None # type: UserList self.user_list = None # type: UserList
self.cococlient = cococlient
async def _send_message(self, message): async def _send_message(self, message):
if isinstance(message, dict): if isinstance(message, dict):
@ -64,18 +70,9 @@ class CoboBot:
elif isinstance(response, AbstractResponse): elif isinstance(response, AbstractResponse):
await self._dispatch_response(response) await self._dispatch_response(response)
async def listen(self): async def socket_listener(self):
if self.method == "https":
socket_address = 'wss://%s/socket/%s' % (self.domain, self.channel)
else:
socket_address = 'ws://%s:%i/socket/%s' % (self.domain, self.port, self.channel)
logging.info("Listening to socket on %s" % socket_address)
async with websockets.connect(socket_address,
extra_headers={"cookie": "id=%s" % self.cookie}) as websocket:
self.socket = websocket
while True: while True:
msg = await websocket.recv() msg = await self.socket.recv()
websocket.recv()
if type(msg) != bytes: if type(msg) != bytes:
msg_data = json.loads(msg, encoding="utf-8") msg_data = json.loads(msg, encoding="utf-8")
msg_type = msg_data.get("type", "") msg_type = msg_data.get("type", "")
@ -95,3 +92,27 @@ class CoboBot:
else: else:
logging.debug("Received sound file") logging.debug("Received sound file")
async def coco_pulse(self):
while True:
logging.debug("Checking coco for new messages")
await sleep(self.COCO_PULSE_TICK)
if self.cococlient.is_connected:
new_messages = self.cococlient.pulse()
if isinstance(new_messages, list):
for response_obj in new_messages:
await self._dispatch_response(response_obj)
elif isinstance(new_messages, AbstractResponse):
await self._dispatch_response(new_messages)
async def listen(self):
if self.method == "https":
socket_address = 'wss://%s/socket/%s' % (self.domain, self.channel)
else:
socket_address = 'ws://%s:%i/socket/%s' % (self.domain, self.port, self.channel)
logging.info("Listening to socket on %s" % socket_address)
async with websockets.connect(socket_address,
extra_headers={"cookie": "id=%s" % self.cookie}) as websocket:
self.socket = websocket
await gather(self.socket_listener(), self.coco_pulse())

14
tools/coco/client.py

@ -1,10 +1,11 @@
import logging
import random import random
from typing import List, Dict, Tuple, Union, Set from typing import List, Dict, Tuple, Union, Set
from collections import defaultdict
from .requests import LoginRequest, PostLoginRequest, PulseRequest, SendMsgRequest from .requests import LoginRequest, PostLoginRequest, PulseRequest, SendMsgRequest
from ..commons import BotMessage, Message, AbstractResponse from ..commons import BotMessage, Message, AbstractResponse
import logging
class Interlocutor: class Interlocutor:
@ -42,7 +43,7 @@ class CocoClient:
def __init__(self): def __init__(self):
self.interlocutors = set() # type: Set[Interlocutor] self.interlocutors = set() # type: Set[Interlocutor]
self.current_interlocutor = None # type: Interlocutor self.current_interlocutor = None # type: Interlocutor
self.histories = {} # type:Dict[Interlocutor,List[Tuple]] self.histories = defaultdict(list) # type:defaultdict[Interlocutor,List[Tuple]]
self.user_id = None # type:str self.user_id = None # type:str
self.user_pass = None # type:str self.user_pass = None # type:str
@ -64,7 +65,7 @@ class CocoClient:
self.histories[user].append((user.nick, msg)) self.histories[user].append((user.nick, msg))
logging.info("Msg from %s : %s" % (user.nick, msg)) logging.info("Msg from %s : %s" % (user.nick, msg))
if user == self.current_interlocutor: if self.current_interlocutor is not None and user == self.current_interlocutor:
out.append(Message("💬 %s: %s" % (user.nick, msg))) out.append(Message("💬 %s: %s" % (user.nick, msg)))
else: else:
out.append(BotMessage("💬 %s: %s" % (user.nick, msg))) out.append(BotMessage("💬 %s: %s" % (user.nick, msg)))
@ -72,7 +73,7 @@ class CocoClient:
def connect(self, nick: str, age: int, is_female: bool, zip_code: str): def connect(self, nick: str, age: int, is_female: bool, zip_code: str):
self.nick = nick self.nick = nick
self.histories = {} self.histories = defaultdict(list)
self.current_interlocutor = None self.current_interlocutor = None
login_req = LoginRequest(nick, age, is_female, zip_code) login_req = LoginRequest(nick, age, is_female, zip_code)
self.user_id, self.user_pass = login_req.retrieve() self.user_id, self.user_pass = login_req.retrieve()
@ -88,6 +89,7 @@ class CocoClient:
return self.__process_and_format_received_msg(received_msg) return self.__process_and_format_received_msg(received_msg)
def send_msg(self, msg: str) -> List[AbstractResponse]: def send_msg(self, msg: str) -> List[AbstractResponse]:
if self.current_interlocutor is not None:
sendmsg_req = SendMsgRequest(self.user_id, self.user_pass, self.current_interlocutor.id, msg) sendmsg_req = SendMsgRequest(self.user_id, self.user_pass, self.current_interlocutor.id, msg)
output = sendmsg_req.retrieve() output = sendmsg_req.retrieve()
self.histories[self.current_interlocutor].append((self.nick, msg)) self.histories[self.current_interlocutor].append((self.nick, msg))
@ -97,6 +99,8 @@ class CocoClient:
return [out_msg] + self.__process_and_format_received_msg(output) return [out_msg] + self.__process_and_format_received_msg(output)
else: else:
return [out_msg] return [out_msg]
else:
return [BotMessage("Il faut sélectionner une conversation d'abord pd")]
def switch_conv(self, nick: str=None) -> Union[List[BotMessage], BotMessage]: def switch_conv(self, nick: str=None) -> Union[List[BotMessage], BotMessage]:
new_interlocutor = None new_interlocutor = None

2
tools/coco/tools.py

@ -70,7 +70,7 @@ smilies = [":)", ":(", ";)", ":d", ":-o", ":s", ":$", "*-)", "-)", "^o)", ":p",
"nw$", "ba$", "ao$", "db$", "si$", "oo$", "co$", "bi$", "cc$", "ye$", "mo$", "aa$", "ci$", "uu$", "ff$", "nw$", "ba$", "ao$", "db$", "si$", "oo$", "co$", "bi$", "cc$", "ye$", "mo$", "aa$", "ci$", "uu$", "ff$",
"zz$", "gt$", "ah$", "mm$", "?$", "xx$"] "zz$", "gt$", "ah$", "mm$", "?$", "xx$"]
special_chars = bidict.bidict({" ": "~", "!": "!", "\"": "*8", "$": "*7", "%": "*g", "'": "*8", "(": "(", ")": ")", "*": "*s", "=": "*h", special_chars = bidict.bidict({" ": "~", "!": "!", "$": "*7", "%": "*g", "'": "*8", "(": "(", ")": ")", "*": "*s", "=": "*h",
"?": "=", "@": "*m", "^": "*l", "_": "*0", "": "*d", "à": "*a", "â": "*k", "ç": "*c", "è": "*e", "?": "=", "@": "*m", "^": "*l", "_": "*0", "": "*d", "à": "*a", "â": "*k", "ç": "*c", "è": "*e",
"é": "*r", "ê": "*b", "î": "*i", "ï": "*j", "ô": "*o", "ù": "*f", "û": "*u"}) "é": "*r", "ê": "*b", "î": "*i", "ï": "*j", "ô": "*o", "ù": "*f", "û": "*u"})

5
tools/processors/messages.py

@ -28,7 +28,7 @@ class CommandsDispatcherProcessor(DispatcherBotProcessor):
or text.upper().startswith("/" + trigger) or text.upper().startswith("/" + trigger)
def process(self, text: str, sender_id : str, users_list: UserList): def process(self, text: str, sender_id : str, users_list: UserList):
without_cmd = text[len(users_list.my_name)+1:] without_cmd = text[len(self.trigger)+1:]
response = super().process(without_cmd, sender_id, users_list) response = super().process(without_cmd, sender_id, users_list)
return Message(self.default_response) if response is None else response return Message(self.default_response) if response is None else response
@ -65,7 +65,8 @@ class CocoConnectCommand(BaseCocobotCommand):
if len(zip_code) != 5 or not zip_code.isnumeric(): if len(zip_code) != 5 or not zip_code.isnumeric():
return Message("Le code postal c'est 5 chiffres, pd") return Message("Le code postal c'est 5 chiffres, pd")
return self.cococlient.connect(nick, int(age), True, zip_code) self.cococlient.connect(nick, int(age), True, zip_code)
return BotMessage("Connecté en tant que %s, de %s ans" % (nick, age))
class CocoMsgCommand(BaseCocobotCommand): class CocoMsgCommand(BaseCocobotCommand):

Loading…
Cancel
Save