merge bookmark @

This commit is contained in:
Goffi 2021-09-08 11:20:37 +02:00
commit 50d7cb2a51
29 changed files with 277 additions and 150 deletions

View file

@ -1,8 +1,8 @@
.. _contribuing:
.. _contributing:
===========
contribuing
===========
============
contributing
============
This part of the documentation is for people willing to contribute to the development of
Libervia and its ecosystem, it is not needed to read this if you only plan to use the

View file

@ -28,7 +28,7 @@ end-to-end tests
================
End-to-end tests are located in ``tests/e2e``. They are launched in a well defined
environment managed through Docker. The ``docker/docker-compose_e2e.yml`` is used to
environment managed through Docker. The ``docker/docker-compose-e2e.yml`` is used to
create the suitable containers.
A script is available at ``tests/e2e/run_e2e.py`` to launch the tests. It will create the
@ -68,7 +68,7 @@ In addition to pytest option, some flags can be set with the following arguments
To log-in into the ``backend`` container, you can use the following command, from
``/docker`` directory::
$ docker-compose -f docker-compose_e2e.yml exec backend /bin/bash
$ docker-compose -f docker-compose-e2e.yml exec backend /bin/bash
Then run a python console with given instructions
@ -224,7 +224,7 @@ test to be sure to have test profiles created and fake SMTP server run…::
…then to go into the ``backend`` container and work with the browser (to be run in ``docker``
directory)…::
$ docker-compose -f docker-compose_e2e.yml exec backend /bin/bash
$ docker-compose -f docker-compose-e2e.yml exec backend /bin/bash
…and, inside the container, you can now run ``python3`` and enter instruction prints at
the end of the test session.

View file

@ -29,7 +29,7 @@ You can follow this documentation to learn more on it, or join our official XMPP
developer.rst
/libervia-cli/index.rst
/libervia-tui/index.rst
/contribuing/index.rst
/contributing/index.rst
Indices and tables

View file

@ -1,4 +1,5 @@
FROM libervia/backend:dev
ARG REVISION=dev
FROM libervia/backend:${REVISION}
LABEL maintainer="Goffi <tmp_dockerfiles@goffi.org>"
@ -46,7 +47,7 @@ USER libervia
RUN \
# pytest and its plugins
pip install pytest pytest-timeout pytest-dependency \
# needed to test jp
# needed to test libervia-cli
sh \
# needed to test libervia
helium \
@ -57,7 +58,7 @@ RUN \
RUN ./entrypoint.sh \
# we create the file sharing component which will autoconnect when backend is started
jp profile create file_sharing -j files.server1.test -p "" --xmpp-password test_e2e -C file_sharing -A && \
li profile create file_sharing -j files.server1.test -p "" --xmpp-password test_e2e -C file_sharing -A && \
libervia-backend stop
ENV LIBERVIA_TEST_REPORT_DIR=/reports

View file

