diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 44fe77c..0000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,78 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - - -## [Unreleased] - -nothing as of yet - -## [1.1.2] - 2023-08-07 - -### Added - -- link to changelog in package metadata - -### Changed - -- manifest example in README as to reflect the latest default sample output - -### Fixed - -- deprecated `license_file` property in package metadata - -## [1.1.1] - 2023-08-07 - -### Added - -- basic test which makes sure the default sample executes without errors - -### Changed - -- metadata of python package as to make it more user-friendly when browsing PyPI - -### Fixed - -- licensing issue with default sample, as it was previously unlicensed - -### Removed - -- redundant default sample configuration - - -## [1.1.0] - 2023-08-07 - -### Added - -- Changelog -- License - -### Changed - -- Output path of attachments, which are now contained in directories named - after their containing page - - -## [1.0.1] - 2023-08-07 - -### Added - -- Sample manifest in README to give a better idea on the output - - -## [1.0.0] - 2023-08-07 - -### Added - -- initial release - - -[unreleased]: https://bitbucket.org/victorykit/xconfluencebuilder/branch/master -[1.1.2]: https://bitbucket.org/victorykit/xconfluencebuilder/src/v1.1.2/ -[1.1.1]: https://bitbucket.org/victorykit/xconfluencebuilder/src/v1.1.1/ -[1.1.0]: https://bitbucket.org/victorykit/xconfluencebuilder/src/v1.1.0/ -[1.0.1]: https://bitbucket.org/victorykit/xconfluencebuilder/src/v1.0.1/ -[1.0.0]: https://bitbucket.org/victorykit/xconfluencebuilder/src/v1.0.0/ diff --git a/LICENSE b/LICENSE deleted file mode 100644 index f092929..0000000 --- a/LICENSE +++ /dev/null @@ -1,41 +0,0 @@ -DL-DE->BY-2.0 -Datenlizenz Deutschland – Namensnennung – Version 2.0 - -(1) Jede Nutzung ist unter den Bedingungen dieser „Datenlizenz Deutschland – Namensnennung – Version 2.0" zulässig. - -Die bereitgestellten Daten und Metadaten dürfen für die kommerzielle und nicht kommerzielle Nutzung insbesondere - - vervielfältigt, ausgedruckt, präsentiert, verändert, bearbeitet sowie an Dritte übermittelt werden; - mit eigenen Daten und Daten Anderer zusammengeführt und zu selbständigen neuen Datensätzen verbunden werden; - in interne und externe Geschäftsprozesse, Produkte und Anwendungen in öffentlichen und nicht öffentlichen elektronischen Netzwerken eingebunden werden. - -(2) Bei der Nutzung ist sicherzustellen, dass folgende Angaben als Quellenvermerk enthalten sind: - - Bezeichnung des Bereitstellers nach dessen Maßgabe, - der Vermerk „Datenlizenz Deutschland – Namensnennung – Version 2.0" oder „dl-de/by-2-0" mit Verweis auf den Lizenztext unter www.govdata.de/dl-de/by-2-0 sowie - einen Verweis auf den Datensatz (URI). - -Dies gilt nur soweit die datenhaltende Stelle die Angaben 1. bis 3. zum Quellenvermerk bereitstellt. - -(3) Veränderungen, Bearbeitungen, neue Gestaltungen oder sonstige Abwandlungen sind im Quellenvermerk mit dem Hinweis zu versehen, dass die Daten geändert wurden. - - -Data licence Germany – attribution – version 2.0 - -(1) Any use will be permitted provided it fulfils the requirements of this "Data licence Germany – attribution – Version 2.0". - -The data and meta-data provided may, for commercial and non-commercial use, in particular - - be copied, printed, presented, altered, processed and transmitted to third parties; - be merged with own data and with the data of others and be combined to form new and independent datasets; - be integrated in internal and external business processes, products and applications in public and non-public electronic networks. - -(2) The user must ensure that the source note contains the following information: - - the name of the provider, - the annotation "Data licence Germany – attribution – Version 2.0" or "dl-de/by-2-0" referring to the licence text available at www.govdata.de/dl-de/by-2-0, and - a reference to the dataset (URI). - -This applies only if the entity keeping the data provides the pieces of information 1-3 for the source note. - -(3) Changes, editing, new designs or other amendments must be marked as such in the source note. diff --git a/README.md b/README.md index 3c6a7fc..351280c 100644 --- a/README.md +++ b/README.md @@ -18,47 +18,6 @@ For a reference implementation of an external publisher, please refer to [PSConfluencePublisher](https://bitbucket.org/victorykit/psconfluencepublisher), a standalone PowerShell publisher for *Atlassian Confluence Builder for Sphinx*. -The following is a sample manifest generated from the default sample: - -``` -{ - "Pages": [ - { - "Title": "Default Sample~", - "Ref": "pages/Default+Sample~.xml" - }, - { - "Title": "Cats", - "Ref": "pages/Cats.xml", - "AncestorTitle": "Default Sample~" - } - ], - "Attachments": [ - { - "Name": "pexels-just-a-couple-photos-3777622.jpg", - "ContainerPageTitle": "Cats", - "MimeType": "image/jpeg", - "Ref": "attachments/Cats/pexels-just-a-couple-photos-3777622.jpg" - }, - { - "Name": "pexels-sami-aksu-14356302.jpg", - "ContainerPageTitle": "Cats", - "MimeType": "image/jpeg", - "Ref": "attachments/Cats/pexels-sami-aksu-14356302.jpg" - }, - { - "Name": "objects.inv", - "ContainerPageTitle": "Default Sample~", - "MimeType": "application/octet-stream", - "Ref": "attachments/Default+Sample~/objects.inv" - } - ] -} -``` - -> **NOTE**: The manifest's schema is currently part of the - [PSConfluencePublisher](https://bitbucket.org/victorykit/psconfluencepublisher) - ## Installing You can install this extension via PyPI (through pip): diff --git a/samples/default/docs/conf.py b/samples/default/docs/conf.py index 64857f5..b904a4d 100644 --- a/samples/default/docs/conf.py +++ b/samples/default/docs/conf.py @@ -3,9 +3,12 @@ """ __author__ = 'theodor.rodweil@victory-k.it' __copyright__ = '2023 - Victory Karma IT' -__license__ = 'DL-DE-BY-2.0' +__license__ = 'UNLICENSED' __version__ = "1.0" +import sys +from pathlib import Path + # -- Project information ------------------------------------------------------- project = 'Default Sample' @@ -22,9 +25,9 @@ extensions = ['xconfluencebuilder'] exclude_patterns = ['Pipfile*', 'build', '.DS_Store', '.venv'] -confluence_server_url = 'https://confluence.example.com/' +confluence_server_url = 'https://confluence.adesso.de/' -confluence_space_key = 'SampleSpace' +confluence_space_key = '~Tiara.Rodney@adesso.de' confluence_publish = True diff --git a/samples/default/docs/confluence_conf.py b/samples/default/docs/confluence_conf.py new file mode 100644 index 0000000..3a68843 --- /dev/null +++ b/samples/default/docs/confluence_conf.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python3 +"""Wrapper for Confluence Sphinx Builder + +enables support for configuration through shell environment variables + +.. warning:: + make sure to pin a concrete version of the ```` +""" +__author__ = 'theodor.rodweil@victory-k.it' +__copyright__ = '2023 - Victory Karma IT' +__license__ = 'DL-DE-BY-2.0' +__version__ = '1.2.0' + + +from dataclasses import dataclass, fields, asdict +from typing import Any, Optional, Callable, Type +from os import environ + + +#: rudimentary typecasting of serialized Python built-ins +DEFAULT_TYPECASTS = { + 'str': lambda inp: str(inp), + 'bool': lambda inp: {'true': True, 'false': False}[inp.lower()] +} + + +def get_config_from_environ( + typecasts: dict[str, Callable] = DEFAULT_TYPECASTS +) -> 'ConfluenceBuilderConfig': + """get confluence builder config from environment + + :param typecasts: a collection of built-in typecast functions + """ + props = {field.name:field.type for field in fields(ConfluenceBuilderConfig)} + + prop_names = props.keys() + + out = {} + + for environ_name in dict(environ).keys(): + + env_name = environ_name + + if env_name in prop_names: + + type_name = props[env_name].__name__ + + if type_name == 'Optional': + + type_name = props[env_name].__args__[0].__name__ + + value = typecasts[type_name]( + environ[environ_name] + ) + + if value is not None: + + out[env_name] = value + + try: + + return ConfluenceBuilderConfig(**out) + + except TypeError as err: + + raise TypeError(f'error getting config from environ: {err}') from err + + +def apply_config( + config: 'ConfluenceBuildConfig', + env: dict = globals() +) -> None: + """apply confluence builder config to runtime environment + + :param config: configuration instance object + :param env: global runtime variables instance object + """ + for key, value in asdict(config).items(): + + env[key.lower()] = value + + +@dataclass +class ConfluenceBuilderConfig: + """partial configuration of the Confluence builder for Sphinx + + see + `https://sphinxcontrib-confluencebuilder.readthedocs.io/en/stable/configuration/`_ + , for more information. + + """ + #: The URL for the Confluence instance to publish to. + CONFLUENCE_SERVER_URL: str + + #: The username value used to authenticate with the Confluence instance. + CONFLUENCE_SERVER_USER: Optional[str] = None + + #: Key of the space in Confluence to be used to publish generated documents + CONFLUENCE_SPACE_KEY: Optional[str] = None + + #: The username value used to authenticate with the Confluence instance. + CONFLUENCE_PUBLISH_DRYRUN: Optional[bool] = None + + #: A boolean that decides whether or not to allow publishing. + CONFLUENCE_PUBLISH: bool = True + + #: A boolean value to whether or not nest pages in a hierarchical ordered. + CONFLUENCE_PAGE_HIERARCHY: bool = True + + #: The password value used to authenticate with the Confluence instance. + CONFLUENCE_SERVER_PASS: Optional[str] = None + + #: The personal access token value used to authenticate with the Confluence + # instance + CONFLUENCE_PUBLISH_TOKEN: Optional[str] = None + + #: The root page found inside the configured space (confluence_space_key) + # where published pages will be a descendant of + CONFLUENCE_PARENT_PAGE: Optional[str] = None + + @staticmethod + def from_environ() -> 'ConfluenceBuilderConfig': + """get a new configuration object + """ + + return get_config_from_environ() + + def apply(self: Type, env: dict = globals()) -> None: + """apply the configuration to the current runtime environment + """ + + return apply_config(self, env) diff --git a/setup.cfg b/setup.cfg index b0d4fb9..65f44d9 100644 --- a/setup.cfg +++ b/setup.cfg @@ -6,11 +6,6 @@ author_email = theodor.rodweil@victory-k.it description = sphinxcontrib.confluencebuilder wrapper for delayed publishing long_description = file: README.md long_description_content_type = text/markdown -license = DL-DE-BY-2.0 -license_files = LICENSE -project_urls = - Changelog = https://bitbucket.org/victorykit/xconfluencebuilder/src/master/CHANGELOG.md - Repository = https://bitbucket.org/victorykit/xconfluencebuilder/ classifiers = ´ topic = : Software Development :: Libraries :: Python Modules diff --git a/src/xconfluencebuilder/__init__.py b/src/xconfluencebuilder/__init__.py index 68b8e17..f4efc0c 100644 --- a/src/xconfluencebuilder/__init__.py +++ b/src/xconfluencebuilder/__init__.py @@ -228,11 +228,16 @@ class ConfluencePublisher(_ConfluencePublisher): """ logger.info('pass-through intercept: store_attachment') + # 😭 i wanted to use this method so bad, but since we're ditching + # hashing altogether, this isn't necessary. We'll keep it as an + # orbituary 🪦 + # mime_extension = guess_extension(mimetype, False) + file_name = quote_plus(name) output_basepath = Path(getattr(self.config, 'xconfluence_outdir')) - file_ = output_basepath / 'attachments' / quote_plus(page_id) / file_name + file_ = output_basepath / 'attachments' / file_name file_.parent.mkdir(parents = True, exist_ok = True) diff --git a/tox.ini b/tox.ini index 1003e7a..4a83969 100644 --- a/tox.ini +++ b/tox.ini @@ -3,15 +3,6 @@ skipsdist = true maxversion = 3.7.0 isolated_build = True -[testenv:test-sample-default] -description = test the default sample -basepython = python3 -changedir = samples/default -setenv = - PIPENV_IGNORE_VIRTUALENVS = 1 -deps = pipenv -commands = - python3 -m pipenv run sphinx-build [testenv:lint] description = lint with pylint