diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7d64fa4..90708c8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,31 +1,30 @@ --- -image: python:3.8 +image: s3lph/spaceapi-server-ci:20191126-01 stages: -- test -- build + - test + - build before_script: -- pip3 install coverage pycodestyle -- export SPACEAPI_SERVER_VERSION=$(python -c 'import spaceapi_server; print(spaceapi_server.__version__)') + - export SPACEAPI_SERVER_VERSION=$(python -c 'import spaceapi_server; print(spaceapi_server.__version__)') test: stage: test script: - - pip3 install -e . - - python3 -m coverage run --rcfile=setup.cfg -m unittest discover spaceapi_server - - python3 -m coverage combine - - python3 -m coverage report --rcfile=setup.cfg + - pip3 install -e . + - python3 -m coverage run --rcfile=setup.cfg -m unittest discover spaceapi_server + - python3 -m coverage combine + - python3 -m coverage report --rcfile=setup.cfg codestyle: stage: test script: - - pip3 install -e . - - pycodestyle spaceapi_server + - pip3 install -e . + - pycodestyle spaceapi_server @@ -41,3 +40,65 @@ build_wheel: - dist/SHA256SUMS only: - tags + +build_debian: + stage: build + script: + - find package/debian -name .gitkeep -delete + # Copy example plugin + - install -m0644 examples/plugins/example.py package/debian/spaceapi-server/etc/spaceapi-server/plugins/example.py + # Create control + - | + cat > package/debian/spaceapi-server/DEBIAN/control < + Section: web + Priority: optional + Architecture: all + Depends: python3 (>= 3.6), python3-jinja2, python3-bottle + Description: Lightweight SpaceAPI endpoint server + Lightweight server for SpaceAPI endpoints. Includes support for pluggable + templating, so dynamic content, like sensor values, can be added. + EOF + - chmod 0644 package/debian/spaceapi-server/DEBIAN/control + # Create changelog + - | + for version in "$(cat CHANGELOG.md | grep '" | grep -B 1000 "<"'!'"-- END CHANGES ${version} -->" | tail -n +2 | head -n -1 | sed -re 's/^-/ */g' >> package/debian/spaceapi-server/usr/share/doc/spaceapi-server/changelog + echo "\n -- s3lph $(date -R)\n" >> package/debian/spaceapi-server/usr/share/doc/spaceapi-server/changelog + done + - gzip -9n package/debian/spaceapi-server/usr/share/doc/spaceapi-server/changelog + # Copy license + - install -m0644 LICENSE package/debian/spaceapi-server/usr/share/doc/spaceapi-server/copyright + # Install spaceapi-server into package root + - python3 setup.py egg_info install --root=package/debian/spaceapi-server/ --prefix=/usr --optimize=1 + - cd package/debian/spaceapi-server + - mkdir -p usr/lib/python3/dist-packages/ + - rsync -a usr/lib/python3.8/site-packages/spaceapi_server usr/lib/python3/dist-packages/spaceapi_server + - rm -rf usr/lib/python3.8/ + # Remove compiled Python files + - find usr/lib/python3/dist-packages -name __pycache__ -exec rm -r {} \; 2>/dev/null || true + - find usr/lib/python3/dist-packages -name '*.pyc' -exec rm {} \; + # Move spaceapi-server binary to /usr/lib + - mv usr/bin/spaceapi-server usr/lib/spaceapi-server/spaceapi-server + - sed -re 's$#!/usr/local/bin/python3.*$#!/usr/bin/python3$' -i usr/lib/spaceapi-server/spaceapi-server + # Fix file permissions + - find . -type f -exec chmod 0644 {} \; + - find . -type d -exec chmod 755 {} \; + - chmod 0755 usr/lib/spaceapi-server/spaceapi-server DEBIAN/postinst DEBIAN/prerm DEBIAN/postrm + # Build the package + - cd .. + - dpkg-deb --build spaceapi-server + - mv spaceapi-server.deb "spaceapi-server_${SPACEAPI_SERVER_VERSION}-1_all.deb" + # Run lintian + - sudo -u nobody lintian --fail-on-warnings "spaceapi-server_${SPACEAPI_SERVER_VERSION}-1_all.deb" + # Generate checksum + - sha256sum *.deb > SHA256SUMS + artifacts: + paths: + - "package/debian/*.deb" + - package/debian/SHA256SUMS + only: + - tags diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..38a0994 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,14 @@ +# SpaceAPI Server Changelog + + +## Version 0.1 + +First release. + +### Changes + + +- First somewhat stable version. + + + diff --git a/README.md b/README.md index f0d553f..6cca514 100644 --- a/README.md +++ b/README.md @@ -91,7 +91,8 @@ its existence. ``` Although the value for the `state` key is a string containing the Jinja2 template, the return value of your template - function is a complex data type, which will be inserted into the result as such. + function is a complex data type, which will be inserted into the result as such. Please be aware that only the + first token of a templated string is used in the result. This limitation is caused by the way Jinja2 is (ab-) used. 3. Configure the server: diff --git a/examples/template.json b/examples/template.json index b066559..7c701f9 100644 --- a/examples/template.json +++ b/examples/template.json @@ -12,7 +12,7 @@ }, "issue_report_channels": [ "email" - ] + ], "state": "{#- You can write your own plugins for retrieving dynamic information -#} {{ our_space_state() }}", "sensors": { "people_now_present": "{{ our_sensor_backend('people_count') }}" diff --git a/package/Dockerfile b/package/Dockerfile new file mode 100644 index 0000000..f28cd2c --- /dev/null +++ b/package/Dockerfile @@ -0,0 +1,6 @@ +FROM python:3.8-buster as python + +RUN apt update \ + && apt install -y --no-install-recommends \ + python3-coverage python3-pycodestyle lintian rsync sudo \ + && rm -rf /var/cache/apt diff --git a/package/debian/spaceapi-server/DEBIAN/conffiles b/package/debian/spaceapi-server/DEBIAN/conffiles new file mode 100644 index 0000000..9f42ddb --- /dev/null +++ b/package/debian/spaceapi-server/DEBIAN/conffiles @@ -0,0 +1,3 @@ +/etc/spaceapi-server/config.json +/etc/spaceapi-server/template.json +/etc/spaceapi-server/plugins/example.py diff --git a/package/debian/spaceapi-server/DEBIAN/postinst b/package/debian/spaceapi-server/DEBIAN/postinst new file mode 100644 index 0000000..abce311 --- /dev/null +++ b/package/debian/spaceapi-server/DEBIAN/postinst @@ -0,0 +1,21 @@ +#!/bin/sh + +set -e + +if [ "$1" = "configure" ]; then + + if ! getent group spaceapi-server >/dev/null; then + groupadd --system spaceapi-server + fi + + if ! getent passwd spaceapi-server >/dev/null; then + useradd --system --create-home --gid spaceapi-server --home-dir /var/lib/spaceapi-server \ + --shell /usr/sbin/nologin spaceapi-server + fi + + chown root:spaceapi-server /etc/spaceapi-server + chmod 0750 /etc/spaceapi-server + + systemctl daemon-reload || true + +fi \ No newline at end of file diff --git a/package/debian/spaceapi-server/DEBIAN/postrm b/package/debian/spaceapi-server/DEBIAN/postrm new file mode 100644 index 0000000..97161c0 --- /dev/null +++ b/package/debian/spaceapi-server/DEBIAN/postrm @@ -0,0 +1,9 @@ +#!/bin/sh + +set -e + +if [ "$1" = "remove" ]; then + + systemctl daemon-reload || true + +fi \ No newline at end of file diff --git a/package/debian/spaceapi-server/DEBIAN/prerm b/package/debian/spaceapi-server/DEBIAN/prerm new file mode 100644 index 0000000..bc72f5d --- /dev/null +++ b/package/debian/spaceapi-server/DEBIAN/prerm @@ -0,0 +1,9 @@ +#!/bin/sh + +set -e + +if [ "$1" = "remove" ]; then + + userdel spaceapi-server + +fi \ No newline at end of file diff --git a/package/debian/spaceapi-server/etc/spaceapi-server/config.json b/package/debian/spaceapi-server/etc/spaceapi-server/config.json new file mode 100644 index 0000000..bb5b41a --- /dev/null +++ b/package/debian/spaceapi-server/etc/spaceapi-server/config.json @@ -0,0 +1,7 @@ +{ + "address": "::", + "port": 8080, + "template": "/etc/spaceapi-server/template.json", + "plugins_dir": "/etc/spaceapi-server/plugins", + "plugins": {} +} \ No newline at end of file diff --git a/package/debian/spaceapi-server/etc/spaceapi-server/plugins/.gitkeep b/package/debian/spaceapi-server/etc/spaceapi-server/plugins/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/package/debian/spaceapi-server/etc/spaceapi-server/template.json b/package/debian/spaceapi-server/etc/spaceapi-server/template.json new file mode 100644 index 0000000..2af901c --- /dev/null +++ b/package/debian/spaceapi-server/etc/spaceapi-server/template.json @@ -0,0 +1,19 @@ +{ + "api": "0.13", + "space": "Example Space", + "logo": "https://example.org/logo.png", + "url": "https://example.org", + "location": { + "lat": 0.0, + "lon": 0.0 + }, + "state": { + "open": null + }, + "contact": { + "email": "example@example.org" + }, + "issue_report_channels": [ + "email" + ] +} \ No newline at end of file diff --git a/package/debian/spaceapi-server/lib/systemd/system/spaceapi-server.service b/package/debian/spaceapi-server/lib/systemd/system/spaceapi-server.service new file mode 100644 index 0000000..8e8b436 --- /dev/null +++ b/package/debian/spaceapi-server/lib/systemd/system/spaceapi-server.service @@ -0,0 +1,10 @@ +[Unit] +Description=Lightweight SpaceAPI Endpoint Server + +[Service] +ExecStart=/usr/lib/spaceapi-server/spaceapi-server /etc/spaceapi-server/config.json +ExecReload=/usr/bin/kill -HUP $MAINPID +User=spaceapi-server + +[Install] +WantedBy=network-online.target \ No newline at end of file diff --git a/package/debian/spaceapi-server/usr/lib/spaceapi-server/.gitkeep b/package/debian/spaceapi-server/usr/lib/spaceapi-server/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/package/debian/spaceapi-server/usr/share/doc/spaceapi-server/changelog b/package/debian/spaceapi-server/usr/share/doc/spaceapi-server/changelog new file mode 100644 index 0000000..e69de29 diff --git a/setup.py b/setup.py index a005663..ebbefca 100755 --- a/setup.py +++ b/setup.py @@ -8,13 +8,13 @@ setup( name='spaceapi_server', version=__version__, author='s3lph', - author_email='', - description='A lightweight SpaceAPI (spaceapi.io) endpoint server', + author_email='account-gitlab-ideynizv@kernelpanic.lol', + description='Lightweight SpaceAPI (spaceapi.io) endpoint server', license='MIT', keywords='spaceapi', url='https://gitlab.com/s3lph/spaceapi-server', packages=find_packages(exclude=['*.test']), - long_description='A lightweight server for SpaceAPI endpoints. Includes support for pluggable templating, ' + long_description='Lightweight server for SpaceAPI endpoints. Includes support for pluggable templating, ' 'so dynamic content, like sensor values, can be added.', python_requires='>=3.6', install_requires=[ diff --git a/spaceapi_server/template/__init__.py b/spaceapi_server/template/__init__.py index 6b1cbbc..7062dea 100644 --- a/spaceapi_server/template/__init__.py +++ b/spaceapi_server/template/__init__.py @@ -28,8 +28,11 @@ def render(template: str): env = _env_init() # Create a Jinja2 template from the input string t = env.from_string(template) + decoder = json.JSONDecoder() # Render the template and turn the JSON dump back into complex data structures - return json.loads(t.render()) + # Only parse the first JSON object in the string, ignore the rest + obj, i = decoder.raw_decode(t.render()) + return obj def render_traverse(obj): diff --git a/spaceapi_server/template/test/test_template.py b/spaceapi_server/template/test/test_template.py index df4404d..fdbc361 100644 --- a/spaceapi_server/template/test/test_template.py +++ b/spaceapi_server/template/test/test_template.py @@ -36,6 +36,7 @@ class TemplateTest(unittest.TestCase): self.assertEqual(42, render('{{ 42 }}')) self.assertEqual(['foo'], render('{{ [ "foo" ] }}')) self.assertEqual({'foo': ['bar']}, render('{{ { "foo": [ "bar" ] } }}')) + self.assertEqual('foo', render('foo{{ "bar" }}')) def test_render_traverse(self): template = {