@ -1,13 +1,15 @@
FROM debian:buster-slim
FROM debian:bullseye-slim
LABEL maintainer="Goffi <tmp_dockerfiles@goffi.org>"
ARG REVISION
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get upgrade -y && \
RUN echo "Building image for Libervia ${REVISION:-dev}" && \
apt-get update && apt-get upgrade -y && \
apt-get install -y --no-install-recommends locales python3-dev python3-venv python3-wheel mercurial libxml2-dev libxslt-dev libcairo2-dev libjpeg-dev libgirepository1.0-dev libdbus-1-dev libdbus-glib-1-dev dbus-x11 cmake && \
\
# will be used to put many SàT specific data
# will be used to put many Libervia specific data
mkdir -p /usr/share/libervia/certificates && \
addgroup tls-cert --gid 9999 && \
chown :tls-cert /usr/share/libervia/certificates && \
@ -18,12 +20,12 @@ RUN apt-get update && apt-get upgrade -y && \
mkdir /src && chown libervia:libervia /src && \
\
# we need UTF-8 locale
sed -i "s/# en_US.UTF-8/en_US.UTF-8/" /etc/locale.gen && locale-gen && \
\
# we need a TCP socket for D-Bus
sed -i "s&<listen>unix:tmpdir=/tmp</listen>&\0\n <listen>tcp:host=localhost,bind=*,port=55555,family=ipv4</listen>\n <auth>ANONYMOUS</auth>\n <allow_anonymous/>&" /usr/share/dbus-1/session.conf
sed -i "s/# en_US.UTF-8/en_US.UTF-8/" /etc/locale.gen && locale-gen
ENV LC_ALL en_US.UTF-8
ENV DOCKER_LIBERVIA_REV=${REVISION:-dev}
COPY --chown=root:root session.conf /usr/share/dbus-1/session.conf
WORKDIR /home/libervia
USER libervia
@ -34,15 +36,16 @@ RUN python3 -m venv libervia_env && libervia_env/bin/pip install -U pip wheel &&
# local repos without it them cause troubles
hg clone https://repos.goffi.org/urwid-satext && ~/libervia_env/bin/pip install -e urwid-satext && \
mv urwid-satext/urwid_satext.egg-info ~/libervia_env/lib/python3.*/site-packages && \
hg clone https://repos.goffi.org/sat_tmp && ~/libervia_env/bin/pip install -e sat_tmp && \
hg clone https://repos.goffi.org/sat_tmp -u "${REVISION:-tip}" && ~/libervia_env/bin/pip install -e sat_tmp && \
mv sat_tmp/sat_tmp.egg-info ~/libervia_env/lib/python3.*/site-packages && \
hg clone https://repos.goffi.org/sat_templates && ~/libervia_env/bin/pip install -e sat_templates && \
mv sat_templates/libervia_templates.egg-info ~/libervia_env/lib/python3.*/site-packages && \
hg clone https://repos.goffi.org/sat_media && \
hg clone https://repos.goffi.org/sat && ~/libervia_env/bin/pip install -e 'sat[SVG]' && \
mv sat/libervia_backend.egg-info ~/libervia_env/lib/python3.*/site-packages
hg clone https://repos.goffi.org/libervia-templates && ~/libervia_env/bin/pip install -e libervia-templates && \
mv libervia-templates/libervia_templates.egg-info ~/libervia_env/lib/python3.*/site-packages && \
hg clone https://repos.goffi.org/libervia-media && \
hg clone https://repos.goffi.org/libervia-backend -u "${REVISION:-tip}" && ~/libervia_env/bin/pip install -e 'libervia-backend[SVG]' && \
mv libervia-backend/libervia_backend.egg-info ~/libervia_env/lib/python3.*/site-packages && \
mkdir -p /home/libervia/.local/share/libervia
ENV DBUS_SESSION_BUS_ADDRESS=tcp:host=backend,port=55555,family=ipv4
ENV DBUS_SESSION_BUS_ADDRESS="tcp:host=backend,port=55555,family=ipv4;unix:path=/home/libervia/.local/share/libervia/dbus_socket"
ENV PATH=/home/libervia/libervia_env/bin:$PATH
COPY --chown=root:root libervia.conf /etc/_libervia.conf

View file

@ -1,5 +1,5 @@
[DEFAULT]
media_dir = /src/sat_media
media_dir = /src/libervia-media
[cli]
# FIXME: default "auto" value cause trouble

View file

@ -0,0 +1,32 @@
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<type>session</type>
<keep_umask/>
<listen>unix:path=/home/libervia/.local/share/libervia/dbus_socket</listen>
<listen>tcp:host=localhost,bind=*,port=55555,family=ipv4</listen>
<auth>ANONYMOUS</auth>
<allow_anonymous/>
<standard_session_servicedirs />
<policy context="default">
<allow send_destination="*" eavesdrop="true"/>
<allow eavesdrop="true"/>
<allow own="*"/>
</policy>
<include if_selinux_enabled="yes" selinux_root_relative="yes">contexts/dbus_contexts</include>
<limit name="max_incoming_bytes">1000000000</limit>
<limit name="max_incoming_unix_fds">250000000</limit>
<limit name="max_outgoing_bytes">1000000000</limit>
<limit name="max_outgoing_unix_fds">250000000</limit>
<limit name="max_message_size">1000000000</limit>
<limit name="service_start_timeout">120000</limit>
<limit name="auth_timeout">240000</limit>
<limit name="pending_fd_timeout">150000</limit>
<limit name="max_completed_connections">100000</limit>
<limit name="max_incomplete_connections">10000</limit>
<limit name="max_connections_per_user">100000</limit>
<limit name="max_pending_service_starts">10000</limit>
<limit name="max_names_per_connection">50000</limit>
<limit name="max_match_rules_per_connection">50000</limit>
<limit name="max_replies_per_connection">50000</limit>
</busconfig>

View file

