refactor pygomx-module -> pygomx
This commit is contained in:
parent
e1dfbe218d
commit
23fc397384
11 changed files with 181 additions and 34 deletions
|
|
@ -4,40 +4,32 @@ ARG GOLANG_VERSION=1.24
|
|||
ARG DEBIAN_VERSION=trixie
|
||||
ARG PYTHON_VERSION=3.14
|
||||
|
||||
FROM docker.io/library/golang:${GOLANG_VERSION}-${DEBIAN_VERSION} AS gobuilder
|
||||
|
||||
RUN apt update
|
||||
RUN apt -y install libolm-dev
|
||||
|
||||
RUN --mount=type=bind,source=./libmxclient/go.mod,target=/libmxclient/build/go.mod --mount=type=bind,source=./libmxclient/go.sum,target=/libmxclient/build/go.sum <<EOF
|
||||
cd /libmxclient/build
|
||||
go mod download
|
||||
EOF
|
||||
|
||||
RUN --mount=type=bind,source=./libmxclient,target=/libmxclient/build <<EOF
|
||||
# building go lib
|
||||
set -e
|
||||
cd /libmxclient/build
|
||||
CGO_ENABLED=1 GOARCH=${GOARCH} go build -buildmode=c-shared -o /pygomx-build/libmxclient.so .
|
||||
EOF
|
||||
|
||||
FROM docker.io/library/python:${PYTHON_VERSION}-${DEBIAN_VERSION} AS pybuilder
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
ENV PIP_ROOT_USER_ACTION=ignore
|
||||
|
||||
COPY --from=gobuilder /pygomx-build/libmxclient.so /usr/local/lib/libmxclient.so
|
||||
COPY --from=gobuilder /pygomx-build/libmxclient.h /usr/local/include/libmxclient.h
|
||||
RUN <<EOF
|
||||
# install packages
|
||||
set -eu
|
||||
apt update
|
||||
apt -y upgrade
|
||||
apt -y install golang libolm-dev
|
||||
EOF
|
||||
|
||||
RUN pip install cffi setuptools
|
||||
RUN pip install cffi setuptools build
|
||||
|
||||
COPY pygomx-module /pygomx
|
||||
#RUN --mount=type=bind,source=.,target=/pygomx <<EOF
|
||||
COPY libmxclient /pygomx/libmxclient
|
||||
COPY pygomx /pygomx/pygomx
|
||||
|
||||
RUN <<EOF
|
||||
# build py module
|
||||
set -e
|
||||
cd /pygomx
|
||||
PYGOMX_BUILD_MODE=shared python3 build_ffi.py
|
||||
ls -la *.so
|
||||
set -eu
|
||||
cd /pygomx/pygomx
|
||||
python3 -m build --verbose --wheel --outdir /pygomx-wheel
|
||||
|
||||
ls -la /pygomx-wheel
|
||||
EOF
|
||||
|
||||
FROM docker.io/library/python:${PYTHON_VERSION}-slim-${DEBIAN_VERSION} AS develop
|
||||
|
|
@ -54,9 +46,7 @@ apt -y install libolm3
|
|||
rm -rf /var/lib/apt/lists/*
|
||||
EOF
|
||||
|
||||
COPY --from=gobuilder /pygomx-build/libmxclient.so /usr/local/lib/
|
||||
COPY --from=pybuilder /pygomx/_pygomx.cpython-314-x86_64-linux-gnu.so /usr/local/lib/python3.14/site-packages/
|
||||
RUN ldconfig
|
||||
RUN --mount=type=bind,from=pybuilder,source=/pygomx-wheel,target=/pygomx-wheel pip install /pygomx-wheel/*.whl
|
||||
|
||||
FROM develop AS demobot
|
||||
WORKDIR /smal
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
monorepos to have the right versions together
|
||||
|
||||
libmxclient - golang matrix client library
|
||||
pygomx-module - python binding package
|
||||
pygomx - python binding package
|
||||
smal - python matrix lib
|
||||
|
||||
|
||||
|
|
@ -20,7 +20,7 @@ the bot follows each invite (autojoin) and have two commands:
|
|||
binary/package install:
|
||||
|
||||
(only linux-amd64 for now)
|
||||
pip install --index-url https://codeberg.org/api/packages/saces/pypi/simple/ --no-deps pygomx-module
|
||||
pip install --index-url https://codeberg.org/api/packages/saces/pypi/simple/ --no-deps pygomx
|
||||
pip install git+https://codeberg.org/saces/pygomx.git#subdirectory=smal
|
||||
|
||||
|
||||
|
|
@ -40,7 +40,7 @@ install from source / develop (venv):
|
|||
|
||||
(create and activate a venv)
|
||||
|
||||
cd pygomx-module
|
||||
cd pygomx
|
||||
pip install .
|
||||
|
||||
cd ../smal
|
||||
|
|
|
|||
0
pygomx-module/.gitignore → pygomx/.gitignore
vendored
0
pygomx-module/.gitignore → pygomx/.gitignore
vendored
|
|
@ -1,5 +1,5 @@
|
|||
pygomx-module
|
||||
=============
|
||||
pygomx
|
||||
======
|
||||
|
||||
python package with the pygomx binaries
|
||||
|
||||
|
|
@ -3,7 +3,7 @@ requires = ["setuptools>=80", "cffi>=2.0.0"]
|
|||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "pygomx-module"
|
||||
name = "pygomx"
|
||||
version = "0.0.1"
|
||||
requires-python = ">=3.10"
|
||||
description = "python pindings for a golang matrix library"
|
||||
|
|
@ -15,3 +15,6 @@ dependencies = ["cffi>=2.0.0"]
|
|||
[project.urls]
|
||||
homepage = "https://codeberg.org/saces/pygomx"
|
||||
heimseite = "https://code.c-base.org/saces/pygomx"
|
||||
|
||||
[tool.setuptools.package-dir]
|
||||
"pygomx" = "src/pygomx"
|
||||
|
|
@ -51,7 +51,7 @@ class CustomCommand(Command):
|
|||
"-tags",
|
||||
",".join(go_tags),
|
||||
"-o",
|
||||
f"../pygomx-module/libmxclient{build_mode_ext}",
|
||||
f"../pygomx/libmxclient{build_mode_ext}",
|
||||
".",
|
||||
]
|
||||
subprocess.call(go_call, cwd="../libmxclient")
|
||||
0
pygomx/src/pygomx/__init__.py
Normal file
0
pygomx/src/pygomx/__init__.py
Normal file
13
pygomx/src/pygomx/errors.py
Normal file
13
pygomx/src/pygomx/errors.py
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
class APIError(Exception):
|
||||
"""Exception raised for api usage errors.
|
||||
|
||||
Attributes:
|
||||
message -- explanation of the error
|
||||
"""
|
||||
|
||||
def __init__(self, message):
|
||||
self.message = message[4:]
|
||||
super().__init__(self.message)
|
||||
141
pygomx/src/pygomx/pygomx.py
Normal file
141
pygomx/src/pygomx/pygomx.py
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import logging
|
||||
from _pygomx import lib, ffi
|
||||
import json
|
||||
from .errors import APIError
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def checkApiError(cstr):
|
||||
result = ffi.string(cstr).decode("utf-8")
|
||||
lib.FreeCString(cstr)
|
||||
|
||||
if result.startswith("ERR:"):
|
||||
raise APIError(result)
|
||||
|
||||
if result == "SUCCESS.":
|
||||
return
|
||||
|
||||
logger.debug(result)
|
||||
|
||||
result_dict = json.loads(result)
|
||||
return result_dict
|
||||
|
||||
|
||||
class _MXClient:
|
||||
"""
|
||||
core binding
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._createMXClient()
|
||||
# create a c-handle for self and keep it alive
|
||||
self._ffi_selfhandle = ffi.new_handle(self)
|
||||
|
||||
r = lib.apiv0_set_on_event_handler(
|
||||
self.client_id, on_event_callback, self._ffi_selfhandle
|
||||
)
|
||||
result = ffi.string(r)
|
||||
lib.FreeCString(r)
|
||||
if result.startswith(b"ERR:"):
|
||||
raise APIError(result)
|
||||
|
||||
r = lib.apiv0_set_on_message_handler(
|
||||
self.client_id, on_message_callback, self._ffi_selfhandle
|
||||
)
|
||||
result = ffi.string(r)
|
||||
lib.FreeCString(r)
|
||||
if result.startswith(b"ERR:"):
|
||||
raise APIError(result)
|
||||
|
||||
r = lib.apiv0_set_on_sys_handler(
|
||||
self.client_id, on_sys_callback, self._ffi_selfhandle
|
||||
)
|
||||
result = ffi.string(r)
|
||||
lib.FreeCString(r)
|
||||
if result.startswith(b"ERR:"):
|
||||
raise APIError(result)
|
||||
|
||||
def _createMXClient(self):
|
||||
r = lib.apiv0_createclient_pass(b".mxpass", b".", b"*", b"*", b"*")
|
||||
|
||||
result = ffi.string(r)
|
||||
lib.FreeCString(r)
|
||||
if result.startswith(b"ERR:"):
|
||||
raise APIError(result)
|
||||
|
||||
result_dict = json.loads(result)
|
||||
self.client_id = result_dict["id"]
|
||||
self.UserID = result_dict["userid"]
|
||||
self.DeviceID = result_dict["deviceid"]
|
||||
|
||||
def _sync(self):
|
||||
r = lib.apiv0_startclient(self.client_id)
|
||||
checkApiError(r)
|
||||
|
||||
def _stopsync(self):
|
||||
r = lib.apiv0_stopclient(self.client_id)
|
||||
checkApiError(r)
|
||||
|
||||
def _sendmessage(self, data_dict):
|
||||
data = json.dumps(data_dict).encode(encoding="utf-8")
|
||||
r = lib.apiv0_sendmessage(self.client_id, data)
|
||||
result = checkApiError(r)
|
||||
return result
|
||||
|
||||
def leaveroom(self, roomid):
|
||||
r = lib.apiv0_leaveroom(self.client_id, roomid.encode(encoding="utf-8"))
|
||||
checkApiError(r)
|
||||
|
||||
def joinedrooms(self):
|
||||
r = lib.apiv0_joinedrooms(self.client_id)
|
||||
return checkApiError(r)
|
||||
|
||||
def _createroom(self, data_dict):
|
||||
data = json.dumps(data_dict).encode(encoding="utf-8")
|
||||
r = lib.apiv0_createroom(self.client_id, data)
|
||||
return checkApiError(r)
|
||||
|
||||
def process_event(self, evt):
|
||||
if hasattr(self, "on_event") and callable(self.on_event):
|
||||
self.on_event(evt)
|
||||
else:
|
||||
logger.warn(f"got event but on_event not declared: {evt}")
|
||||
|
||||
def process_message(self, msg):
|
||||
if hasattr(self, "on_message") and callable(self.on_message):
|
||||
self.on_message(msg)
|
||||
else:
|
||||
logger.warn(f"got message but on_message not declared: {msg}")
|
||||
|
||||
def process_sys(self, ntf):
|
||||
if hasattr(self, "on_sys") and callable(self.on_sys):
|
||||
self.on_sys(ntf)
|
||||
else:
|
||||
logger.warn(f"got systen notification but on_sys not declared: {ntf}")
|
||||
|
||||
|
||||
@ffi.callback("void(char*, void*)")
|
||||
def on_event_callback(evt, pobj):
|
||||
cli = ffi.from_handle(pobj)
|
||||
e = ffi.string(evt).decode("utf-8")
|
||||
evt = json.loads(e)
|
||||
cli.process_event(evt)
|
||||
|
||||
|
||||
@ffi.callback("void(char*, void*)")
|
||||
def on_message_callback(msg, pobj):
|
||||
cli = ffi.from_handle(pobj)
|
||||
m = ffi.string(msg).decode("utf-8")
|
||||
msg = json.loads(m)
|
||||
cli.process_message(msg)
|
||||
|
||||
|
||||
@ffi.callback("void(char*, void*)")
|
||||
def on_sys_callback(msg, pobj):
|
||||
cli = ffi.from_handle(pobj)
|
||||
m = ffi.string(msg).decode("utf-8")
|
||||
sys = json.loads(m)
|
||||
cli.process_sys(sys)
|
||||
Loading…
Add table
Add a link
Reference in a new issue