Skip to content

Commit

Permalink
Add message event
Browse files Browse the repository at this point in the history
  • Loading branch information
Ovizro committed Nov 16, 2023
1 parent bed8225 commit 6ad7ceb
Show file tree
Hide file tree
Showing 11 changed files with 135 additions and 135 deletions.
8 changes: 1 addition & 7 deletions .github/workflows/build_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,7 @@ jobs:
strategy:
matrix:
python-version: [3.8, 3.9, "3.10", "3.11"]
os: [windows-latest, ubuntu-20.04, macos-latest]
# exclude:
# # package dependencies error on macos 3.9+ for unkwown reason
# - os: macos-latest
# python-version: 3.9
# - os: macos-latest
# python-version: "3.10"
os: [windows-latest, ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
timeout-minutes: 30
steps:
Expand Down
124 changes: 21 additions & 103 deletions .github/workflows/python-publish.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# This workflow will upload a Python Package using Twine when a release is created
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries

# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
Expand All @@ -9,114 +9,32 @@
name: Upload Python Package

on:
create:
release:
types: [published]
workflow_dispatch:

permissions:
contents: read

jobs:
deploy-wheels:
name: Deploy wheels on ${{ matrix.os }} for ${{ matrix.arch }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: [36, 37, 38, 39, 310]
manylinux-image: [manylinux2010, manylinux2014, manylinux_2_24]
arch: [auto]
include:
- os: ubuntu-latest
manylinux-image: manylinux2014
arch: aarch64
python-version: 36
- os: ubuntu-latest
manylinux-image: manylinux2014
arch: aarch64
python-version: 37
- os: ubuntu-latest
manylinux-image: manylinux2014
arch: aarch64
python-version: 38
- os: ubuntu-latest
manylinux-image: manylinux2014
arch: aarch64
python-version: 39
- os: ubuntu-latest
manylinux-image: manylinux2014
arch: aarch64
python-version: 310
exclude:
# manyliunx image is not a valid variation on MacOS and Windows
- os: macos-latest
manylinux-image: manylinux2010
- os: windows-latest
manylinux-image: manylinux2010
- os: macos-latest
manylinux-image: manylinux2014
- os: windows-latest
manylinux-image: manylinux2014
deploy:

steps:
- uses: actions/checkout@v2
- name: Set up QEMU
if: ${{ matrix.arch == 'aarch64' }}
uses: docker/setup-qemu-action@v1
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.9
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install twine setuptools wheel
- name: Install cibuildwheel
run: python -m pip install cibuildwheel -U

- name: Build wheels
run: python -m cibuildwheel --output-dir wheelhouse
env:
CIBW_BUILD: 'cp${{ matrix.python-version }}-*'
CIBW_SKIP: '*musllinux*'
CIBW_ARCHS: ${{matrix.arch}}
CIBW_MANYLINUX_*_IMAGE: ${{ matrix.manylinux-image }}
CIBW_MANYLINUX_I686_IMAGE: ${{ matrix.manylinux-image }}

- name: Publish wheels to PyPI Unix
if: matrix.os != 'windows-latest'
continue-on-error: true
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
run: |
twine upload wheelhouse/*.whl
- name: Publish wheels to PyPI Windows
if: matrix.os == 'windows-latest'
continue-on-error: true
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
run: |
twine upload (Get-ChildItem wheelhouse/*.whl)
deploy-tar:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install twine setuptools wheel
- name: Build source tar
run: |
python setup.py sdist
- name: Publish wheels to PyPI
continue-on-error: true
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
run: |
twine upload dist/*tar*
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.8'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install build
- name: Build package
run: python -m build
- name: Publish package
uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
16 changes: 9 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,25 +68,27 @@ Because this is a relatively low-level API, I will only give an example to show

```python
import karuha
from karuha import Bot, DataEvent
from karuha import Bot, MessageEvent, PublishEvent


bot = Bot(
"chatbot",
"basic",
"chatbot:123456"
)


@karuha.on(DataEvent)
async def reply(event: DataEvent) -> None:
if event.server_message.content.decode() == "\"Hello chatbot!\"": # message.content is a json string
await event.bot.publish(
event.server_message.topic,
@karuha.on(MessageEvent)
async def reply(event: MessageEvent) -> None:
if event.text == "Hello!":
PublishEvent.new(
event.bot,
event.topic,
"Hello world!"
)


if __name__ = "__main__":
if __name__ == "__main__":
karuha.load_config()
karuha.add_bot(bot)
karuha.run()
Expand Down
16 changes: 9 additions & 7 deletions README_cn.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,25 +70,27 @@

```python
import karuha
from karuha import Bot, DataEvent
from karuha import Bot, MessageEvent, PublishEvent


bot = Bot(
"chatbot",
"basic",
"chatbot:123456"
)


@karuha.on(DataEvent)
async def reply(event: DataEvent) -> None:
if event.server_message.content.decode() == "\"Hello chatbot!\"": # message.content is a json string
await event.bot.publish(
event.server_message.topic,
@karuha.on(MessageEvent)
async def reply(event: MessageEvent) -> None:
if event.text == "Hello!":
PublishEvent.new(
event.bot,
event.topic,
"Hello world!"
)


if __name__ = "__main__":
if __name__ == "__main__":
karuha.load_config()
karuha.add_bot(bot)
karuha.run()
Expand Down
9 changes: 2 additions & 7 deletions karuha/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
from .config import get_config, load_config, init_config, save_config, Config
from .config import Server as ServerConfig, Bot as BotConfig
from .bot import Bot
from .event import on, BotEvent, DataEvent, CtrlEvent, PresEvent, MetaEvent, InfoEvent
from .event import *
from .text import Drafty, BaseText, PlainText
from .plugin_server import init_server
from .logger import logger
from .exception import KaruhaException
Expand Down Expand Up @@ -103,11 +104,5 @@ def run() -> None:
"ServerConfig",
"Bot",
"on",
"BotEvent",
"DataEvent",
"CtrlEvent",
"PresEvent",
"MetaEvent",
"InfoEvent",
"KaruhaException"
]
6 changes: 5 additions & 1 deletion karuha/event/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from .base import Event
from .bot import BotEvent, ClientEvent, PublishEvent, SubscribeEvent, LeaveEvent, ServerEvent, DataEvent, CtrlEvent, MetaEvent, PresEvent, InfoEvent
from .message import MessageEvent
from . import handler


Expand All @@ -16,6 +17,7 @@ def wrapper(func: Callable[[T_Event], Any]) -> Callable[[T_Event], Any]:


__all__ = [
"on",
"Event",
"BotEvent",

Expand All @@ -29,5 +31,7 @@ def wrapper(func: Callable[[T_Event], Any]) -> Callable[[T_Event], Any]:
"CtrlEvent",
"MetaEvent",
"PresEvent",
"InfoEvent"
"InfoEvent",

"MessageEvent"
]
13 changes: 12 additions & 1 deletion karuha/event/base.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import asyncio
from typing import Any, Callable, ClassVar, Coroutine, List
from typing_extensions import Self
from typing_extensions import Self, ParamSpec

from ..logger import logger


P = ParamSpec("P")


class Event(object):
__slots__ = []

Expand All @@ -18,6 +21,14 @@ def add_handler(cls, handler: Callable[[Self], Coroutine]) -> None:
def remove_handler(cls, handler: Callable[[Self], Coroutine]) -> None:
cls.__handlers__.remove(handler)

@classmethod # type: ignore
def new(cls: Callable[P, Self], *args: P.args, **kwds: P.kwargs) -> Self: # type: ignore
event = cls(
*args, **kwds
)
event.trigger()
return event

def call_handler(self, handler: Callable[[Self], Coroutine]) -> None:
asyncio.create_task(handler(self))

Expand Down
12 changes: 11 additions & 1 deletion karuha/event/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,25 @@

from ..text import BaseText
from .bot import DataEvent, CtrlEvent, PresEvent, PublishEvent, SubscribeEvent, LeaveEvent
from .message import MessageEvent


@DataEvent.add_handler
async def _(event: DataEvent) -> None:
msg = event.server_message
event.bot.logger.info(f"({msg.topic})=> {msg.content.decode()}")
await event.bot.note_read(msg.topic, msg.seq_id)


@DataEvent.add_handler
async def _(event: DataEvent) -> None:
MessageEvent.from_data_event(event).trigger()


@MessageEvent.add_handler
async def _(event: MessageEvent) -> None:
event.bot.logger.info(f"({event.topic})=> {event.text}")


@CtrlEvent.add_handler
async def _(event: CtrlEvent) -> None:
tid = event.server_message.id
Expand Down
59 changes: 59 additions & 0 deletions karuha/event/message.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import json
from typing import Dict
from typing_extensions import Self

from ..bot import Bot
from ..text import Drafty, PlainText, drafty2text
from .bot import BotEvent, DataEvent


class MessageEvent(BotEvent):
__slots__ = ["topic", "uid", "seq_id", "head", "raw_content", "raw_text", "text"]

def __init__(self, bot: Bot, /, topic: str, uid: str, seq_id: int, head: Dict[str, str], content: bytes) -> None:
super().__init__(bot)
self.topic = topic
self.uid = uid
self.seq_id = seq_id
self.head = head
self._set_text(content)

@classmethod
def from_data_event(cls, event: DataEvent, /) -> Self:
message = event.server_message
return cls(
event.bot,
message.topic,
message.from_user_id,
message.seq_id,
{k: json.loads(v) for k, v in message.head},
message.content
)

def _set_text(self, content: bytes, /) -> None:
self.raw_content = content

try:
raw_text = json.loads(content)
except json.JSONDecodeError:
raw_text = content.decode()
topic = self.topic
seq_id = self.seq_id
self.bot.logger.error(f"cannot decode text {raw_text} ({topic=},{seq_id=})")

if not isinstance(raw_text, str):
try:
self.raw_text = Drafty.model_validate(raw_text)
except Exception:
self.bot.logger.error(f"unknown text format {raw_text}")
raw_text = str(raw_text)
else:
try:
self.text = drafty2text(self.raw_text)
except Exception:
self.bot.logger.error(f"cannot decode drafty {self.raw_text}")
self.text = self.raw_text.txt
return

self.raw_text = raw_text
self.text = PlainText(raw_text)
Loading

0 comments on commit 6ad7ceb

Please sign in to comment.