@ -38,8 +38,11 @@ services:
LIBERVIA_PUBSUB_XMPP_PWD: test_e2e
backend:
image: libervia/backend:dev-e2e
build: backend-dev-e2e
image: libervia/backend:${DOCKER_LIBERVIA_REV:-dev}-e2e
build:
context: backend-dev-e2e
args:
REVISION: ${DOCKER_LIBERVIA_REV:-}
environment:
LIBERVIA_TEST_ENV_E2E: "1"
LIBERVIA_TEST_ENV_E2E_WEB: "1"
@ -54,8 +57,11 @@ services:
- libervia-backend.test
web:
image: libervia/web:dev-e2e
build: libervia-web-dev-e2e
image: libervia/web:${DOCKER_LIBERVIA_REV:-dev}-e2e
build:
context: libervia-web-dev-e2e
args:
REVISION: ${DOCKER_LIBERVIA_REV:-}
depends_on:
- backend
environment:

View file

@ -2,11 +2,17 @@ version: "3.6"
services:
backend:
image: libervia/backend:dev
build: backend-dev
image: "libervia/backend:${DOCKER_LIBERVIA_REV:-dev}"
build:
context: backend-dev
args:
REVISION: "${DOCKER_LIBERVIA_REV:-}"
web:
image: libervia/web:dev
build: libervia-web-dev
image: "libervia/web:${DOCKER_LIBERVIA_REV:-dev}"
build:
context: libervia-web-dev
args:
REVISION: "${DOCKER_LIBERVIA_REV:-}"
depends_on:
- backend

View file

@ -1,4 +1,5 @@
FROM libervia/web:dev
ARG REVISION=dev
FROM libervia/web:${REVISION}
LABEL maintainer="Goffi <tmp_dockerfiles@goffi.org>"

View file

@ -1,4 +1,5 @@
FROM libervia/web:dev
ARG REVISION=dev
FROM libervia/web:${REVISION}
LABEL maintainer="Goffi <tmp_dockerfiles@goffi.org>"

View file

@ -1,7 +1,9 @@
FROM libervia/backend:dev
ARG REVISION
FROM libervia/backend:${REVISION:-dev}
LABEL maintainer="Goffi <tmp_dockerfiles@goffi.org>"
ARG REVISION
ARG DEBIAN_FRONTEND=noninteractive
USER root
@ -9,9 +11,9 @@ USER root
RUN apt-get install -y --no-install-recommends yarnpkg
WORKDIR /home/libervia
USER libervia
RUN cd /src && hg clone https://repos.goffi.org/libervia && \
~/libervia_env/bin/pip install -e libervia && \
mv libervia/libervia_web.egg-info ~/libervia_env/lib/python3.*/site-packages
RUN cd /src && hg clone https://repos.goffi.org/libervia-web -u "${REVISION:-tip}" && \
~/libervia_env/bin/pip install -e libervia-web && \
mv libervia-web/libervia_web.egg-info ~/libervia_env/lib/python3.*/site-packages
RUN ./entrypoint.sh \
# we build here to avoid re-downloading node modules or other browser

View file

@ -1,4 +1,4 @@
FROM debian:buster-slim
FROM debian:bullseye-slim
LABEL maintainer="Goffi <tmp_dockerfiles@goffi.org>"
@ -29,6 +29,6 @@ RUN python3 -m venv libervia_env && libervia_env/bin/pip install -U pip wheel &&
hg clone https://repos.goffi.org/sat_tmp && ~/libervia_env/bin/pip install -e sat_tmp && \
mv sat_tmp/sat_tmp.egg-info ~/libervia_env/lib/python3.*/site-packages && \
hg clone https://repos.goffi.org/sat_pubsub && ~/libervia_env/bin/pip install -e sat_pubsub && \
mv sat_pubsub/libervia_pubsub.egg-info ~/libervia_env/lib/python3.*/site-packages
mv sat_pubsub/sat_pubsub.egg-info ~/libervia_env/lib/python3.*/site-packages
ENTRYPOINT ["/home/libervia/entrypoint.sh"]

View file

