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 DEBIAN_VERSION=trixie
|
||||||
ARG PYTHON_VERSION=3.14
|
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
|
FROM docker.io/library/python:${PYTHON_VERSION}-${DEBIAN_VERSION} AS pybuilder
|
||||||
ENV PYTHONUNBUFFERED=1
|
ENV PYTHONUNBUFFERED=1
|
||||||
ENV PIP_ROOT_USER_ACTION=ignore
|
ENV PIP_ROOT_USER_ACTION=ignore
|
||||||
|
|
||||||
COPY --from=gobuilder /pygomx-build/libmxclient.so /usr/local/lib/libmxclient.so
|
RUN <<EOF
|
||||||
COPY --from=gobuilder /pygomx-build/libmxclient.h /usr/local/include/libmxclient.h
|
# 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
|
RUN <<EOF
|
||||||
# build py module
|
# build py module
|
||||||
set -e
|
set -eu
|
||||||
cd /pygomx
|
cd /pygomx/pygomx
|
||||||
PYGOMX_BUILD_MODE=shared python3 build_ffi.py
|
python3 -m build --verbose --wheel --outdir /pygomx-wheel
|
||||||
ls -la *.so
|
|
||||||
|
ls -la /pygomx-wheel
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
FROM docker.io/library/python:${PYTHON_VERSION}-slim-${DEBIAN_VERSION} AS develop
|
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/*
|
rm -rf /var/lib/apt/lists/*
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
COPY --from=gobuilder /pygomx-build/libmxclient.so /usr/local/lib/
|
RUN --mount=type=bind,from=pybuilder,source=/pygomx-wheel,target=/pygomx-wheel pip install /pygomx-wheel/*.whl
|
||||||
COPY --from=pybuilder /pygomx/_pygomx.cpython-314-x86_64-linux-gnu.so /usr/local/lib/python3.14/site-packages/
|
|
||||||
RUN ldconfig
|
|
||||||
|
|
||||||
FROM develop AS demobot
|
FROM develop AS demobot
|
||||||
WORKDIR /smal
|
WORKDIR /smal
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
monorepos to have the right versions together
|
monorepos to have the right versions together
|
||||||
|
|
||||||
libmxclient - golang matrix client library
|
libmxclient - golang matrix client library
|
||||||
pygomx-module - python binding package
|
pygomx - python binding package
|
||||||
smal - python matrix lib
|
smal - python matrix lib
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -20,7 +20,7 @@ the bot follows each invite (autojoin) and have two commands:
|
||||||
binary/package install:
|
binary/package install:
|
||||||
|
|
||||||
(only linux-amd64 for now)
|
(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
|
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)
|
(create and activate a venv)
|
||||||
|
|
||||||
cd pygomx-module
|
cd pygomx
|
||||||
pip install .
|
pip install .
|
||||||
|
|
||||||
cd ../smal
|
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
|
python package with the pygomx binaries
|
||||||
|
|
||||||
|
|
@ -3,7 +3,7 @@ requires = ["setuptools>=80", "cffi>=2.0.0"]
|
||||||
build-backend = "setuptools.build_meta"
|
build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "pygomx-module"
|
name = "pygomx"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
requires-python = ">=3.10"
|
requires-python = ">=3.10"
|
||||||
description = "python pindings for a golang matrix library"
|
description = "python pindings for a golang matrix library"
|
||||||
|
|
@ -15,3 +15,6 @@ dependencies = ["cffi>=2.0.0"]
|
||||||
[project.urls]
|
[project.urls]
|
||||||
homepage = "https://codeberg.org/saces/pygomx"
|
homepage = "https://codeberg.org/saces/pygomx"
|
||||||
heimseite = "https://code.c-base.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",
|
"-tags",
|
||||||
",".join(go_tags),
|
",".join(go_tags),
|
||||||
"-o",
|
"-o",
|
||||||
f"../pygomx-module/libmxclient{build_mode_ext}",
|
f"../pygomx/libmxclient{build_mode_ext}",
|
||||||
".",
|
".",
|
||||||
]
|
]
|
||||||
subprocess.call(go_call, cwd="../libmxclient")
|
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