@ -140,7 +140,21 @@ class Bridge:
kwargs['reply_handler'] = _callback
kwargs['error_handler'] = lambda err: _errback(dbus_to_bridge_exception(err))
return method(*args, **kwargs)
try:
return method(*args, **kwargs)
except ValueError as e:
if e.args[0].startswith("Unable to guess signature"):
# XXX: if frontend is started too soon after backend, the
# inspection misses methods (notably plugin dynamically added
# methods). The following hack works around that by redoing the
# cache of introspected methods signatures.
log.debug("using hack to work around inspection issue")
proxy = self.db_plugin_iface.proxy_object
IN_PROGRESS = proxy.INTROSPECT_STATE_INTROSPECT_IN_PROGRESS
proxy._introspect_state = IN_PROGRESS
proxy._Introspect()
return self.db_plugin_iface.get_dbus_method(name)(*args, **kwargs)
raise e
return getPluginMethod
@ -167,13 +181,32 @@ class AIOBridge(Bridge):
fut.set_result, ret)
error_handler = lambda err: loop.call_soon_threadsafe(
fut.set_exception, dbus_to_bridge_exception(err))
method(
*args,
**kwargs,
timeout=const_TIMEOUT,
reply_handler=reply_handler,
error_handler=error_handler
)
try:
method(
*args,
**kwargs,
timeout=const_TIMEOUT,
reply_handler=reply_handler,
error_handler=error_handler
)
except ValueError as e:
if e.args[0].startswith("Unable to guess signature"):
# same hack as for Bridge.__getattribute__
log.warning("using hack to work around inspection issue")
proxy = self.db_plugin_iface.proxy_object
IN_PROGRESS = proxy.INTROSPECT_STATE_INTROSPECT_IN_PROGRESS
proxy._introspect_state = IN_PROGRESS
proxy._Introspect()
self.db_plugin_iface.get_dbus_method(name)(
*args,
**kwargs,
timeout=const_TIMEOUT,
reply_handler=reply_handler,
error_handler=error_handler
)
else:
raise e
return fut
return getPluginMethod

View file

@ -228,11 +228,7 @@ class SAT(service.Service):
ui_contact_list.ContactList(self)
ui_profile_manager.ProfileManager(self)
except Exception as e:
log.error(
_("Could not initialize backend: {reason}").format(
reason=str(e).decode("utf-8", "ignore")
)
)
log.error(f"Could not initialize backend: {e}")
sys.exit(1)
self._addBaseMenus()
@ -344,6 +340,12 @@ class SAT(service.Service):
plugin_modes = plugin_info["modes"] = set(
plugin_info.setdefault("modes", C.PLUG_MODE_DEFAULT)
)
if not plugin_modes.intersection(C.PLUG_MODE_BOTH):
log.error(
f"Can't import plugin at {plugin_path}, invalid {C.PI_MODES!r} "
f"value: {plugin_modes!r}"
)
continue
# if the plugin is an entry point, it must work in component mode
if plugin_info["type"] == C.PLUG_TYPE_ENTRY_POINT:

View file

@ -204,7 +204,7 @@ class LazyPersistentBinaryDict(PersistentBinaryDict):
))
def __repr__(self):
raise NotImplementedError
return self.__str__()
def __str__(self):
return "LazyPersistentBinaryDict (namespace: {})".format(self.namespace)

View file

@ -309,9 +309,11 @@ class AndroidPlugin(object):
# "XXX has no attribute 'invoke'" error (looks like the same issue as
# https://github.com/kivy/pyjnius/issues/59)
self.br = BroadcastReceiver(
callback=lambda *args, **kwargs: reactor.callLater(0,
self.onConnectivityChange),
actions=["android.net.conn.CONNECTIVITY_CHANGE"])
callback=lambda *args, **kwargs: reactor.callFromThread(
self.onConnectivityChange
),
actions=["android.net.conn.CONNECTIVITY_CHANGE"]
)
self.br.start()
@property

View file

@ -237,8 +237,8 @@ class FilePlugin:
data_cb=file_data.get("data_cb"),
)
def _gotConfirmation(
self, data, client, peer_jid, transfer_data, file_data, stream_object
async def _gotConfirmation(
self, client, data, peer_jid, transfer_data, file_data, stream_object
):
"""Called when the permission and dest path have been received
@ -258,19 +258,7 @@ class FilePlugin:
# we manage case where file already exists
if os.path.exists(file_path):
def check_overwrite(overwrite):
if overwrite:
self.openFileWrite(
client, file_path, transfer_data, file_data, stream_object
)
return True
else:
return defer.ensureDeferred(
self.getDestDir(client, peer_jid, transfer_data, file_data)
)
exists_d = xml_tools.deferConfirm(
overwrite = await xml_tools.deferConfirm(
self.host,
_(CONFIRM_OVERWRITE).format(file_path),
_(CONFIRM_OVERWRITE_TITLE),
@ -282,8 +270,9 @@ class FilePlugin:
security_limit=SECURITY_LIMIT,
profile=client.profile,
)
exists_d.addCallback(check_overwrite)
return exists_d
if not overwrite:
return await self.getDestDir(client, peer_jid, transfer_data, file_data)
self.openFileWrite(client, file_path, transfer_data, file_data, stream_object)
return True
@ -315,7 +304,7 @@ class FilePlugin:
"size_human" will also be added with human readable file size
@param stream_object(bool): if True, a stream_object will be used instead of file_obj
a stream.FileStreamObject will be used
return (defer.Deferred): True if transfer is accepted
return: True if transfer is accepted
"""
cont, ret_value = await self.host.trigger.asyncReturnPoint(
"FILE_getDestDir", client, peer_jid, transfer_data, file_data, stream_object
@ -327,7 +316,7 @@ class FilePlugin:
assert PROGRESS_ID_KEY in file_data
# human readable size
file_data["size_human"] = common_utils.getHumanSize(file_data["size"])
d = xml_tools.deferDialog(
resp_data = await xml_tools.deferDialog(
self.host,
_(CONFIRM).format(peer=peer_jid.full(), **file_data),
_(CONFIRM_TITLE),
@ -341,12 +330,13 @@ class FilePlugin:
security_limit=SECURITY_LIMIT,
profile=client.profile,
)
d.addCallback(
self._gotConfirmation,
accepted = await self._gotConfirmation(
client,
resp_data,
peer_jid,
transfer_data,
file_data,
stream_object,
)
return d
return accepted

View file

@ -19,7 +19,6 @@
import time
import dateutil
import calendar
import urllib.parse
from secrets import token_urlsafe
from typing import Optional
from functools import partial
@ -1032,13 +1031,12 @@ class XEP_0277(object):
will return(JID(u'sat-pubsub.example.net'), 'urn:xmpp:comments:_af43b363-3259-4b2a-ba4c-1bc33aa87634__urn:xmpp:groupblog:somebody@example.net')
@return (tuple[jid.JID, unicode]): service and node
"""
parsed_url = urllib.parse.urlparse(node_url, "xmpp")
service = jid.JID(parsed_url.path)
parsed_queries = urllib.parse.parse_qs(parsed_url.query)
node = parsed_queries.get("node", [""])[0]
if not node:
raise exceptions.DataError("Invalid comments link")
try:
parsed_url = xmpp_uri.parseXMPPUri(node_url)
service = jid.JID(parsed_url["path"])
node = parsed_url["node"]
except Exception as e:
raise exceptions.DataError(f"Invalid comments link: {e}")
return (service, node)

View file

@ -19,7 +19,7 @@
from zope.interface import implementer
from twisted.internet import defer
from twisted.internet import reactor
from twisted.words.protocols.jabber import xmlstream, jid
from twisted.words.protocols.jabber import xmlstream, jid, error
from twisted.words.xish import domish
from wokkel import disco, iwokkel
from sat.core.i18n import _, D_
@ -38,7 +38,7 @@ PLUGIN_INFO = {
C.PI_NAME: "Jingle Message Initiation",
C.PI_IMPORT_NAME: "XEP-0353",
C.PI_TYPE: "XEP",
C.PI_MODES: C.PLUG_MODE_CLIENT,
C.PI_MODES: [C.PLUG_MODE_CLIENT],
C.PI_PROTOCOLS: ["XEP-0353"],
C.PI_DEPENDENCIES: ["XEP-0166"],
C.PI_MAIN: "XEP_0353",
@ -85,8 +85,15 @@ class XEP_0353:
if peer_jid.resource:
return True
infos = await self.host.memory.disco.getInfos(client, peer_jid)
categories = {c for c, __ in infos.identities}
try:
infos = await self.host.memory.disco.getInfos(client, peer_jid)
except error.StanzaError as e:
if e.condition == "service-unavailable":
categories = {}
else:
raise e
else:
categories = {c for c, __ in infos.identities}
if "component" in categories:
# we don't use message initiation with components
return True

View file

@ -19,6 +19,7 @@
""" XMPP uri parsing tools """
import sys
import urllib.parse
import urllib.request, urllib.parse, urllib.error
@ -53,7 +54,13 @@ def parseXMPPUri(uri):
if query_end == -1 or "=" in query_type:
raise ValueError("no query type, invalid XMPP URI")
pairs = urllib.parse.parse_qs(uri_split.geturl())
if sys.version_info >= (3, 9):
# parse_qs behaviour has been modified in Python 3.9, ";" is not understood as a
# parameter separator anymore but the "separator" argument has been added to
# change it.
pairs = urllib.parse.parse_qs(uri_split.geturl(), separator=";")
else:
pairs = urllib.parse.parse_qs(uri_split.geturl())
for k, v in list(pairs.items()):
if len(v) != 1:
raise NotImplementedError("multiple values not managed")

View file

@ -140,7 +140,21 @@ class Bridge:
kwargs['reply_handler'] = _callback
kwargs['error_handler'] = lambda err: _errback(dbus_to_bridge_exception(err))
return method(*args, **kwargs)
try:
return method(*args, **kwargs)
except ValueError as e:
if e.args[0].startswith("Unable to guess signature"):
# XXX: if frontend is started too soon after backend, the
# inspection misses methods (notably plugin dynamically added
# methods). The following hack works around that by redoing the
# cache of introspected methods signatures.
log.debug("using hack to work around inspection issue")
proxy = self.db_plugin_iface.proxy_object
IN_PROGRESS = proxy.INTROSPECT_STATE_INTROSPECT_IN_PROGRESS
proxy._introspect_state = IN_PROGRESS
proxy._Introspect()
return self.db_plugin_iface.get_dbus_method(name)(*args, **kwargs)
raise e
return getPluginMethod
@ -930,13 +944,32 @@ class AIOBridge(Bridge):
fut.set_result, ret)
error_handler = lambda err: loop.call_soon_threadsafe(
fut.set_exception, dbus_to_bridge_exception(err))
method(
*args,
**kwargs,
timeout=const_TIMEOUT,
reply_handler=reply_handler,
error_handler=error_handler
)
try:
method(
*args,
**kwargs,
timeout=const_TIMEOUT,
reply_handler=reply_handler,
error_handler=error_handler
)
except ValueError as e:
if e.args[0].startswith("Unable to guess signature"):
# same hack as for Bridge.__getattribute__
log.warning("using hack to work around inspection issue")
proxy = self.db_plugin_iface.proxy_object
IN_PROGRESS = proxy.INTROSPECT_STATE_INTROSPECT_IN_PROGRESS
proxy._introspect_state = IN_PROGRESS
proxy._Introspect()
self.db_plugin_iface.get_dbus_method(name)(
*args,
**kwargs,
timeout=const_TIMEOUT,
reply_handler=reply_handler,
error_handler=error_handler
)
else:
raise e
return fut
return getPluginMethod

View file

@ -54,6 +54,11 @@ class Const(constants.Const):
OUTPUT_XMLUI,
OUTPUT_LIST_XMLUI,
)
OUTPUT_NAME_SIMPLE = "simple"
OUTPUT_NAME_XML = "xml"
OUTPUT_NAME_XML_RAW = "xml-raw"
OUTPUT_NAME_JSON = "json"
OUTPUT_NAME_JSON_RAW = "json-raw"
# Pubsub options flags
SERVICE = "service" # service required

View file

@ -26,9 +26,6 @@ from sat.tools.common import date_utils
import json
__outputs__ = ["Simple", "Json"]
SIMPLE = "simple"
JSON = "json"
JSON_RAW = "json_raw"
class Simple(object):
@ -36,13 +33,13 @@ class Simple(object):
def __init__(self, host):
self.host = host
host.register_output(C.OUTPUT_TEXT, SIMPLE, self.simple_print)
host.register_output(C.OUTPUT_LIST, SIMPLE, self.list)
host.register_output(C.OUTPUT_DICT, SIMPLE, self.dict)
host.register_output(C.OUTPUT_LIST_DICT, SIMPLE, self.list_dict)
host.register_output(C.OUTPUT_DICT_DICT, SIMPLE, self.dict_dict)
host.register_output(C.OUTPUT_MESS, SIMPLE, self.messages)
host.register_output(C.OUTPUT_COMPLEX, SIMPLE, self.simple_print)
host.register_output(C.OUTPUT_TEXT, C.OUTPUT_NAME_SIMPLE, self.simple_print)
host.register_output(C.OUTPUT_LIST, C.OUTPUT_NAME_SIMPLE, self.list)
host.register_output(C.OUTPUT_DICT, C.OUTPUT_NAME_SIMPLE, self.dict)
host.register_output(C.OUTPUT_LIST_DICT, C.OUTPUT_NAME_SIMPLE, self.list_dict)
host.register_output(C.OUTPUT_DICT_DICT, C.OUTPUT_NAME_SIMPLE, self.dict_dict)
host.register_output(C.OUTPUT_MESS, C.OUTPUT_NAME_SIMPLE, self.messages)
host.register_output(C.OUTPUT_COMPLEX, C.OUTPUT_NAME_SIMPLE, self.simple_print)
def simple_print(self, data):
self.host.disp(str(data))
@ -109,19 +106,19 @@ class Json(object):
def __init__(self, host):
self.host = host
host.register_output(C.OUTPUT_TEXT, JSON, self.dump)
host.register_output(C.OUTPUT_LIST, JSON, self.dump_pretty)
host.register_output(C.OUTPUT_LIST, JSON_RAW, self.dump)
host.register_output(C.OUTPUT_DICT, JSON, self.dump_pretty)
host.register_output(C.OUTPUT_DICT, JSON_RAW, self.dump)
host.register_output(C.OUTPUT_LIST_DICT, JSON, self.dump_pretty)
host.register_output(C.OUTPUT_LIST_DICT, JSON_RAW, self.dump)
host.register_output(C.OUTPUT_DICT_DICT, JSON, self.dump_pretty)
host.register_output(C.OUTPUT_DICT_DICT, JSON_RAW, self.dump)
host.register_output(C.OUTPUT_MESS, JSON, self.dump_pretty)
host.register_output(C.OUTPUT_MESS, JSON_RAW, self.dump)
host.register_output(C.OUTPUT_COMPLEX, JSON, self.dump_pretty)
host.register_output(C.OUTPUT_COMPLEX, JSON_RAW, self.dump)
host.register_output(C.OUTPUT_TEXT, C.OUTPUT_NAME_JSON, self.dump)
host.register_output(C.OUTPUT_LIST, C.OUTPUT_NAME_JSON, self.dump_pretty)
host.register_output(C.OUTPUT_LIST, C.OUTPUT_NAME_JSON_RAW, self.dump)
host.register_output(C.OUTPUT_DICT, C.OUTPUT_NAME_JSON, self.dump_pretty)
host.register_output(C.OUTPUT_DICT, C.OUTPUT_NAME_JSON_RAW, self.dump)
host.register_output(C.OUTPUT_LIST_DICT, C.OUTPUT_NAME_JSON, self.dump_pretty)
host.register_output(C.OUTPUT_LIST_DICT, C.OUTPUT_NAME_JSON_RAW, self.dump)
host.register_output(C.OUTPUT_DICT_DICT, C.OUTPUT_NAME_JSON, self.dump_pretty)
host.register_output(C.OUTPUT_DICT_DICT, C.OUTPUT_NAME_JSON_RAW, self.dump)
host.register_output(C.OUTPUT_MESS, C.OUTPUT_NAME_JSON, self.dump_pretty)
host.register_output(C.OUTPUT_MESS, C.OUTPUT_NAME_JSON_RAW, self.dump)
host.register_output(C.OUTPUT_COMPLEX, C.OUTPUT_NAME_JSON, self.dump_pretty)
host.register_output(C.OUTPUT_COMPLEX, C.OUTPUT_NAME_JSON_RAW, self.dump)
def dump(self, data):
self.host.disp(json.dumps(data, default=str))

View file

@ -1,7 +1,6 @@
#! /usr/bin/env python3
# jp: a SàT command line tool
# Libervia CLI frontend
# Copyright (C) 2009-2021 Jérôme Poisson (goffi@goffi.org)
# This program is free software: you can redistribute it and/or modify
@ -36,8 +35,6 @@ except ImportError:
__outputs__ = ["XML"]
RAW = "xml_raw"
PRETTY = "xml_pretty"
class XML(object):
@ -45,16 +42,20 @@ class XML(object):
def __init__(self, host):
self.host = host
host.register_output(C.OUTPUT_XML, PRETTY, self.pretty, default=True)
host.register_output(C.OUTPUT_LIST_XML, PRETTY, self.pretty_list, default=True)
host.register_output(C.OUTPUT_XML, RAW, self.raw)
host.register_output(C.OUTPUT_LIST_XML, RAW, self.list_raw)
host.register_output(C.OUTPUT_XML, C.OUTPUT_NAME_XML, self.pretty, default=True)
host.register_output(
C.OUTPUT_LIST_XML, C.OUTPUT_NAME_XML, self.pretty_list, default=True
)
host.register_output(C.OUTPUT_XML, C.OUTPUT_NAME_XML_RAW, self.raw)
host.register_output(C.OUTPUT_LIST_XML, C.OUTPUT_NAME_XML_RAW, self.list_raw)
def colorize(self, xml):
if pygments is None:
self.host.disp(
_(
"Pygments is not available, syntax highlighting is not possible. Please install if from http://pygments.org or with pip install pygments"
"Pygments is not available, syntax highlighting is not possible. "
"Please install if from http://pygments.org or with pip install "
"pygments"
),
error=True,
)

View file

@ -35,7 +35,7 @@ class LiberviaCliJson:
def __call__(self, *args, **kwargs):
args = self.subcommands + list(args)
self.subcommands.clear()
kwargs['output'] = 'json_raw'
kwargs['output'] = 'json-raw'
kwargs['_tty_out'] = False
cmd = li(*args, **kwargs)
return json.loads(cmd.stdout)
@ -60,7 +60,7 @@ class LiberviaCliElt(LiberviaCliJson):
def __call__(self, *args, **kwargs):
args = self.subcommands + list(args)
self.subcommands.clear()
kwargs['output'] = 'xml_raw'
kwargs['output'] = 'xml-raw'
kwargs['_tty_out'] = False
cmd = li(*args, **kwargs)
return self.parser(cmd.stdout.decode().strip())
@ -153,13 +153,13 @@ class Editor:
@pytest.fixture(scope="session")
def li_json():
"""Run li with "json_raw" output, and returns the parsed value"""
"""Run li with "json-raw" output, and returns the parsed value"""
return LiberviaCliJson()
@pytest.fixture(scope="session")
def li_elt():
"""Run li with "xml_raw" output, and returns the parsed value"""
"""Run li with "xml-raw" output, and returns the parsed value"""
return LiberviaCliElt()

View file

@ -176,7 +176,7 @@ class TestLiberviaCliBlog:
li.blog.edit(_env=editor.env)
assert len(editor.original_content) == 0
assert editor.new_content == payload_md
items_data = li_json.blog.get(max=1)
items_data = li_json.blog.get(max_items=1)
last_item = items_data[0][0]
last_item_id = last_item['id']
assert last_item['content'] == "content in markdown"
@ -187,7 +187,7 @@ class TestLiberviaCliBlog:
li.blog.edit("--last-item", _env=editor.env)
assert editor.original_content == payload_md
assert editor.new_content == f"{payload_md} extended"
items_data = li_json.blog.get(max=1)
items_data = li_json.blog.get(max_items=1)
last_item = items_data[0][0]
# we check that the id hasn't been modified
assert last_item['id'] == last_item_id

View file

@ -94,9 +94,9 @@ class TestPhotos:
click(album_link)
wait_until(lambda: S("#file_drop").exists())
wait_until(lambda: not S("#loading_screen").exists())
drag_file("/src/sat/tests/_files/test_1.jpg", "drop photos here")
drag_file("/src/libervia-backend/tests/_files/test_1.jpg", "drop photos here")
wait_until(lambda: len(find_all(S("div.progress_finished")))==1)
drag_file("/src/sat/tests/_files/test_2.jpg", "drop photos here")
drag_file("/src/libervia-backend/tests/_files/test_2.jpg", "drop photos here")
wait_until(lambda: len(find_all(S("div.progress_finished")))==2)
assert S('img[alt="test_1.jpg"]').exists()
assert S('img[alt="test_2.jpg"]').exists()

View file

@ -158,19 +158,19 @@ def use_e2e_env():
libervia_web_root_path = libervia_web_path.parent
if (libervia_web_root_path / ".hg").is_dir():
libervia_web_source = libervia_web_root_path
libervia_web_target = "/src/libervia"
libervia_web_target = "/src/libervia-web"
else:
libervia_web_source = libervia_web_path
libervia_web_target = "/src/libervia/libervia"
libervia_web_target = "/src/libervia-web/libervia"
sat_templates_path = Path(sat_templates.__file__).parent.resolve()
sat_templates_root_path = sat_templates_path.parent
if (sat_templates_root_path / ".hg").is_dir():
sat_templates_source = sat_templates_root_path
sat_templates_target = "/src/sat_templates"
sat_templates_target = "/src/libervia-templates"
else:
sat_templates_source = sat_templates_path
sat_templates_target = "/src/sat_templates/sat_templates"
sat_templates_target = "/src/libervia-templates/sat_templates"
compose_e2e_path = docker_path / "docker-compose-e2e.yml"
if not compose_e2e_path.is_file():
@ -186,13 +186,13 @@ def use_e2e_env():
volumes:
- type: bind
source: {backend_root_path}
target: /src/sat
target: /src/libervia-backend
read_only: true
web:
volumes:
- type: bind
source: {backend_root_path}
target: /src/sat
target: /src/libervia-backend
read_only: true
- type: bind
source: {libervia_web_source}
@ -224,7 +224,7 @@ def use_e2e_env():
docker_compose.up("-d")
p = docker_compose.exec(
"-T", "--workdir", "/src/sat/tests", "backend",
"-T", "--workdir", "/src/libervia-backend/tests", "backend",
"pytest", "-o", "cache_dir=/tmp", *sys.argv[1:], color="yes",
_in=sys.stdin, _out=live_out, _out_bufsize=0, _err=live_err, _err_bufsize=0,
_bg=True