From 3a0495b6af67f28891f3be8f58d5f5a5ac353957 Mon Sep 17 00:00:00 2001 From: Wolfgang Fahl Date: Sat, 3 Aug 2024 19:55:04 +0200 Subject: [PATCH] Deployed a7ffa8d with MkDocs version: 1.6.0 --- index.html | 26 +++++++++++++------------- search/search_index.json | 2 +- sitemap.xml.gz | Bin 127 -> 127 bytes 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/index.html b/index.html index 6bcb3b3..a2dc3eb 100644 --- a/index.html +++ b/index.html @@ -3691,7 +3691,7 @@

self, prefix: str = "pw", smw_version="4.1.3", - mw_version="1.39.7", + mw_version="1.39.8", port: int = 9079, ): """ @@ -3870,7 +3870,7 @@

pwc.log_action(f"patching {ls_file.name}") pwc.dc.container.copy_from(ls_path, ls_file.name) patch = Patch(file_path=ls_file.name) - lines = f"""// modified by profiwiki + lines = f"""// modified by profiwiki // use WikiEditor e.g. for MsUpload wfLoadExtension( 'WikiEditor' ); # make this an intranet - comment out if you want this to be a public wiki @@ -3883,7 +3883,7 @@

# WF 2015-01-20 # allow string functions - needed for Template:Link $wgPFEnableStringFunctions=true; -// allow raw HTML +// allow raw HTML $wgRawHtml = true; // allow images $wgAllowImageTag=true; @@ -3915,7 +3915,7 @@

$wgPdfEmbed['width'] = 800; //Default height for the PDF object container. $wgPdfEmbed['height'] = 1090; -//Allow user the usage of the tag +//Allow user the usage of the tag $wgGroupPermissions['*']['embed_pdf'] = true; // config parameters for MsUpload // https://www.mediawiki.org/wiki/Extension:MsUpload @@ -4035,8 +4035,8 @@

# after it has been globally disabled with "a2disconf". #Include conf-available/serve-cgi-bin.conf - # Mediawiki installations - ProxyPass / http://localhost:{config.port}/ + # Mediawiki installations + ProxyPass / http://localhost:{config.port}/ ProxyPassReverse / http://localhost:{config.port}/ </VirtualHost>""" return apache_config @@ -4059,7 +4059,7 @@

- __init__(prefix='pw', smw_version='4.1.3', mw_version='1.39.7', port=9079) + __init__(prefix='pw', smw_version='4.1.3', mw_version='1.39.8', port=9079)

@@ -4124,7 +4124,7 @@

self, prefix: str = "pw", smw_version="4.1.3", - mw_version="1.39.7", + mw_version="1.39.8", port: int = 9079, ): """ @@ -4298,8 +4298,8 @@

# after it has been globally disabled with "a2disconf". #Include conf-available/serve-cgi-bin.conf - # Mediawiki installations - ProxyPass / http://localhost:{config.port}/ + # Mediawiki installations + ProxyPass / http://localhost:{config.port}/ ProxyPassReverse / http://localhost:{config.port}/ </VirtualHost>""" return apache_config @@ -4848,7 +4848,7 @@

pwc.log_action(f"patching {ls_file.name}") pwc.dc.container.copy_from(ls_path, ls_file.name) patch = Patch(file_path=ls_file.name) - lines = f"""// modified by profiwiki + lines = f"""// modified by profiwiki // use WikiEditor e.g. for MsUpload wfLoadExtension( 'WikiEditor' ); # make this an intranet - comment out if you want this to be a public wiki @@ -4861,7 +4861,7 @@

# WF 2015-01-20 # allow string functions - needed for Template:Link $wgPFEnableStringFunctions=true; -// allow raw HTML +// allow raw HTML $wgRawHtml = true; // allow images $wgAllowImageTag=true; @@ -4893,7 +4893,7 @@

$wgPdfEmbed['width'] = 800; //Default height for the PDF object container. $wgPdfEmbed['height'] = 1090; -//Allow user the usage of the tag +//Allow user the usage of the tag $wgGroupPermissions['*']['embed_pdf'] = true; // config parameters for MsUpload // https://www.mediawiki.org/wiki/Extension:MsUpload diff --git a/search/search_index.json b/search/search_index.json index 44680d8..3cd142e 100644 --- a/search/search_index.json +++ b/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"ProfiWiki API Documentation","text":""},{"location":"#profiwiki.docker","title":"docker","text":"

Created on 2023-04-01

@author: wf

"},{"location":"#profiwiki.docker.ProfiWikiContainer","title":"ProfiWikiContainer","text":"

a profiwiki docker container wrapper

Source code in profiwiki/docker.py
class ProfiWikiContainer:\n    \"\"\"\n    a profiwiki docker container wrapper\n    \"\"\"\n\n    def __init__(self, dc: DockerContainer):\n        \"\"\"\n        Args:\n            dc(DockerContainer): the to wrap\n        \"\"\"\n        self.dc = dc\n\n    def log_action(self, action: str):\n        \"\"\"\n        log the given action\n\n        Args:\n            action(str): the d\n        \"\"\"\n        if self.dc:\n            print(f\"{action} {self.dc.kind} {self.dc.name}\", flush=True)\n        else:\n            print(f\"{action}\", flush=True)\n\n    def upload(self, text: str, path: str):\n        \"\"\"\n        upload the given text to the given path\n        \"\"\"\n        with tempfile.NamedTemporaryFile() as tmp:\n            self.log_action(f\"uploading {tmp.name} as {path} to \")\n            with open(tmp.name, \"w\") as text_file:\n                text_file.write(text)\n            self.dc.container.copy_to(tmp.name, path)\n\n    def killremove(self, volumes: bool = False):\n        \"\"\"\n        kill and remove me\n\n        Args:\n            volumes(bool): if True remove anonymous volumes associated with the container, default=True (to avoid e.g. passwords to get remembered / stuck\n        \"\"\"\n        if self.dc:\n            self.log_action(\"killing and removing\")\n            self.dc.container.kill()\n            self.dc.container.remove(volumes=volumes)\n\n    def start_cron(self):\n        \"\"\"\n        Starting periodic command scheduler: cron.\n        \"\"\"\n        self.dc.container.execute([\"/usr/sbin/service\", \"cron\", \"start\"], tty=True)\n\n    def install_plantuml(self):\n        \"\"\"\n        install plantuml to this container\n        \"\"\"\n        script = \"\"\"#!/bin/bash\n# install plantuml\n# WF 2023-05-01\napt-get update\napt-get install -y plantuml\n\"\"\"\n        # https://gabrieldemarmiesse.github.io/python-on-whales/docker_objects/containers/\n        script_path = \"/root/install_plantuml.sh\"\n        self.install_and_run_script(script, script_path)\n        pass\n\n    def install_and_run_script(self, script: str, script_path: str):\n        \"\"\"\n        install and run the given script\n\n        Args:\n            script(str): the source code of the script\n            script_path(str): the path to copy the script to and then execute\n        \"\"\"\n        self.upload(script, script_path)\n        # make executable\n        self.dc.container.execute([\"chmod\", \"+x\", script_path])\n        self.dc.container.execute([script_path], tty=True)\n\n    def install_fontawesome(self):\n        \"\"\"\n        install fontawesome to this container\n        \"\"\"\n        script = \"\"\"#!/bin/bash\n# install fontawesome\n# WF 2023-01-25\nversion=6.4.0\n#version=5.15.4\n#version=4.7.0\nzip_url=https://github.com/FortAwesome/Font-Awesome/releases/download/$version/fontawesome-free-$version-desktop.zip\n#https://github.com/FortAwesome/Font-Awesome/releases/download/5.15.4/fontawesome-free-5.15.4-desktop.zip\n\ncd /var/www\n#curl https://use.fontawesome.com/releases/$version/fontawesome-free-$version-web.zip -o fontawesome.zip\ncurl --location $zip_url -o fontawesome.zip\nunzip -o fontawesome.zip\nln -s -f fontawesome-free-$version-desktop fontawesome\nchown -R www-data.www-data fontawesome\ncd fontawesome\nln -s svgs/solid svg\ncat << EOS > /etc/apache2/conf-available/font-awesome.conf\nAlias /font-awesome /var/www/fontawesome\n<Directory /var/www/fontawesome>\n  Options Indexes FollowSymLinks MultiViews\n  Require all granted\n</Directory>\nEOS\na2enconf font-awesome\n\"\"\"\n        script_path = \"/root/install_fontawesome\"\n        self.install_and_run_script(script, script_path)\n        try:\n            self.dc.container.execute([\"service\", \"apache2\", \"restart\"])\n        except DockerException as e:\n            # we expect a SIGTERM\n            if not e.return_code == 143:\n                raise e\n        pass\n
"},{"location":"#profiwiki.docker.ProfiWikiContainer.__init__","title":"__init__(dc)","text":"

Parameters:

Name Type Description Default dc(DockerContainer)

the to wrap

required Source code in profiwiki/docker.py
def __init__(self, dc: DockerContainer):\n    \"\"\"\n    Args:\n        dc(DockerContainer): the to wrap\n    \"\"\"\n    self.dc = dc\n
"},{"location":"#profiwiki.docker.ProfiWikiContainer.install_and_run_script","title":"install_and_run_script(script, script_path)","text":"

install and run the given script

Parameters:

Name Type Description Default script(str)

the source code of the script

required script_path(str)

the path to copy the script to and then execute

required Source code in profiwiki/docker.py
def install_and_run_script(self, script: str, script_path: str):\n    \"\"\"\n    install and run the given script\n\n    Args:\n        script(str): the source code of the script\n        script_path(str): the path to copy the script to and then execute\n    \"\"\"\n    self.upload(script, script_path)\n    # make executable\n    self.dc.container.execute([\"chmod\", \"+x\", script_path])\n    self.dc.container.execute([script_path], tty=True)\n
"},{"location":"#profiwiki.docker.ProfiWikiContainer.install_fontawesome","title":"install_fontawesome()","text":"

install fontawesome to this container

Source code in profiwiki/docker.py
    def install_fontawesome(self):\n        \"\"\"\n        install fontawesome to this container\n        \"\"\"\n        script = \"\"\"#!/bin/bash\n# install fontawesome\n# WF 2023-01-25\nversion=6.4.0\n#version=5.15.4\n#version=4.7.0\nzip_url=https://github.com/FortAwesome/Font-Awesome/releases/download/$version/fontawesome-free-$version-desktop.zip\n#https://github.com/FortAwesome/Font-Awesome/releases/download/5.15.4/fontawesome-free-5.15.4-desktop.zip\n\ncd /var/www\n#curl https://use.fontawesome.com/releases/$version/fontawesome-free-$version-web.zip -o fontawesome.zip\ncurl --location $zip_url -o fontawesome.zip\nunzip -o fontawesome.zip\nln -s -f fontawesome-free-$version-desktop fontawesome\nchown -R www-data.www-data fontawesome\ncd fontawesome\nln -s svgs/solid svg\ncat << EOS > /etc/apache2/conf-available/font-awesome.conf\nAlias /font-awesome /var/www/fontawesome\n<Directory /var/www/fontawesome>\n  Options Indexes FollowSymLinks MultiViews\n  Require all granted\n</Directory>\nEOS\na2enconf font-awesome\n\"\"\"\n        script_path = \"/root/install_fontawesome\"\n        self.install_and_run_script(script, script_path)\n        try:\n            self.dc.container.execute([\"service\", \"apache2\", \"restart\"])\n        except DockerException as e:\n            # we expect a SIGTERM\n            if not e.return_code == 143:\n                raise e\n        pass\n
"},{"location":"#profiwiki.docker.ProfiWikiContainer.install_plantuml","title":"install_plantuml()","text":"

install plantuml to this container

Source code in profiwiki/docker.py
    def install_plantuml(self):\n        \"\"\"\n        install plantuml to this container\n        \"\"\"\n        script = \"\"\"#!/bin/bash\n# install plantuml\n# WF 2023-05-01\napt-get update\napt-get install -y plantuml\n\"\"\"\n        # https://gabrieldemarmiesse.github.io/python-on-whales/docker_objects/containers/\n        script_path = \"/root/install_plantuml.sh\"\n        self.install_and_run_script(script, script_path)\n        pass\n
"},{"location":"#profiwiki.docker.ProfiWikiContainer.killremove","title":"killremove(volumes=False)","text":"

kill and remove me

Parameters:

Name Type Description Default volumes(bool)

if True remove anonymous volumes associated with the container, default=True (to avoid e.g. passwords to get remembered / stuck

required Source code in profiwiki/docker.py
def killremove(self, volumes: bool = False):\n    \"\"\"\n    kill and remove me\n\n    Args:\n        volumes(bool): if True remove anonymous volumes associated with the container, default=True (to avoid e.g. passwords to get remembered / stuck\n    \"\"\"\n    if self.dc:\n        self.log_action(\"killing and removing\")\n        self.dc.container.kill()\n        self.dc.container.remove(volumes=volumes)\n
"},{"location":"#profiwiki.docker.ProfiWikiContainer.log_action","title":"log_action(action)","text":"

log the given action

Parameters:

Name Type Description Default action(str)

the d

required Source code in profiwiki/docker.py
def log_action(self, action: str):\n    \"\"\"\n    log the given action\n\n    Args:\n        action(str): the d\n    \"\"\"\n    if self.dc:\n        print(f\"{action} {self.dc.kind} {self.dc.name}\", flush=True)\n    else:\n        print(f\"{action}\", flush=True)\n
"},{"location":"#profiwiki.docker.ProfiWikiContainer.start_cron","title":"start_cron()","text":"

Starting periodic command scheduler: cron.

Source code in profiwiki/docker.py
def start_cron(self):\n    \"\"\"\n    Starting periodic command scheduler: cron.\n    \"\"\"\n    self.dc.container.execute([\"/usr/sbin/service\", \"cron\", \"start\"], tty=True)\n
"},{"location":"#profiwiki.docker.ProfiWikiContainer.upload","title":"upload(text, path)","text":"

upload the given text to the given path

Source code in profiwiki/docker.py
def upload(self, text: str, path: str):\n    \"\"\"\n    upload the given text to the given path\n    \"\"\"\n    with tempfile.NamedTemporaryFile() as tmp:\n        self.log_action(f\"uploading {tmp.name} as {path} to \")\n        with open(tmp.name, \"w\") as text_file:\n            text_file.write(text)\n        self.dc.container.copy_to(tmp.name, path)\n
"},{"location":"#profiwiki.patch","title":"patch","text":"

Created on 2023-04-09

@author: wf

"},{"location":"#profiwiki.patch.Patch","title":"Patch","text":"

A class for patch a text file

Source code in profiwiki/patch.py
class Patch:\n    \"\"\"\n    A class for patch a text file\n    \"\"\"\n\n    def __init__(self, file_path: str):\n        \"\"\"\n        Initializes a Patch instance with the file path file to be patched.\n\n        Args:\n            file_path (str): The file path of the PHP file to be patched.\n        \"\"\"\n        self.lines = []\n        self.file_path = file_path\n        # https://stackoverflow.com/a/3277516/1497139\n        with open(self.file_path, \"r\", encoding=\"UTF-8\") as file:\n            while line := file.readline():\n                self.lines.append(line.rstrip())\n\n    def save(self):\n        \"\"\"\n        save my lines\n        \"\"\"\n        with open(self.file_path, \"w\") as f:\n            for line in self.lines:\n                f.write(f\"{line}\\n\")\n\n    def patch_mediawiki_config_var(self, var_name: str, var_value: str) -> None:\n        \"\"\"\n        Patches a MediaWiki configuration variable in the PHP file with the given name and value.\n\n        Args:\n            var_name (str): The name of the configuration variable to be patched.\n            var_value (str): The new value to be set for the configuration variable.\n\n        Returns:\n            None\n        \"\"\"\n        # Define the regex pattern to match the configuration variable\n        pattern = r\"\\$wg\" + re.escape(var_name) + r\"\\s*=\\s*[^\\n]+\"\n\n        # Define the replacement string with the updated value\n        replacement = f\"$wg{var_name} = {var_value};\"\n\n        # Use fileinput to replace the matched line in the file\n        for i, line in enumerate(self.lines):\n            new_line = re.sub(pattern, replacement, line)\n            self.lines[i] = new_line\n\n    def add_text(self, text: str, avoid_duplication: bool = True):\n        \"\"\"\n        Adds text avoiding duplication if specified\n\n        Args:\n            text (str): the text to add\n            avoid_duplication(bool): if True avoid duplication of existing lines\n        \"\"\"\n        new_lines = text.split(\"\\n\")\n        for new_line in new_lines:\n            do_add = True\n            if avoid_duplication:\n                do_add = not new_line in self.lines\n            if do_add:\n                self.lines.append(new_line)\n
"},{"location":"#profiwiki.patch.Patch.__init__","title":"__init__(file_path)","text":"

Initializes a Patch instance with the file path file to be patched.

Parameters:

Name Type Description Default file_path str

The file path of the PHP file to be patched.

required Source code in profiwiki/patch.py
def __init__(self, file_path: str):\n    \"\"\"\n    Initializes a Patch instance with the file path file to be patched.\n\n    Args:\n        file_path (str): The file path of the PHP file to be patched.\n    \"\"\"\n    self.lines = []\n    self.file_path = file_path\n    # https://stackoverflow.com/a/3277516/1497139\n    with open(self.file_path, \"r\", encoding=\"UTF-8\") as file:\n        while line := file.readline():\n            self.lines.append(line.rstrip())\n
"},{"location":"#profiwiki.patch.Patch.add_text","title":"add_text(text, avoid_duplication=True)","text":"

Adds text avoiding duplication if specified

Parameters:

Name Type Description Default text str

the text to add

required avoid_duplication(bool)

if True avoid duplication of existing lines

required Source code in profiwiki/patch.py
def add_text(self, text: str, avoid_duplication: bool = True):\n    \"\"\"\n    Adds text avoiding duplication if specified\n\n    Args:\n        text (str): the text to add\n        avoid_duplication(bool): if True avoid duplication of existing lines\n    \"\"\"\n    new_lines = text.split(\"\\n\")\n    for new_line in new_lines:\n        do_add = True\n        if avoid_duplication:\n            do_add = not new_line in self.lines\n        if do_add:\n            self.lines.append(new_line)\n
"},{"location":"#profiwiki.patch.Patch.patch_mediawiki_config_var","title":"patch_mediawiki_config_var(var_name, var_value)","text":"

Patches a MediaWiki configuration variable in the PHP file with the given name and value.

Parameters:

Name Type Description Default var_name str

The name of the configuration variable to be patched.

required var_value str

The new value to be set for the configuration variable.

required

Returns:

Type Description None

None

Source code in profiwiki/patch.py
def patch_mediawiki_config_var(self, var_name: str, var_value: str) -> None:\n    \"\"\"\n    Patches a MediaWiki configuration variable in the PHP file with the given name and value.\n\n    Args:\n        var_name (str): The name of the configuration variable to be patched.\n        var_value (str): The new value to be set for the configuration variable.\n\n    Returns:\n        None\n    \"\"\"\n    # Define the regex pattern to match the configuration variable\n    pattern = r\"\\$wg\" + re.escape(var_name) + r\"\\s*=\\s*[^\\n]+\"\n\n    # Define the replacement string with the updated value\n    replacement = f\"$wg{var_name} = {var_value};\"\n\n    # Use fileinput to replace the matched line in the file\n    for i, line in enumerate(self.lines):\n        new_line = re.sub(pattern, replacement, line)\n        self.lines[i] = new_line\n
"},{"location":"#profiwiki.patch.Patch.save","title":"save()","text":"

save my lines

Source code in profiwiki/patch.py
def save(self):\n    \"\"\"\n    save my lines\n    \"\"\"\n    with open(self.file_path, \"w\") as f:\n        for line in self.lines:\n            f.write(f\"{line}\\n\")\n
"},{"location":"#profiwiki.profiwiki_cmd","title":"profiwiki_cmd","text":"

Created on 2023-04-01

@author: wf

"},{"location":"#profiwiki.profiwiki_cmd.ProfiWikiCmd","title":"ProfiWikiCmd","text":"

ProfiWiki command line

Source code in profiwiki/profiwiki_cmd.py
class ProfiWikiCmd:\n    \"\"\"\n    ProfiWiki command line\n    \"\"\"\n\n    def get_arg_parser(\n        self, config: MwClusterConfig, description: str, version_msg: str\n    ) -> ArgumentParser:\n        \"\"\"\n        Setup command line argument parser\n\n        Args:\n            config(MwClusterConfig): the mediawiki cluster configuration\n            description(str): the description\n            version_msg(str): the version message\n\n        Returns:\n            ArgumentParser: the argument parser\n        \"\"\"\n        # script_path=Path(__file__)\n        parser = ArgumentParser(\n            description=description, formatter_class=RawDescriptionHelpFormatter\n        )\n        config.addArgs(parser)\n        parser.add_argument(\n            \"--about\",\n            help=\"show about info [default: %(default)s]\",\n            action=\"store_true\",\n        )\n        parser.add_argument(\n            \"--apache\", help=\"generate apache configuration\", action=\"store_true\"\n        )\n        parser.add_argument(\n            \"--all\", help=\"do all necessary steps for a full setup\", action=\"store_true\"\n        )\n        parser.add_argument(\"--bash\", help=\"bash into container\", action=\"store_true\")\n        parser.add_argument(\"--create\", action=\"store_true\", help=\"create the wiki\")\n        parser.add_argument(\"--check\", action=\"store_true\", help=\"check the wiki\")\n        parser.add_argument(\n            \"--update\",\n            action=\"store_true\",\n            help=\"start the update script -e.g. to fix SMW key\",\n        )\n        parser.add_argument(\"--cron\", action=\"store_true\", help=\"start cron service\")\n        parser.add_argument(\n            \"--down\",\n            action=\"store_true\",\n            help=\"shutdown the wiki [default: %(default)s]\",\n        )\n        parser.add_argument(\n            \"--patch\",\n            action=\"store_true\",\n            help=\"apply LocalSettings.php patches [default: %(default)s]\",\n        )\n        parser.add_argument(\n            \"--list\",\n            action=\"store_true\",\n            help=\"list the available profi wikis [default: %(default)s]\",\n        )\n        parser.add_argument(\n            \"-fa\", \"--fontawesome\", action=\"store_true\", help=\"install fontawesome\"\n        )\n        parser.add_argument(\n            \"-wuc\", \"--wikiuser_check\", action=\"store_true\", help=\"check wikiuser\"\n        )\n        parser.add_argument(\n            \"-pu\", \"--plantuml\", action=\"store_true\", help=\"install plantuml\"\n        )\n        parser.add_argument(\n            \"-i\", \"--info\", help=\"show system info\", action=\"store_true\"\n        )\n        parser.add_argument(\"-V\", \"--version\", action=\"version\", version=version_msg)\n        # debug args\n        parser.add_argument(\"--debugServer\", help=\"remote debug Server\")\n        parser.add_argument(\n            \"--debugPort\", type=int, help=\"remote debug Port\", default=5678\n        )\n        parser.add_argument(\n            \"--debugPathMapping\",\n            nargs=\"+\",\n            help=\"remote debug Server path mapping - needs two arguments 1st: remotePath 2nd: local Path\",\n        )\n        return parser\n\n    def optional_debug(self, args):\n        \"\"\"\n        start the remote debugger if the arguments specify so\n\n        Args:\n            args: The command line arguments\n        \"\"\"\n        if args.debugServer:\n            import pydevd\n            import pydevd_file_utils\n\n            print(args.debugPathMapping, flush=True)\n            if args.debugPathMapping:\n                if len(args.debugPathMapping) == 2:\n                    remotePath = args.debugPathMapping[\n                        0\n                    ]  # path on the remote debugger side\n                    localPath = args.debugPathMapping[\n                        1\n                    ]  # path on the local machine where the code runs\n                    MY_PATHS_FROM_ECLIPSE_TO_PYTHON = [\n                        (remotePath, localPath),\n                    ]\n                    pydevd_file_utils.setup_client_server_paths(\n                        MY_PATHS_FROM_ECLIPSE_TO_PYTHON\n                    )  # os.environ[\"PATHS_FROM_ECLIPSE_TO_PYTHON\"]='[[\"%s\", \"%s\"]]' % (remotePath,localPath)  # print(\"trying to debug with PATHS_FROM_ECLIPSE_TO_PYTHON=%s\" % os.environ[\"PATHS_FROM_ECLIPSE_TO_PYTHON\"]);\n\n            pydevd.settrace(\n                args.debugServer,\n                port=args.debugPort,\n                stdoutToServer=True,\n                stderrToServer=True,\n            )\n            print(\"command line args are: %s\" % str(sys.argv))\n            pass\n
"},{"location":"#profiwiki.profiwiki_cmd.ProfiWikiCmd.get_arg_parser","title":"get_arg_parser(config, description, version_msg)","text":"

Setup command line argument parser

Parameters:

Name Type Description Default config(MwClusterConfig)

the mediawiki cluster configuration

required description(str)

the description

required version_msg(str)

the version message

required

Returns:

Name Type Description ArgumentParser ArgumentParser

the argument parser

Source code in profiwiki/profiwiki_cmd.py
def get_arg_parser(\n    self, config: MwClusterConfig, description: str, version_msg: str\n) -> ArgumentParser:\n    \"\"\"\n    Setup command line argument parser\n\n    Args:\n        config(MwClusterConfig): the mediawiki cluster configuration\n        description(str): the description\n        version_msg(str): the version message\n\n    Returns:\n        ArgumentParser: the argument parser\n    \"\"\"\n    # script_path=Path(__file__)\n    parser = ArgumentParser(\n        description=description, formatter_class=RawDescriptionHelpFormatter\n    )\n    config.addArgs(parser)\n    parser.add_argument(\n        \"--about\",\n        help=\"show about info [default: %(default)s]\",\n        action=\"store_true\",\n    )\n    parser.add_argument(\n        \"--apache\", help=\"generate apache configuration\", action=\"store_true\"\n    )\n    parser.add_argument(\n        \"--all\", help=\"do all necessary steps for a full setup\", action=\"store_true\"\n    )\n    parser.add_argument(\"--bash\", help=\"bash into container\", action=\"store_true\")\n    parser.add_argument(\"--create\", action=\"store_true\", help=\"create the wiki\")\n    parser.add_argument(\"--check\", action=\"store_true\", help=\"check the wiki\")\n    parser.add_argument(\n        \"--update\",\n        action=\"store_true\",\n        help=\"start the update script -e.g. to fix SMW key\",\n    )\n    parser.add_argument(\"--cron\", action=\"store_true\", help=\"start cron service\")\n    parser.add_argument(\n        \"--down\",\n        action=\"store_true\",\n        help=\"shutdown the wiki [default: %(default)s]\",\n    )\n    parser.add_argument(\n        \"--patch\",\n        action=\"store_true\",\n        help=\"apply LocalSettings.php patches [default: %(default)s]\",\n    )\n    parser.add_argument(\n        \"--list\",\n        action=\"store_true\",\n        help=\"list the available profi wikis [default: %(default)s]\",\n    )\n    parser.add_argument(\n        \"-fa\", \"--fontawesome\", action=\"store_true\", help=\"install fontawesome\"\n    )\n    parser.add_argument(\n        \"-wuc\", \"--wikiuser_check\", action=\"store_true\", help=\"check wikiuser\"\n    )\n    parser.add_argument(\n        \"-pu\", \"--plantuml\", action=\"store_true\", help=\"install plantuml\"\n    )\n    parser.add_argument(\n        \"-i\", \"--info\", help=\"show system info\", action=\"store_true\"\n    )\n    parser.add_argument(\"-V\", \"--version\", action=\"version\", version=version_msg)\n    # debug args\n    parser.add_argument(\"--debugServer\", help=\"remote debug Server\")\n    parser.add_argument(\n        \"--debugPort\", type=int, help=\"remote debug Port\", default=5678\n    )\n    parser.add_argument(\n        \"--debugPathMapping\",\n        nargs=\"+\",\n        help=\"remote debug Server path mapping - needs two arguments 1st: remotePath 2nd: local Path\",\n    )\n    return parser\n
"},{"location":"#profiwiki.profiwiki_cmd.ProfiWikiCmd.optional_debug","title":"optional_debug(args)","text":"

start the remote debugger if the arguments specify so

Parameters:

Name Type Description Default args

The command line arguments

required Source code in profiwiki/profiwiki_cmd.py
def optional_debug(self, args):\n    \"\"\"\n    start the remote debugger if the arguments specify so\n\n    Args:\n        args: The command line arguments\n    \"\"\"\n    if args.debugServer:\n        import pydevd\n        import pydevd_file_utils\n\n        print(args.debugPathMapping, flush=True)\n        if args.debugPathMapping:\n            if len(args.debugPathMapping) == 2:\n                remotePath = args.debugPathMapping[\n                    0\n                ]  # path on the remote debugger side\n                localPath = args.debugPathMapping[\n                    1\n                ]  # path on the local machine where the code runs\n                MY_PATHS_FROM_ECLIPSE_TO_PYTHON = [\n                    (remotePath, localPath),\n                ]\n                pydevd_file_utils.setup_client_server_paths(\n                    MY_PATHS_FROM_ECLIPSE_TO_PYTHON\n                )  # os.environ[\"PATHS_FROM_ECLIPSE_TO_PYTHON\"]='[[\"%s\", \"%s\"]]' % (remotePath,localPath)  # print(\"trying to debug with PATHS_FROM_ECLIPSE_TO_PYTHON=%s\" % os.environ[\"PATHS_FROM_ECLIPSE_TO_PYTHON\"]);\n\n        pydevd.settrace(\n            args.debugServer,\n            port=args.debugPort,\n            stdoutToServer=True,\n            stderrToServer=True,\n        )\n        print(\"command line args are: %s\" % str(sys.argv))\n        pass\n
"},{"location":"#profiwiki.profiwiki_cmd.main","title":"main(argv=None)","text":"

main program.

Source code in profiwiki/profiwiki_cmd.py
def main(argv=None):  # IGNORE:C0111\n    \"\"\"main program.\"\"\"\n\n    if argv is None:\n        argv = sys.argv[1:]\n\n    program_name = \"profiwiki\"\n    program_version = f\"v{Version.version}\"\n    program_build_date = str(Version.date)\n    program_version_message = f\"{program_name} ({program_version},{program_build_date})\"\n\n    args = None\n    try:\n        pw = ProfiWiki()\n        pw_cmd = ProfiWikiCmd()\n        parser = pw_cmd.get_arg_parser(\n            config=pw.config,\n            description=Version.license,\n            version_msg=program_version_message,\n        )\n        args = parser.parse_args(argv)\n        if len(argv) < 1:\n            parser.print_usage()\n            sys.exit(1)\n        if args.about:\n            print(program_version_message)\n            print(f\"see {Version.doc_url}\")\n            webbrowser.open(Version.doc_url)\n        pw_cmd.optional_debug(args)\n        if args.info:\n            info = pw.system_info()\n            print(info)\n        pw.work(args)\n\n    except KeyboardInterrupt:\n        ###\n        # handle keyboard interrupt\n        # ###\n        return 1\n    except Exception as e:\n        if DEBUG:\n            raise e\n        indent = len(program_name) * \" \"\n        sys.stderr.write(program_name + \": \" + repr(e) + \"\\n\")\n        sys.stderr.write(indent + \"  for help use --help\")\n        if args is None:\n            print(\"args could not be parsed\")\n        elif args.debug:\n            print(traceback.format_exc())\n        return 2\n
"},{"location":"#profiwiki.profiwiki_core","title":"profiwiki_core","text":"

Created on 2023-04-01

@author: wf

"},{"location":"#profiwiki.profiwiki_core.ProfiWiki","title":"ProfiWiki","text":"

ProfiWiki

Source code in profiwiki/profiwiki_core.py
class ProfiWiki:\n    \"\"\"\n    ProfiWiki\n    \"\"\"\n\n    def __init__(\n        self,\n        prefix: str = \"pw\",\n        smw_version=\"4.1.3\",\n        mw_version=\"1.39.7\",\n        port: int = 9079,\n    ):\n        \"\"\"\n        constructor\n        \"\"\"\n        self.os_name = platform.system()\n        self.os_uname = os.uname()\n        self.os_release = platform.release()\n        self.args = None\n        self.config = MwClusterConfig()\n        self.config.smw_version = smw_version\n        self.config.random_password = False\n        self.config.prefix = prefix\n        self.config.base_port = port\n        self.config.sql_port = port - 1\n        self.config.port = port\n        self.config.versions = [mw_version]\n        self.config.version=mw_version\n        self.config.container_base_name = \"pw\"\n        self.config.extensionNameList = [\n            \"Admin Links\",\n            \"Diagrams\",\n            \"Graph\",\n            \"Header Tabs\",\n            \"ImageMap\",\n            \"ImageLink\",\n            \"MagicNoCache\",\n            \"Maps9\",\n            \"Mermaid\",\n            \"MsUpload\",\n            \"Nuke\",\n            \"Page Forms\",\n            \"ParserFunctions\",\n            \"PDFEmbed\",\n            \"Renameuser\",\n            \"Replace Text\",\n            \"Semantic Result Formats\",\n            \"SyntaxHighlight\",\n            \"Variables\",\n            \"UserFunctions\",\n            \"YouTube\"\n        ]\n        self.config.logo = \"https://wiki.bitplan.com/images/wiki/thumb/6/63/Profiwikiicon.png/96px-Profiwikiicon.png\"\n        self.config.__post_init__()\n        self.mwCluster = None\n        pass\n\n    def system_info(self) -> str:\n        \"\"\"\n        collect system information\n        \"\"\"\n        info = f\"\"\"os: {self.os_name}\"\"\"\n        if \"Darwin\" in info:\n            release, _version, _machine = platform.mac_ver()\n            info += f\" MacOS {release}\"\n        else:\n            info += f\"{self.os_release}\"\n        return info\n\n    def work(self, args):\n        \"\"\"\n        work as instructed by the arguments\n\n        Args:\n            args(Namespace): the command line arguments\n        \"\"\"\n        self.config.fromArgs(args)\n        # make sure the wikiId is set from the container base name\n        config_path = self.config.get_config_path()\n        if os.path.isfile(config_path) and not self.config.forceRebuild:\n            # reload the previous configuration e.g. based on container_name only\n            previous_config = self.config.load(config_path)\n            if self.config.verbose:\n                print(f\"ProfiWiki with previous configuration from {config_path}...\")\n            self.config = previous_config\n        self.config.wikiId = self.config.container_base_name\n        if args.bash:\n            cmd = f\"docker exec -it {self.config.container_base_name}-mw /bin/bash\"\n            print(cmd)\n            return\n        mwApp = self.getMwApp(withGenerate=args.forceRebuild)\n        if self.config.verbose:\n            print(\n                f\"ProfiWiki {mwApp.config.container_base_name} using port {mwApp.config.port} sqlport {mwApp.config.sql_port}\"\n            )\n        if args.force_user:\n            mwApp.createWikiUser(store=True)\n        if args.all:\n            self.create(mwApp, args.forceRebuild)\n            pmw, _pdb = self.getProfiWikiContainers(mwApp)\n            pmw.install_fontawesome()\n            pmw.install_plantuml()\n            self.patch(pmw)\n            self.update(mwApp)\n            pmw.start_cron()\n        if args.wikiuser_check:\n            self.check_wikiuser(mwApp)\n        if args.apache:\n            apache_config = self.apache_config(mwApp)\n            print(apache_config)\n        if args.create:\n            self.create(mwApp, args.forceRebuild)\n        if args.check:\n            self.check(mwApp)\n        if args.down:\n            self.down(mwApp, args.forceRebuild)\n        if args.list:\n            self.list(mwApp)\n        if args.plantuml or args.fontawesome or args.cron or args.patch:\n            pmw, _pdb = self.getProfiWikiContainers(mwApp)\n            if args.plantuml:\n                pmw.install_plantuml()\n            if args.fontawesome:\n                pmw.install_fontawesome()\n            if args.cron:\n                pmw.start_cron()\n            if args.patch:\n                self.patch(pmw)\n        if args.update:\n            self.update(mwApp)\n\n    def getMwCluster(self, withGenerate: bool = True) -> MediaWikiCluster:\n        \"\"\"\n        get a mediawiki Cluster for my configuration\n\n        Args:\n            withGenerate(bool): if True regenerate the configuration files\n\n        Returns:\n            MediaWikiCluster: the MediaWiki Cluser\n        \"\"\"\n        if self.mwCluster is not None:\n            return self.mwCluster\n        mwCluster = MediaWikiCluster(config=self.config)\n        # generate\n        mwCluster.createApps(withGenerate=withGenerate)\n        self.mwCluster = mwCluster\n        return mwCluster\n\n    def getMwApp(self, withGenerate: bool = True):\n        \"\"\"\n        get my mediawiki Docker application\n        \"\"\"\n        mwCluster = self.getMwCluster(withGenerate)\n        if not self.config.version in mwCluster.apps:\n            raise Exception(f\"Mediawiki version {self.config.version} missing {mwCluster.apps.keys()}\")\n        mwApp = mwCluster.apps[self.config.version]\n        return mwApp\n\n    def getProfiWikiContainers(self, mwApp: DockerApplication):\n        \"\"\"\n        get the two containers - for mediawiki and the database\n\n        Args:\n            mwApp(DockerApplication): the MediaWiki Docker Application\n\n        Returns:\n            Tuple(ProfiWikiContainer,ProfiWikiContainer): MediaWiki, Database\n        \"\"\"\n        mw, db = mwApp.getContainers()\n        pmw = ProfiWikiContainer(mw)\n        pdb = ProfiWikiContainer(db)\n        return pmw, pdb\n\n    def patch(self, pwc: ProfiWikiContainer):\n        \"\"\"\n        apply profi wiki patches to the given ProfiWikiContainer\n        \"\"\"\n        if not pwc.dc:\n            raise (\"no container to apply patch\")\n        ls_path = \"/var/www/html/LocalSettings.php\"\n        timestamp = datetime.datetime.utcnow().strftime(\"%Y-%m-%d\")\n        with tempfile.NamedTemporaryFile(\n            mode=\"w\", prefix=\"LocalSettings_\", suffix=\".php\"\n        ) as ls_file:\n            pwc.log_action(f\"patching {ls_file.name}\")\n            pwc.dc.container.copy_from(ls_path, ls_file.name)\n            patch = Patch(file_path=ls_file.name)\n            lines = f\"\"\"// modified by profiwiki \n// use WikiEditor e.g. for MsUpload\nwfLoadExtension( 'WikiEditor' );\n# make this an intranet - comment out if you want this to be a public wiki\n# The following permissions were set based on your choice in the installer\n$wgGroupPermissions['*']['createaccount'] = false;\n$wgGroupPermissions['*']['edit'] = false;\n$wgGroupPermissions['*']['read'] = false;\n# Allow properties in Templates\n$smwgNamespacesWithSemanticLinks[NS_TEMPLATE] = true;\n# WF 2015-01-20\n# allow string functions - needed for Template:Link\n$wgPFEnableStringFunctions=true;\n// allow raw HTML \n$wgRawHtml = true;\n// allow images\n$wgAllowImageTag=true;\n// InstantCommons allows wiki to use images from https://commons.wikimedia.org\n$wgUseInstantCommons = true;\n// avoid showing (expected) deprecation warnings\nerror_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE);\n# # add support for special properties\n# see https://www.semantic-mediawiki.org/wiki/Help:$smwgPageSpecialProperties\n# Modification date\n$smwgPageSpecialProperties[] = '_MDAT';\n# Creation date\n$smwgPageSpecialProperties[] = '_CDAT';\n# Is a new page\n$smwgPageSpecialProperties[] = '_NEWP';\n# Last editor is\n$smwgPageSpecialProperties[] = '_LEDT';\n# Media type\n$smwgPageSpecialProperties[] = '_MEDIA';\n# MIME type\n$smwgPageSpecialProperties[] = '_MIME';\n// https://www.mediawiki.org/wiki/Extension:UserFunctions\n$wgUFEnabledPersonalDataFunctions = ['ip','nickname','realname','useremail','username',];\n// allow user functions in main mediawiki space\n$wgUFAllowedNamespaces[NS_MAIN] = true;\n# increase query limit\n$smwgQMaxLimit = 20000;\n//Default width for the PDF object container.\n$wgPdfEmbed['width'] = 800;\n//Default height for the PDF object container.\n$wgPdfEmbed['height'] = 1090;\n//Allow user the usage of the tag \n$wgGroupPermissions['*']['embed_pdf'] = true;\n// config parameters for MsUpload\n// https://www.mediawiki.org/wiki/Extension:MsUpload\n$wgMSU_useDragDrop = true; // Should the drag & drop area be shown? (Not set by default)\n$wgMSU_showAutoCat = true; // Files uploaded while editing a category page will be added to that category\n$wgMSU_checkAutoCat = true; // Whether the checkbox for adding a category to a page is checked by default\n$wgMSU_useMsLinks = false; // Insert links in Extension:MsLinks style?\n$wgMSU_confirmReplace = true; // Show the \"Replace file?\" checkbox\n$wgMSU_imgParams = '400px'; // Default image parameters, for example \"thumb|200px\"\n$wgMSU_uploadsize = '100mb'; // Max upload size through MsUpload\n// general parameters for MsUpload\n$wgEnableWriteAPI = true; // Enable the API\n$wgEnableUploads = true; // Enable uploads\n$wgAllowJavaUploads = true; // Solves problem with Office 2007 and newer files (docx, xlsx, etc.)\n$wgGroupPermissions['user']['upload'] = true; // Allow regular users to upload files\n# add more file upload options\n$wgGroupPermissions['user']['upload_by_url'] = true;\n$wgAllowCopyUploads = true;\n$wgCopyUploadsFromSpecialUpload = true;\n# http://www.mediawiki.org/wiki/Manual:Configuring_file_uploads/de\n$wgFileExtensions = array_merge($wgFileExtensions, array('doc', 'gcode',\n'gpx','htm','html','jscad','jpg','pdf','ppt','docx', 'docxm','xlsx','xlsm','mp3','mp4','odp','otp','pptx', 'pptm','reqif','reqifz','rtf','rythm'\n,'scad','sh','stl','svg','vcf','vim','uew','xls','xml','zip'));\n# allow html\n$wgVerifyMimeType=false;\n# disable upload script checks ...\n$wgDisableUploadScriptChecks = true;\n\"\"\"\n            patch.add_text(lines)\n            patch.save()\n            pwc.dc.container.copy_to(ls_file.name, ls_path)\n\n    def update(self, mwApp):\n        \"\"\"\n        run the update script\n        \"\"\"\n        mwApp.execute(\"/root/update.sh\")\n\n    def check(self, mwApp):\n        \"\"\"\n        check\n        \"\"\"\n        mwApp.check()\n\n    def create(self, mwApp, forceRebuild: bool = False):\n        \"\"\"\n        create a profiwiki mediawiki\n        \"\"\"\n        mwApp.start(forceRebuild=forceRebuild)\n\n    def down(self, mwApp, forceRebuild: bool = False):\n        \"\"\"\n        shut down the profiwiki base mediawiki\n        \"\"\"\n        mwApp.down(forceRebuild=forceRebuild)\n\n    def list(self, mwApp):\n        \"\"\"\n        list the profi wikis\n        \"\"\"\n        print(json.dumps(mwApp.config.as_dict(), indent=2))\n        pass\n\n    def check_wikiuser(self, mwApp: DockerApplication):\n        \"\"\" \"\"\"\n        print(f\"Checking WikiUser ... for {mwApp.config.container_base_name}\")\n        wikiUsers = WikiUser.getWikiUsers(lenient=True)\n        if not mwApp.config.wikiId:\n            print(\"no WikiId configured\")\n            return\n        if not mwApp.config.wikiId in wikiUsers:\n            print(f\"no wikiUser for wikiId {mwApp.config.wikiId} found\")\n            return\n        wikiUser = wikiUsers[mwApp.config.wikiId]\n        if mwApp.config.password != wikiUser.getPassword():\n            print(f\"configured password is different then {mwApp.config.wikiId}\")\n        else:\n            print(\n                f\"wikiUser for wikiId {mwApp.config.wikiId} is available and password as configured\"\n            )\n        pass\n\n    def apache_config(self, mwApp: DockerApplication) -> str:\n        \"\"\"\n        get the apache configuration for the given mediawiki Docker application\n\n        Args:\n            mwApp(DockerApplication): the docker application to generate the configuration for\n        \"\"\"\n        config = mwApp.config\n        apache_config = f\"\"\"<VirtualHost *:80 >\n    # The ServerName directive sets the request scheme, hostname and port that\n    # the server uses to identify itself. This is used when creating\n    # redirection URLs. In the context of virtual hosts, the ServerName\n    # specifies what hostname must appear in the request's Host: header to\n    # match this virtual host. For the default virtual host (this file) this\n    # value is not decisive as it is used as a last resort host regardless.\n    # However, you must set it for any further virtual host explicitly.\n    ServerName {config.host}\n\n    ServerAdmin webmaster@{config.host}\n    #DocumentRoot /var/www/html\n\n    # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,\n    # error, crit, alert, emerg.\n    # It is also possible to configure the loglevel for particular\n    # modules, e.g.\n    #LogLevel info ssl:warn\n\n    ErrorLog ${{APACHE_LOG_DIR}}/{config.container_base_name}_error.log\n    CustomLog ${{APACHE_LOG_DIR}}/{config.container_base_name}_access.log combined\n\n    # For most configuration files from conf-available/, which are\n    # enabled or disabled at a global level, it is possible to\n    # include a line for only one particular virtual host. For example the\n    # following line enables the CGI configuration for this host only\n    # after it has been globally disabled with \"a2disconf\".\n    #Include conf-available/serve-cgi-bin.conf\n\n    # Mediawiki installations \n    ProxyPass / http://localhost:{config.port}/ \n    ProxyPassReverse / http://localhost:{config.port}/\n</VirtualHost>\"\"\"\n        return apache_config\n
"},{"location":"#profiwiki.profiwiki_core.ProfiWiki.__init__","title":"__init__(prefix='pw', smw_version='4.1.3', mw_version='1.39.7', port=9079)","text":"

constructor

Source code in profiwiki/profiwiki_core.py
def __init__(\n    self,\n    prefix: str = \"pw\",\n    smw_version=\"4.1.3\",\n    mw_version=\"1.39.7\",\n    port: int = 9079,\n):\n    \"\"\"\n    constructor\n    \"\"\"\n    self.os_name = platform.system()\n    self.os_uname = os.uname()\n    self.os_release = platform.release()\n    self.args = None\n    self.config = MwClusterConfig()\n    self.config.smw_version = smw_version\n    self.config.random_password = False\n    self.config.prefix = prefix\n    self.config.base_port = port\n    self.config.sql_port = port - 1\n    self.config.port = port\n    self.config.versions = [mw_version]\n    self.config.version=mw_version\n    self.config.container_base_name = \"pw\"\n    self.config.extensionNameList = [\n        \"Admin Links\",\n        \"Diagrams\",\n        \"Graph\",\n        \"Header Tabs\",\n        \"ImageMap\",\n        \"ImageLink\",\n        \"MagicNoCache\",\n        \"Maps9\",\n        \"Mermaid\",\n        \"MsUpload\",\n        \"Nuke\",\n        \"Page Forms\",\n        \"ParserFunctions\",\n        \"PDFEmbed\",\n        \"Renameuser\",\n        \"Replace Text\",\n        \"Semantic Result Formats\",\n        \"SyntaxHighlight\",\n        \"Variables\",\n        \"UserFunctions\",\n        \"YouTube\"\n    ]\n    self.config.logo = \"https://wiki.bitplan.com/images/wiki/thumb/6/63/Profiwikiicon.png/96px-Profiwikiicon.png\"\n    self.config.__post_init__()\n    self.mwCluster = None\n    pass\n
"},{"location":"#profiwiki.profiwiki_core.ProfiWiki.apache_config","title":"apache_config(mwApp)","text":"

get the apache configuration for the given mediawiki Docker application

Parameters:

Name Type Description Default mwApp(DockerApplication)

the docker application to generate the configuration for

required Source code in profiwiki/profiwiki_core.py
    def apache_config(self, mwApp: DockerApplication) -> str:\n        \"\"\"\n        get the apache configuration for the given mediawiki Docker application\n\n        Args:\n            mwApp(DockerApplication): the docker application to generate the configuration for\n        \"\"\"\n        config = mwApp.config\n        apache_config = f\"\"\"<VirtualHost *:80 >\n    # The ServerName directive sets the request scheme, hostname and port that\n    # the server uses to identify itself. This is used when creating\n    # redirection URLs. In the context of virtual hosts, the ServerName\n    # specifies what hostname must appear in the request's Host: header to\n    # match this virtual host. For the default virtual host (this file) this\n    # value is not decisive as it is used as a last resort host regardless.\n    # However, you must set it for any further virtual host explicitly.\n    ServerName {config.host}\n\n    ServerAdmin webmaster@{config.host}\n    #DocumentRoot /var/www/html\n\n    # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,\n    # error, crit, alert, emerg.\n    # It is also possible to configure the loglevel for particular\n    # modules, e.g.\n    #LogLevel info ssl:warn\n\n    ErrorLog ${{APACHE_LOG_DIR}}/{config.container_base_name}_error.log\n    CustomLog ${{APACHE_LOG_DIR}}/{config.container_base_name}_access.log combined\n\n    # For most configuration files from conf-available/, which are\n    # enabled or disabled at a global level, it is possible to\n    # include a line for only one particular virtual host. For example the\n    # following line enables the CGI configuration for this host only\n    # after it has been globally disabled with \"a2disconf\".\n    #Include conf-available/serve-cgi-bin.conf\n\n    # Mediawiki installations \n    ProxyPass / http://localhost:{config.port}/ \n    ProxyPassReverse / http://localhost:{config.port}/\n</VirtualHost>\"\"\"\n        return apache_config\n
"},{"location":"#profiwiki.profiwiki_core.ProfiWiki.check","title":"check(mwApp)","text":"

check

Source code in profiwiki/profiwiki_core.py
def check(self, mwApp):\n    \"\"\"\n    check\n    \"\"\"\n    mwApp.check()\n
"},{"location":"#profiwiki.profiwiki_core.ProfiWiki.check_wikiuser","title":"check_wikiuser(mwApp)","text":"Source code in profiwiki/profiwiki_core.py
def check_wikiuser(self, mwApp: DockerApplication):\n    \"\"\" \"\"\"\n    print(f\"Checking WikiUser ... for {mwApp.config.container_base_name}\")\n    wikiUsers = WikiUser.getWikiUsers(lenient=True)\n    if not mwApp.config.wikiId:\n        print(\"no WikiId configured\")\n        return\n    if not mwApp.config.wikiId in wikiUsers:\n        print(f\"no wikiUser for wikiId {mwApp.config.wikiId} found\")\n        return\n    wikiUser = wikiUsers[mwApp.config.wikiId]\n    if mwApp.config.password != wikiUser.getPassword():\n        print(f\"configured password is different then {mwApp.config.wikiId}\")\n    else:\n        print(\n            f\"wikiUser for wikiId {mwApp.config.wikiId} is available and password as configured\"\n        )\n    pass\n
"},{"location":"#profiwiki.profiwiki_core.ProfiWiki.create","title":"create(mwApp, forceRebuild=False)","text":"

create a profiwiki mediawiki

Source code in profiwiki/profiwiki_core.py
def create(self, mwApp, forceRebuild: bool = False):\n    \"\"\"\n    create a profiwiki mediawiki\n    \"\"\"\n    mwApp.start(forceRebuild=forceRebuild)\n
"},{"location":"#profiwiki.profiwiki_core.ProfiWiki.down","title":"down(mwApp, forceRebuild=False)","text":"

shut down the profiwiki base mediawiki

Source code in profiwiki/profiwiki_core.py
def down(self, mwApp, forceRebuild: bool = False):\n    \"\"\"\n    shut down the profiwiki base mediawiki\n    \"\"\"\n    mwApp.down(forceRebuild=forceRebuild)\n
"},{"location":"#profiwiki.profiwiki_core.ProfiWiki.getMwApp","title":"getMwApp(withGenerate=True)","text":"

get my mediawiki Docker application

Source code in profiwiki/profiwiki_core.py
def getMwApp(self, withGenerate: bool = True):\n    \"\"\"\n    get my mediawiki Docker application\n    \"\"\"\n    mwCluster = self.getMwCluster(withGenerate)\n    if not self.config.version in mwCluster.apps:\n        raise Exception(f\"Mediawiki version {self.config.version} missing {mwCluster.apps.keys()}\")\n    mwApp = mwCluster.apps[self.config.version]\n    return mwApp\n
"},{"location":"#profiwiki.profiwiki_core.ProfiWiki.getMwCluster","title":"getMwCluster(withGenerate=True)","text":"

get a mediawiki Cluster for my configuration

Parameters:

Name Type Description Default withGenerate(bool)

if True regenerate the configuration files

required

Returns:

Name Type Description MediaWikiCluster MediaWikiCluster

the MediaWiki Cluser

Source code in profiwiki/profiwiki_core.py
def getMwCluster(self, withGenerate: bool = True) -> MediaWikiCluster:\n    \"\"\"\n    get a mediawiki Cluster for my configuration\n\n    Args:\n        withGenerate(bool): if True regenerate the configuration files\n\n    Returns:\n        MediaWikiCluster: the MediaWiki Cluser\n    \"\"\"\n    if self.mwCluster is not None:\n        return self.mwCluster\n    mwCluster = MediaWikiCluster(config=self.config)\n    # generate\n    mwCluster.createApps(withGenerate=withGenerate)\n    self.mwCluster = mwCluster\n    return mwCluster\n
"},{"location":"#profiwiki.profiwiki_core.ProfiWiki.getProfiWikiContainers","title":"getProfiWikiContainers(mwApp)","text":"

get the two containers - for mediawiki and the database

Parameters:

Name Type Description Default mwApp(DockerApplication)

the MediaWiki Docker Application

required

Returns:

Name Type Description Tuple (ProfiWikiContainer, ProfiWikiContainer)

MediaWiki, Database

Source code in profiwiki/profiwiki_core.py
def getProfiWikiContainers(self, mwApp: DockerApplication):\n    \"\"\"\n    get the two containers - for mediawiki and the database\n\n    Args:\n        mwApp(DockerApplication): the MediaWiki Docker Application\n\n    Returns:\n        Tuple(ProfiWikiContainer,ProfiWikiContainer): MediaWiki, Database\n    \"\"\"\n    mw, db = mwApp.getContainers()\n    pmw = ProfiWikiContainer(mw)\n    pdb = ProfiWikiContainer(db)\n    return pmw, pdb\n
"},{"location":"#profiwiki.profiwiki_core.ProfiWiki.list","title":"list(mwApp)","text":"

list the profi wikis

Source code in profiwiki/profiwiki_core.py
def list(self, mwApp):\n    \"\"\"\n    list the profi wikis\n    \"\"\"\n    print(json.dumps(mwApp.config.as_dict(), indent=2))\n    pass\n
"},{"location":"#profiwiki.profiwiki_core.ProfiWiki.patch","title":"patch(pwc)","text":"

apply profi wiki patches to the given ProfiWikiContainer

Source code in profiwiki/profiwiki_core.py
    def patch(self, pwc: ProfiWikiContainer):\n        \"\"\"\n        apply profi wiki patches to the given ProfiWikiContainer\n        \"\"\"\n        if not pwc.dc:\n            raise (\"no container to apply patch\")\n        ls_path = \"/var/www/html/LocalSettings.php\"\n        timestamp = datetime.datetime.utcnow().strftime(\"%Y-%m-%d\")\n        with tempfile.NamedTemporaryFile(\n            mode=\"w\", prefix=\"LocalSettings_\", suffix=\".php\"\n        ) as ls_file:\n            pwc.log_action(f\"patching {ls_file.name}\")\n            pwc.dc.container.copy_from(ls_path, ls_file.name)\n            patch = Patch(file_path=ls_file.name)\n            lines = f\"\"\"// modified by profiwiki \n// use WikiEditor e.g. for MsUpload\nwfLoadExtension( 'WikiEditor' );\n# make this an intranet - comment out if you want this to be a public wiki\n# The following permissions were set based on your choice in the installer\n$wgGroupPermissions['*']['createaccount'] = false;\n$wgGroupPermissions['*']['edit'] = false;\n$wgGroupPermissions['*']['read'] = false;\n# Allow properties in Templates\n$smwgNamespacesWithSemanticLinks[NS_TEMPLATE] = true;\n# WF 2015-01-20\n# allow string functions - needed for Template:Link\n$wgPFEnableStringFunctions=true;\n// allow raw HTML \n$wgRawHtml = true;\n// allow images\n$wgAllowImageTag=true;\n// InstantCommons allows wiki to use images from https://commons.wikimedia.org\n$wgUseInstantCommons = true;\n// avoid showing (expected) deprecation warnings\nerror_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE);\n# # add support for special properties\n# see https://www.semantic-mediawiki.org/wiki/Help:$smwgPageSpecialProperties\n# Modification date\n$smwgPageSpecialProperties[] = '_MDAT';\n# Creation date\n$smwgPageSpecialProperties[] = '_CDAT';\n# Is a new page\n$smwgPageSpecialProperties[] = '_NEWP';\n# Last editor is\n$smwgPageSpecialProperties[] = '_LEDT';\n# Media type\n$smwgPageSpecialProperties[] = '_MEDIA';\n# MIME type\n$smwgPageSpecialProperties[] = '_MIME';\n// https://www.mediawiki.org/wiki/Extension:UserFunctions\n$wgUFEnabledPersonalDataFunctions = ['ip','nickname','realname','useremail','username',];\n// allow user functions in main mediawiki space\n$wgUFAllowedNamespaces[NS_MAIN] = true;\n# increase query limit\n$smwgQMaxLimit = 20000;\n//Default width for the PDF object container.\n$wgPdfEmbed['width'] = 800;\n//Default height for the PDF object container.\n$wgPdfEmbed['height'] = 1090;\n//Allow user the usage of the tag \n$wgGroupPermissions['*']['embed_pdf'] = true;\n// config parameters for MsUpload\n// https://www.mediawiki.org/wiki/Extension:MsUpload\n$wgMSU_useDragDrop = true; // Should the drag & drop area be shown? (Not set by default)\n$wgMSU_showAutoCat = true; // Files uploaded while editing a category page will be added to that category\n$wgMSU_checkAutoCat = true; // Whether the checkbox for adding a category to a page is checked by default\n$wgMSU_useMsLinks = false; // Insert links in Extension:MsLinks style?\n$wgMSU_confirmReplace = true; // Show the \"Replace file?\" checkbox\n$wgMSU_imgParams = '400px'; // Default image parameters, for example \"thumb|200px\"\n$wgMSU_uploadsize = '100mb'; // Max upload size through MsUpload\n// general parameters for MsUpload\n$wgEnableWriteAPI = true; // Enable the API\n$wgEnableUploads = true; // Enable uploads\n$wgAllowJavaUploads = true; // Solves problem with Office 2007 and newer files (docx, xlsx, etc.)\n$wgGroupPermissions['user']['upload'] = true; // Allow regular users to upload files\n# add more file upload options\n$wgGroupPermissions['user']['upload_by_url'] = true;\n$wgAllowCopyUploads = true;\n$wgCopyUploadsFromSpecialUpload = true;\n# http://www.mediawiki.org/wiki/Manual:Configuring_file_uploads/de\n$wgFileExtensions = array_merge($wgFileExtensions, array('doc', 'gcode',\n'gpx','htm','html','jscad','jpg','pdf','ppt','docx', 'docxm','xlsx','xlsm','mp3','mp4','odp','otp','pptx', 'pptm','reqif','reqifz','rtf','rythm'\n,'scad','sh','stl','svg','vcf','vim','uew','xls','xml','zip'));\n# allow html\n$wgVerifyMimeType=false;\n# disable upload script checks ...\n$wgDisableUploadScriptChecks = true;\n\"\"\"\n            patch.add_text(lines)\n            patch.save()\n            pwc.dc.container.copy_to(ls_file.name, ls_path)\n
"},{"location":"#profiwiki.profiwiki_core.ProfiWiki.system_info","title":"system_info()","text":"

collect system information

Source code in profiwiki/profiwiki_core.py
def system_info(self) -> str:\n    \"\"\"\n    collect system information\n    \"\"\"\n    info = f\"\"\"os: {self.os_name}\"\"\"\n    if \"Darwin\" in info:\n        release, _version, _machine = platform.mac_ver()\n        info += f\" MacOS {release}\"\n    else:\n        info += f\"{self.os_release}\"\n    return info\n
"},{"location":"#profiwiki.profiwiki_core.ProfiWiki.update","title":"update(mwApp)","text":"

run the update script

Source code in profiwiki/profiwiki_core.py
def update(self, mwApp):\n    \"\"\"\n    run the update script\n    \"\"\"\n    mwApp.execute(\"/root/update.sh\")\n
"},{"location":"#profiwiki.profiwiki_core.ProfiWiki.work","title":"work(args)","text":"

work as instructed by the arguments

Parameters:

Name Type Description Default args(Namespace)

the command line arguments

required Source code in profiwiki/profiwiki_core.py
def work(self, args):\n    \"\"\"\n    work as instructed by the arguments\n\n    Args:\n        args(Namespace): the command line arguments\n    \"\"\"\n    self.config.fromArgs(args)\n    # make sure the wikiId is set from the container base name\n    config_path = self.config.get_config_path()\n    if os.path.isfile(config_path) and not self.config.forceRebuild:\n        # reload the previous configuration e.g. based on container_name only\n        previous_config = self.config.load(config_path)\n        if self.config.verbose:\n            print(f\"ProfiWiki with previous configuration from {config_path}...\")\n        self.config = previous_config\n    self.config.wikiId = self.config.container_base_name\n    if args.bash:\n        cmd = f\"docker exec -it {self.config.container_base_name}-mw /bin/bash\"\n        print(cmd)\n        return\n    mwApp = self.getMwApp(withGenerate=args.forceRebuild)\n    if self.config.verbose:\n        print(\n            f\"ProfiWiki {mwApp.config.container_base_name} using port {mwApp.config.port} sqlport {mwApp.config.sql_port}\"\n        )\n    if args.force_user:\n        mwApp.createWikiUser(store=True)\n    if args.all:\n        self.create(mwApp, args.forceRebuild)\n        pmw, _pdb = self.getProfiWikiContainers(mwApp)\n        pmw.install_fontawesome()\n        pmw.install_plantuml()\n        self.patch(pmw)\n        self.update(mwApp)\n        pmw.start_cron()\n    if args.wikiuser_check:\n        self.check_wikiuser(mwApp)\n    if args.apache:\n        apache_config = self.apache_config(mwApp)\n        print(apache_config)\n    if args.create:\n        self.create(mwApp, args.forceRebuild)\n    if args.check:\n        self.check(mwApp)\n    if args.down:\n        self.down(mwApp, args.forceRebuild)\n    if args.list:\n        self.list(mwApp)\n    if args.plantuml or args.fontawesome or args.cron or args.patch:\n        pmw, _pdb = self.getProfiWikiContainers(mwApp)\n        if args.plantuml:\n            pmw.install_plantuml()\n        if args.fontawesome:\n            pmw.install_fontawesome()\n        if args.cron:\n            pmw.start_cron()\n        if args.patch:\n            self.patch(pmw)\n    if args.update:\n        self.update(mwApp)\n
"},{"location":"#profiwiki.version","title":"version","text":"

Created on 2023-04-01

@author: wf

"},{"location":"#profiwiki.version.Version","title":"Version","text":"

Bases: object

Version handling for ProfiWiki

Source code in profiwiki/version.py
class Version(object):\n    \"\"\"\n    Version handling for ProfiWiki\n    \"\"\"\n\n    name = \"pyProfiWiki\"\n    description = \"\"\"BITPlan's professional Semantic Mediawiki\"\"\"\n    version = profiwiki.__version__\n    date = \"2023-04-01\"\n    updated = \"2024-08-02\"\n    authors = \"Wolfgang Fahl\"\n    doc_url = \"https://wiki.bitplan.com/index.php/ProfiWiki\"\n    chat_url = \"https://github.com/BITPlan/ProfiWiki/discussions\"\n    cm_url = \"https://github.com/BITPlan/ProfiWiki\"\n    license = f\"\"\"Copyright 2015-2024 contributors. All rights reserved.\n  Licensed under the Apache License 2.0\n  http://www.apache.org/licenses/LICENSE-2.0\n  Distributed on an \"AS IS\" basis without warranties\n  or conditions of any kind, either express or implied.\"\"\"\n    longDescription = f\"\"\"{name} version {version}\n{description}\n  Created by {authors} on {date} last updated {updated}\"\"\"\n
"}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"ProfiWiki API Documentation","text":""},{"location":"#profiwiki.docker","title":"docker","text":"

Created on 2023-04-01

@author: wf

"},{"location":"#profiwiki.docker.ProfiWikiContainer","title":"ProfiWikiContainer","text":"

a profiwiki docker container wrapper

Source code in profiwiki/docker.py
class ProfiWikiContainer:\n    \"\"\"\n    a profiwiki docker container wrapper\n    \"\"\"\n\n    def __init__(self, dc: DockerContainer):\n        \"\"\"\n        Args:\n            dc(DockerContainer): the to wrap\n        \"\"\"\n        self.dc = dc\n\n    def log_action(self, action: str):\n        \"\"\"\n        log the given action\n\n        Args:\n            action(str): the d\n        \"\"\"\n        if self.dc:\n            print(f\"{action} {self.dc.kind} {self.dc.name}\", flush=True)\n        else:\n            print(f\"{action}\", flush=True)\n\n    def upload(self, text: str, path: str):\n        \"\"\"\n        upload the given text to the given path\n        \"\"\"\n        with tempfile.NamedTemporaryFile() as tmp:\n            self.log_action(f\"uploading {tmp.name} as {path} to \")\n            with open(tmp.name, \"w\") as text_file:\n                text_file.write(text)\n            self.dc.container.copy_to(tmp.name, path)\n\n    def killremove(self, volumes: bool = False):\n        \"\"\"\n        kill and remove me\n\n        Args:\n            volumes(bool): if True remove anonymous volumes associated with the container, default=True (to avoid e.g. passwords to get remembered / stuck\n        \"\"\"\n        if self.dc:\n            self.log_action(\"killing and removing\")\n            self.dc.container.kill()\n            self.dc.container.remove(volumes=volumes)\n\n    def start_cron(self):\n        \"\"\"\n        Starting periodic command scheduler: cron.\n        \"\"\"\n        self.dc.container.execute([\"/usr/sbin/service\", \"cron\", \"start\"], tty=True)\n\n    def install_plantuml(self):\n        \"\"\"\n        install plantuml to this container\n        \"\"\"\n        script = \"\"\"#!/bin/bash\n# install plantuml\n# WF 2023-05-01\napt-get update\napt-get install -y plantuml\n\"\"\"\n        # https://gabrieldemarmiesse.github.io/python-on-whales/docker_objects/containers/\n        script_path = \"/root/install_plantuml.sh\"\n        self.install_and_run_script(script, script_path)\n        pass\n\n    def install_and_run_script(self, script: str, script_path: str):\n        \"\"\"\n        install and run the given script\n\n        Args:\n            script(str): the source code of the script\n            script_path(str): the path to copy the script to and then execute\n        \"\"\"\n        self.upload(script, script_path)\n        # make executable\n        self.dc.container.execute([\"chmod\", \"+x\", script_path])\n        self.dc.container.execute([script_path], tty=True)\n\n    def install_fontawesome(self):\n        \"\"\"\n        install fontawesome to this container\n        \"\"\"\n        script = \"\"\"#!/bin/bash\n# install fontawesome\n# WF 2023-01-25\nversion=6.4.0\n#version=5.15.4\n#version=4.7.0\nzip_url=https://github.com/FortAwesome/Font-Awesome/releases/download/$version/fontawesome-free-$version-desktop.zip\n#https://github.com/FortAwesome/Font-Awesome/releases/download/5.15.4/fontawesome-free-5.15.4-desktop.zip\n\ncd /var/www\n#curl https://use.fontawesome.com/releases/$version/fontawesome-free-$version-web.zip -o fontawesome.zip\ncurl --location $zip_url -o fontawesome.zip\nunzip -o fontawesome.zip\nln -s -f fontawesome-free-$version-desktop fontawesome\nchown -R www-data.www-data fontawesome\ncd fontawesome\nln -s svgs/solid svg\ncat << EOS > /etc/apache2/conf-available/font-awesome.conf\nAlias /font-awesome /var/www/fontawesome\n<Directory /var/www/fontawesome>\n  Options Indexes FollowSymLinks MultiViews\n  Require all granted\n</Directory>\nEOS\na2enconf font-awesome\n\"\"\"\n        script_path = \"/root/install_fontawesome\"\n        self.install_and_run_script(script, script_path)\n        try:\n            self.dc.container.execute([\"service\", \"apache2\", \"restart\"])\n        except DockerException as e:\n            # we expect a SIGTERM\n            if not e.return_code == 143:\n                raise e\n        pass\n
"},{"location":"#profiwiki.docker.ProfiWikiContainer.__init__","title":"__init__(dc)","text":"

Parameters:

Name Type Description Default dc(DockerContainer)

the to wrap

required Source code in profiwiki/docker.py
def __init__(self, dc: DockerContainer):\n    \"\"\"\n    Args:\n        dc(DockerContainer): the to wrap\n    \"\"\"\n    self.dc = dc\n
"},{"location":"#profiwiki.docker.ProfiWikiContainer.install_and_run_script","title":"install_and_run_script(script, script_path)","text":"

install and run the given script

Parameters:

Name Type Description Default script(str)

the source code of the script

required script_path(str)

the path to copy the script to and then execute

required Source code in profiwiki/docker.py
def install_and_run_script(self, script: str, script_path: str):\n    \"\"\"\n    install and run the given script\n\n    Args:\n        script(str): the source code of the script\n        script_path(str): the path to copy the script to and then execute\n    \"\"\"\n    self.upload(script, script_path)\n    # make executable\n    self.dc.container.execute([\"chmod\", \"+x\", script_path])\n    self.dc.container.execute([script_path], tty=True)\n
"},{"location":"#profiwiki.docker.ProfiWikiContainer.install_fontawesome","title":"install_fontawesome()","text":"

install fontawesome to this container

Source code in profiwiki/docker.py
    def install_fontawesome(self):\n        \"\"\"\n        install fontawesome to this container\n        \"\"\"\n        script = \"\"\"#!/bin/bash\n# install fontawesome\n# WF 2023-01-25\nversion=6.4.0\n#version=5.15.4\n#version=4.7.0\nzip_url=https://github.com/FortAwesome/Font-Awesome/releases/download/$version/fontawesome-free-$version-desktop.zip\n#https://github.com/FortAwesome/Font-Awesome/releases/download/5.15.4/fontawesome-free-5.15.4-desktop.zip\n\ncd /var/www\n#curl https://use.fontawesome.com/releases/$version/fontawesome-free-$version-web.zip -o fontawesome.zip\ncurl --location $zip_url -o fontawesome.zip\nunzip -o fontawesome.zip\nln -s -f fontawesome-free-$version-desktop fontawesome\nchown -R www-data.www-data fontawesome\ncd fontawesome\nln -s svgs/solid svg\ncat << EOS > /etc/apache2/conf-available/font-awesome.conf\nAlias /font-awesome /var/www/fontawesome\n<Directory /var/www/fontawesome>\n  Options Indexes FollowSymLinks MultiViews\n  Require all granted\n</Directory>\nEOS\na2enconf font-awesome\n\"\"\"\n        script_path = \"/root/install_fontawesome\"\n        self.install_and_run_script(script, script_path)\n        try:\n            self.dc.container.execute([\"service\", \"apache2\", \"restart\"])\n        except DockerException as e:\n            # we expect a SIGTERM\n            if not e.return_code == 143:\n                raise e\n        pass\n
"},{"location":"#profiwiki.docker.ProfiWikiContainer.install_plantuml","title":"install_plantuml()","text":"

install plantuml to this container

Source code in profiwiki/docker.py
    def install_plantuml(self):\n        \"\"\"\n        install plantuml to this container\n        \"\"\"\n        script = \"\"\"#!/bin/bash\n# install plantuml\n# WF 2023-05-01\napt-get update\napt-get install -y plantuml\n\"\"\"\n        # https://gabrieldemarmiesse.github.io/python-on-whales/docker_objects/containers/\n        script_path = \"/root/install_plantuml.sh\"\n        self.install_and_run_script(script, script_path)\n        pass\n
"},{"location":"#profiwiki.docker.ProfiWikiContainer.killremove","title":"killremove(volumes=False)","text":"

kill and remove me

Parameters:

Name Type Description Default volumes(bool)

if True remove anonymous volumes associated with the container, default=True (to avoid e.g. passwords to get remembered / stuck

required Source code in profiwiki/docker.py
def killremove(self, volumes: bool = False):\n    \"\"\"\n    kill and remove me\n\n    Args:\n        volumes(bool): if True remove anonymous volumes associated with the container, default=True (to avoid e.g. passwords to get remembered / stuck\n    \"\"\"\n    if self.dc:\n        self.log_action(\"killing and removing\")\n        self.dc.container.kill()\n        self.dc.container.remove(volumes=volumes)\n
"},{"location":"#profiwiki.docker.ProfiWikiContainer.log_action","title":"log_action(action)","text":"

log the given action

Parameters:

Name Type Description Default action(str)

the d

required Source code in profiwiki/docker.py
def log_action(self, action: str):\n    \"\"\"\n    log the given action\n\n    Args:\n        action(str): the d\n    \"\"\"\n    if self.dc:\n        print(f\"{action} {self.dc.kind} {self.dc.name}\", flush=True)\n    else:\n        print(f\"{action}\", flush=True)\n
"},{"location":"#profiwiki.docker.ProfiWikiContainer.start_cron","title":"start_cron()","text":"

Starting periodic command scheduler: cron.

Source code in profiwiki/docker.py
def start_cron(self):\n    \"\"\"\n    Starting periodic command scheduler: cron.\n    \"\"\"\n    self.dc.container.execute([\"/usr/sbin/service\", \"cron\", \"start\"], tty=True)\n
"},{"location":"#profiwiki.docker.ProfiWikiContainer.upload","title":"upload(text, path)","text":"

upload the given text to the given path

Source code in profiwiki/docker.py
def upload(self, text: str, path: str):\n    \"\"\"\n    upload the given text to the given path\n    \"\"\"\n    with tempfile.NamedTemporaryFile() as tmp:\n        self.log_action(f\"uploading {tmp.name} as {path} to \")\n        with open(tmp.name, \"w\") as text_file:\n            text_file.write(text)\n        self.dc.container.copy_to(tmp.name, path)\n
"},{"location":"#profiwiki.patch","title":"patch","text":"

Created on 2023-04-09

@author: wf

"},{"location":"#profiwiki.patch.Patch","title":"Patch","text":"

A class for patch a text file

Source code in profiwiki/patch.py
class Patch:\n    \"\"\"\n    A class for patch a text file\n    \"\"\"\n\n    def __init__(self, file_path: str):\n        \"\"\"\n        Initializes a Patch instance with the file path file to be patched.\n\n        Args:\n            file_path (str): The file path of the PHP file to be patched.\n        \"\"\"\n        self.lines = []\n        self.file_path = file_path\n        # https://stackoverflow.com/a/3277516/1497139\n        with open(self.file_path, \"r\", encoding=\"UTF-8\") as file:\n            while line := file.readline():\n                self.lines.append(line.rstrip())\n\n    def save(self):\n        \"\"\"\n        save my lines\n        \"\"\"\n        with open(self.file_path, \"w\") as f:\n            for line in self.lines:\n                f.write(f\"{line}\\n\")\n\n    def patch_mediawiki_config_var(self, var_name: str, var_value: str) -> None:\n        \"\"\"\n        Patches a MediaWiki configuration variable in the PHP file with the given name and value.\n\n        Args:\n            var_name (str): The name of the configuration variable to be patched.\n            var_value (str): The new value to be set for the configuration variable.\n\n        Returns:\n            None\n        \"\"\"\n        # Define the regex pattern to match the configuration variable\n        pattern = r\"\\$wg\" + re.escape(var_name) + r\"\\s*=\\s*[^\\n]+\"\n\n        # Define the replacement string with the updated value\n        replacement = f\"$wg{var_name} = {var_value};\"\n\n        # Use fileinput to replace the matched line in the file\n        for i, line in enumerate(self.lines):\n            new_line = re.sub(pattern, replacement, line)\n            self.lines[i] = new_line\n\n    def add_text(self, text: str, avoid_duplication: bool = True):\n        \"\"\"\n        Adds text avoiding duplication if specified\n\n        Args:\n            text (str): the text to add\n            avoid_duplication(bool): if True avoid duplication of existing lines\n        \"\"\"\n        new_lines = text.split(\"\\n\")\n        for new_line in new_lines:\n            do_add = True\n            if avoid_duplication:\n                do_add = not new_line in self.lines\n            if do_add:\n                self.lines.append(new_line)\n
"},{"location":"#profiwiki.patch.Patch.__init__","title":"__init__(file_path)","text":"

Initializes a Patch instance with the file path file to be patched.

Parameters:

Name Type Description Default file_path str

The file path of the PHP file to be patched.

required Source code in profiwiki/patch.py
def __init__(self, file_path: str):\n    \"\"\"\n    Initializes a Patch instance with the file path file to be patched.\n\n    Args:\n        file_path (str): The file path of the PHP file to be patched.\n    \"\"\"\n    self.lines = []\n    self.file_path = file_path\n    # https://stackoverflow.com/a/3277516/1497139\n    with open(self.file_path, \"r\", encoding=\"UTF-8\") as file:\n        while line := file.readline():\n            self.lines.append(line.rstrip())\n
"},{"location":"#profiwiki.patch.Patch.add_text","title":"add_text(text, avoid_duplication=True)","text":"

Adds text avoiding duplication if specified

Parameters:

Name Type Description Default text str

the text to add

required avoid_duplication(bool)

if True avoid duplication of existing lines

required Source code in profiwiki/patch.py
def add_text(self, text: str, avoid_duplication: bool = True):\n    \"\"\"\n    Adds text avoiding duplication if specified\n\n    Args:\n        text (str): the text to add\n        avoid_duplication(bool): if True avoid duplication of existing lines\n    \"\"\"\n    new_lines = text.split(\"\\n\")\n    for new_line in new_lines:\n        do_add = True\n        if avoid_duplication:\n            do_add = not new_line in self.lines\n        if do_add:\n            self.lines.append(new_line)\n
"},{"location":"#profiwiki.patch.Patch.patch_mediawiki_config_var","title":"patch_mediawiki_config_var(var_name, var_value)","text":"

Patches a MediaWiki configuration variable in the PHP file with the given name and value.

Parameters:

Name Type Description Default var_name str

The name of the configuration variable to be patched.

required var_value str

The new value to be set for the configuration variable.

required

Returns:

Type Description None

None

Source code in profiwiki/patch.py
def patch_mediawiki_config_var(self, var_name: str, var_value: str) -> None:\n    \"\"\"\n    Patches a MediaWiki configuration variable in the PHP file with the given name and value.\n\n    Args:\n        var_name (str): The name of the configuration variable to be patched.\n        var_value (str): The new value to be set for the configuration variable.\n\n    Returns:\n        None\n    \"\"\"\n    # Define the regex pattern to match the configuration variable\n    pattern = r\"\\$wg\" + re.escape(var_name) + r\"\\s*=\\s*[^\\n]+\"\n\n    # Define the replacement string with the updated value\n    replacement = f\"$wg{var_name} = {var_value};\"\n\n    # Use fileinput to replace the matched line in the file\n    for i, line in enumerate(self.lines):\n        new_line = re.sub(pattern, replacement, line)\n        self.lines[i] = new_line\n
"},{"location":"#profiwiki.patch.Patch.save","title":"save()","text":"

save my lines

Source code in profiwiki/patch.py
def save(self):\n    \"\"\"\n    save my lines\n    \"\"\"\n    with open(self.file_path, \"w\") as f:\n        for line in self.lines:\n            f.write(f\"{line}\\n\")\n
"},{"location":"#profiwiki.profiwiki_cmd","title":"profiwiki_cmd","text":"

Created on 2023-04-01

@author: wf

"},{"location":"#profiwiki.profiwiki_cmd.ProfiWikiCmd","title":"ProfiWikiCmd","text":"

ProfiWiki command line

Source code in profiwiki/profiwiki_cmd.py
class ProfiWikiCmd:\n    \"\"\"\n    ProfiWiki command line\n    \"\"\"\n\n    def get_arg_parser(\n        self, config: MwClusterConfig, description: str, version_msg: str\n    ) -> ArgumentParser:\n        \"\"\"\n        Setup command line argument parser\n\n        Args:\n            config(MwClusterConfig): the mediawiki cluster configuration\n            description(str): the description\n            version_msg(str): the version message\n\n        Returns:\n            ArgumentParser: the argument parser\n        \"\"\"\n        # script_path=Path(__file__)\n        parser = ArgumentParser(\n            description=description, formatter_class=RawDescriptionHelpFormatter\n        )\n        config.addArgs(parser)\n        parser.add_argument(\n            \"--about\",\n            help=\"show about info [default: %(default)s]\",\n            action=\"store_true\",\n        )\n        parser.add_argument(\n            \"--apache\", help=\"generate apache configuration\", action=\"store_true\"\n        )\n        parser.add_argument(\n            \"--all\", help=\"do all necessary steps for a full setup\", action=\"store_true\"\n        )\n        parser.add_argument(\"--bash\", help=\"bash into container\", action=\"store_true\")\n        parser.add_argument(\"--create\", action=\"store_true\", help=\"create the wiki\")\n        parser.add_argument(\"--check\", action=\"store_true\", help=\"check the wiki\")\n        parser.add_argument(\n            \"--update\",\n            action=\"store_true\",\n            help=\"start the update script -e.g. to fix SMW key\",\n        )\n        parser.add_argument(\"--cron\", action=\"store_true\", help=\"start cron service\")\n        parser.add_argument(\n            \"--down\",\n            action=\"store_true\",\n            help=\"shutdown the wiki [default: %(default)s]\",\n        )\n        parser.add_argument(\n            \"--patch\",\n            action=\"store_true\",\n            help=\"apply LocalSettings.php patches [default: %(default)s]\",\n        )\n        parser.add_argument(\n            \"--list\",\n            action=\"store_true\",\n            help=\"list the available profi wikis [default: %(default)s]\",\n        )\n        parser.add_argument(\n            \"-fa\", \"--fontawesome\", action=\"store_true\", help=\"install fontawesome\"\n        )\n        parser.add_argument(\n            \"-wuc\", \"--wikiuser_check\", action=\"store_true\", help=\"check wikiuser\"\n        )\n        parser.add_argument(\n            \"-pu\", \"--plantuml\", action=\"store_true\", help=\"install plantuml\"\n        )\n        parser.add_argument(\n            \"-i\", \"--info\", help=\"show system info\", action=\"store_true\"\n        )\n        parser.add_argument(\"-V\", \"--version\", action=\"version\", version=version_msg)\n        # debug args\n        parser.add_argument(\"--debugServer\", help=\"remote debug Server\")\n        parser.add_argument(\n            \"--debugPort\", type=int, help=\"remote debug Port\", default=5678\n        )\n        parser.add_argument(\n            \"--debugPathMapping\",\n            nargs=\"+\",\n            help=\"remote debug Server path mapping - needs two arguments 1st: remotePath 2nd: local Path\",\n        )\n        return parser\n\n    def optional_debug(self, args):\n        \"\"\"\n        start the remote debugger if the arguments specify so\n\n        Args:\n            args: The command line arguments\n        \"\"\"\n        if args.debugServer:\n            import pydevd\n            import pydevd_file_utils\n\n            print(args.debugPathMapping, flush=True)\n            if args.debugPathMapping:\n                if len(args.debugPathMapping) == 2:\n                    remotePath = args.debugPathMapping[\n                        0\n                    ]  # path on the remote debugger side\n                    localPath = args.debugPathMapping[\n                        1\n                    ]  # path on the local machine where the code runs\n                    MY_PATHS_FROM_ECLIPSE_TO_PYTHON = [\n                        (remotePath, localPath),\n                    ]\n                    pydevd_file_utils.setup_client_server_paths(\n                        MY_PATHS_FROM_ECLIPSE_TO_PYTHON\n                    )  # os.environ[\"PATHS_FROM_ECLIPSE_TO_PYTHON\"]='[[\"%s\", \"%s\"]]' % (remotePath,localPath)  # print(\"trying to debug with PATHS_FROM_ECLIPSE_TO_PYTHON=%s\" % os.environ[\"PATHS_FROM_ECLIPSE_TO_PYTHON\"]);\n\n            pydevd.settrace(\n                args.debugServer,\n                port=args.debugPort,\n                stdoutToServer=True,\n                stderrToServer=True,\n            )\n            print(\"command line args are: %s\" % str(sys.argv))\n            pass\n
"},{"location":"#profiwiki.profiwiki_cmd.ProfiWikiCmd.get_arg_parser","title":"get_arg_parser(config, description, version_msg)","text":"

Setup command line argument parser

Parameters:

Name Type Description Default config(MwClusterConfig)

the mediawiki cluster configuration

required description(str)

the description

required version_msg(str)

the version message

required

Returns:

Name Type Description ArgumentParser ArgumentParser

the argument parser

Source code in profiwiki/profiwiki_cmd.py
def get_arg_parser(\n    self, config: MwClusterConfig, description: str, version_msg: str\n) -> ArgumentParser:\n    \"\"\"\n    Setup command line argument parser\n\n    Args:\n        config(MwClusterConfig): the mediawiki cluster configuration\n        description(str): the description\n        version_msg(str): the version message\n\n    Returns:\n        ArgumentParser: the argument parser\n    \"\"\"\n    # script_path=Path(__file__)\n    parser = ArgumentParser(\n        description=description, formatter_class=RawDescriptionHelpFormatter\n    )\n    config.addArgs(parser)\n    parser.add_argument(\n        \"--about\",\n        help=\"show about info [default: %(default)s]\",\n        action=\"store_true\",\n    )\n    parser.add_argument(\n        \"--apache\", help=\"generate apache configuration\", action=\"store_true\"\n    )\n    parser.add_argument(\n        \"--all\", help=\"do all necessary steps for a full setup\", action=\"store_true\"\n    )\n    parser.add_argument(\"--bash\", help=\"bash into container\", action=\"store_true\")\n    parser.add_argument(\"--create\", action=\"store_true\", help=\"create the wiki\")\n    parser.add_argument(\"--check\", action=\"store_true\", help=\"check the wiki\")\n    parser.add_argument(\n        \"--update\",\n        action=\"store_true\",\n        help=\"start the update script -e.g. to fix SMW key\",\n    )\n    parser.add_argument(\"--cron\", action=\"store_true\", help=\"start cron service\")\n    parser.add_argument(\n        \"--down\",\n        action=\"store_true\",\n        help=\"shutdown the wiki [default: %(default)s]\",\n    )\n    parser.add_argument(\n        \"--patch\",\n        action=\"store_true\",\n        help=\"apply LocalSettings.php patches [default: %(default)s]\",\n    )\n    parser.add_argument(\n        \"--list\",\n        action=\"store_true\",\n        help=\"list the available profi wikis [default: %(default)s]\",\n    )\n    parser.add_argument(\n        \"-fa\", \"--fontawesome\", action=\"store_true\", help=\"install fontawesome\"\n    )\n    parser.add_argument(\n        \"-wuc\", \"--wikiuser_check\", action=\"store_true\", help=\"check wikiuser\"\n    )\n    parser.add_argument(\n        \"-pu\", \"--plantuml\", action=\"store_true\", help=\"install plantuml\"\n    )\n    parser.add_argument(\n        \"-i\", \"--info\", help=\"show system info\", action=\"store_true\"\n    )\n    parser.add_argument(\"-V\", \"--version\", action=\"version\", version=version_msg)\n    # debug args\n    parser.add_argument(\"--debugServer\", help=\"remote debug Server\")\n    parser.add_argument(\n        \"--debugPort\", type=int, help=\"remote debug Port\", default=5678\n    )\n    parser.add_argument(\n        \"--debugPathMapping\",\n        nargs=\"+\",\n        help=\"remote debug Server path mapping - needs two arguments 1st: remotePath 2nd: local Path\",\n    )\n    return parser\n
"},{"location":"#profiwiki.profiwiki_cmd.ProfiWikiCmd.optional_debug","title":"optional_debug(args)","text":"

start the remote debugger if the arguments specify so

Parameters:

Name Type Description Default args

The command line arguments

required Source code in profiwiki/profiwiki_cmd.py
def optional_debug(self, args):\n    \"\"\"\n    start the remote debugger if the arguments specify so\n\n    Args:\n        args: The command line arguments\n    \"\"\"\n    if args.debugServer:\n        import pydevd\n        import pydevd_file_utils\n\n        print(args.debugPathMapping, flush=True)\n        if args.debugPathMapping:\n            if len(args.debugPathMapping) == 2:\n                remotePath = args.debugPathMapping[\n                    0\n                ]  # path on the remote debugger side\n                localPath = args.debugPathMapping[\n                    1\n                ]  # path on the local machine where the code runs\n                MY_PATHS_FROM_ECLIPSE_TO_PYTHON = [\n                    (remotePath, localPath),\n                ]\n                pydevd_file_utils.setup_client_server_paths(\n                    MY_PATHS_FROM_ECLIPSE_TO_PYTHON\n                )  # os.environ[\"PATHS_FROM_ECLIPSE_TO_PYTHON\"]='[[\"%s\", \"%s\"]]' % (remotePath,localPath)  # print(\"trying to debug with PATHS_FROM_ECLIPSE_TO_PYTHON=%s\" % os.environ[\"PATHS_FROM_ECLIPSE_TO_PYTHON\"]);\n\n        pydevd.settrace(\n            args.debugServer,\n            port=args.debugPort,\n            stdoutToServer=True,\n            stderrToServer=True,\n        )\n        print(\"command line args are: %s\" % str(sys.argv))\n        pass\n
"},{"location":"#profiwiki.profiwiki_cmd.main","title":"main(argv=None)","text":"

main program.

Source code in profiwiki/profiwiki_cmd.py
def main(argv=None):  # IGNORE:C0111\n    \"\"\"main program.\"\"\"\n\n    if argv is None:\n        argv = sys.argv[1:]\n\n    program_name = \"profiwiki\"\n    program_version = f\"v{Version.version}\"\n    program_build_date = str(Version.date)\n    program_version_message = f\"{program_name} ({program_version},{program_build_date})\"\n\n    args = None\n    try:\n        pw = ProfiWiki()\n        pw_cmd = ProfiWikiCmd()\n        parser = pw_cmd.get_arg_parser(\n            config=pw.config,\n            description=Version.license,\n            version_msg=program_version_message,\n        )\n        args = parser.parse_args(argv)\n        if len(argv) < 1:\n            parser.print_usage()\n            sys.exit(1)\n        if args.about:\n            print(program_version_message)\n            print(f\"see {Version.doc_url}\")\n            webbrowser.open(Version.doc_url)\n        pw_cmd.optional_debug(args)\n        if args.info:\n            info = pw.system_info()\n            print(info)\n        pw.work(args)\n\n    except KeyboardInterrupt:\n        ###\n        # handle keyboard interrupt\n        # ###\n        return 1\n    except Exception as e:\n        if DEBUG:\n            raise e\n        indent = len(program_name) * \" \"\n        sys.stderr.write(program_name + \": \" + repr(e) + \"\\n\")\n        sys.stderr.write(indent + \"  for help use --help\")\n        if args is None:\n            print(\"args could not be parsed\")\n        elif args.debug:\n            print(traceback.format_exc())\n        return 2\n
"},{"location":"#profiwiki.profiwiki_core","title":"profiwiki_core","text":"

Created on 2023-04-01

@author: wf

"},{"location":"#profiwiki.profiwiki_core.ProfiWiki","title":"ProfiWiki","text":"

ProfiWiki

Source code in profiwiki/profiwiki_core.py
class ProfiWiki:\n    \"\"\"\n    ProfiWiki\n    \"\"\"\n\n    def __init__(\n        self,\n        prefix: str = \"pw\",\n        smw_version=\"4.1.3\",\n        mw_version=\"1.39.8\",\n        port: int = 9079,\n    ):\n        \"\"\"\n        constructor\n        \"\"\"\n        self.os_name = platform.system()\n        self.os_uname = os.uname()\n        self.os_release = platform.release()\n        self.args = None\n        self.config = MwClusterConfig()\n        self.config.smw_version = smw_version\n        self.config.random_password = False\n        self.config.prefix = prefix\n        self.config.base_port = port\n        self.config.sql_port = port - 1\n        self.config.port = port\n        self.config.versions = [mw_version]\n        self.config.version=mw_version\n        self.config.container_base_name = \"pw\"\n        self.config.extensionNameList = [\n            \"Admin Links\",\n            \"Diagrams\",\n            \"Graph\",\n            \"Header Tabs\",\n            \"ImageMap\",\n            \"ImageLink\",\n            \"MagicNoCache\",\n            \"Maps9\",\n            \"Mermaid\",\n            \"MsUpload\",\n            \"Nuke\",\n            \"Page Forms\",\n            \"ParserFunctions\",\n            \"PDFEmbed\",\n            \"Renameuser\",\n            \"Replace Text\",\n            \"Semantic Result Formats\",\n            \"SyntaxHighlight\",\n            \"Variables\",\n            \"UserFunctions\",\n            \"YouTube\"\n        ]\n        self.config.logo = \"https://wiki.bitplan.com/images/wiki/thumb/6/63/Profiwikiicon.png/96px-Profiwikiicon.png\"\n        self.config.__post_init__()\n        self.mwCluster = None\n        pass\n\n    def system_info(self) -> str:\n        \"\"\"\n        collect system information\n        \"\"\"\n        info = f\"\"\"os: {self.os_name}\"\"\"\n        if \"Darwin\" in info:\n            release, _version, _machine = platform.mac_ver()\n            info += f\" MacOS {release}\"\n        else:\n            info += f\"{self.os_release}\"\n        return info\n\n    def work(self, args):\n        \"\"\"\n        work as instructed by the arguments\n\n        Args:\n            args(Namespace): the command line arguments\n        \"\"\"\n        self.config.fromArgs(args)\n        # make sure the wikiId is set from the container base name\n        config_path = self.config.get_config_path()\n        if os.path.isfile(config_path) and not self.config.forceRebuild:\n            # reload the previous configuration e.g. based on container_name only\n            previous_config = self.config.load(config_path)\n            if self.config.verbose:\n                print(f\"ProfiWiki with previous configuration from {config_path}...\")\n            self.config = previous_config\n        self.config.wikiId = self.config.container_base_name\n        if args.bash:\n            cmd = f\"docker exec -it {self.config.container_base_name}-mw /bin/bash\"\n            print(cmd)\n            return\n        mwApp = self.getMwApp(withGenerate=args.forceRebuild)\n        if self.config.verbose:\n            print(\n                f\"ProfiWiki {mwApp.config.container_base_name} using port {mwApp.config.port} sqlport {mwApp.config.sql_port}\"\n            )\n        if args.force_user:\n            mwApp.createWikiUser(store=True)\n        if args.all:\n            self.create(mwApp, args.forceRebuild)\n            pmw, _pdb = self.getProfiWikiContainers(mwApp)\n            pmw.install_fontawesome()\n            pmw.install_plantuml()\n            self.patch(pmw)\n            self.update(mwApp)\n            pmw.start_cron()\n        if args.wikiuser_check:\n            self.check_wikiuser(mwApp)\n        if args.apache:\n            apache_config = self.apache_config(mwApp)\n            print(apache_config)\n        if args.create:\n            self.create(mwApp, args.forceRebuild)\n        if args.check:\n            self.check(mwApp)\n        if args.down:\n            self.down(mwApp, args.forceRebuild)\n        if args.list:\n            self.list(mwApp)\n        if args.plantuml or args.fontawesome or args.cron or args.patch:\n            pmw, _pdb = self.getProfiWikiContainers(mwApp)\n            if args.plantuml:\n                pmw.install_plantuml()\n            if args.fontawesome:\n                pmw.install_fontawesome()\n            if args.cron:\n                pmw.start_cron()\n            if args.patch:\n                self.patch(pmw)\n        if args.update:\n            self.update(mwApp)\n\n    def getMwCluster(self, withGenerate: bool = True) -> MediaWikiCluster:\n        \"\"\"\n        get a mediawiki Cluster for my configuration\n\n        Args:\n            withGenerate(bool): if True regenerate the configuration files\n\n        Returns:\n            MediaWikiCluster: the MediaWiki Cluser\n        \"\"\"\n        if self.mwCluster is not None:\n            return self.mwCluster\n        mwCluster = MediaWikiCluster(config=self.config)\n        # generate\n        mwCluster.createApps(withGenerate=withGenerate)\n        self.mwCluster = mwCluster\n        return mwCluster\n\n    def getMwApp(self, withGenerate: bool = True):\n        \"\"\"\n        get my mediawiki Docker application\n        \"\"\"\n        mwCluster = self.getMwCluster(withGenerate)\n        if not self.config.version in mwCluster.apps:\n            raise Exception(f\"Mediawiki version {self.config.version} missing {mwCluster.apps.keys()}\")\n        mwApp = mwCluster.apps[self.config.version]\n        return mwApp\n\n    def getProfiWikiContainers(self, mwApp: DockerApplication):\n        \"\"\"\n        get the two containers - for mediawiki and the database\n\n        Args:\n            mwApp(DockerApplication): the MediaWiki Docker Application\n\n        Returns:\n            Tuple(ProfiWikiContainer,ProfiWikiContainer): MediaWiki, Database\n        \"\"\"\n        mw, db = mwApp.getContainers()\n        pmw = ProfiWikiContainer(mw)\n        pdb = ProfiWikiContainer(db)\n        return pmw, pdb\n\n    def patch(self, pwc: ProfiWikiContainer):\n        \"\"\"\n        apply profi wiki patches to the given ProfiWikiContainer\n        \"\"\"\n        if not pwc.dc:\n            raise (\"no container to apply patch\")\n        ls_path = \"/var/www/html/LocalSettings.php\"\n        timestamp = datetime.datetime.utcnow().strftime(\"%Y-%m-%d\")\n        with tempfile.NamedTemporaryFile(\n            mode=\"w\", prefix=\"LocalSettings_\", suffix=\".php\"\n        ) as ls_file:\n            pwc.log_action(f\"patching {ls_file.name}\")\n            pwc.dc.container.copy_from(ls_path, ls_file.name)\n            patch = Patch(file_path=ls_file.name)\n            lines = f\"\"\"// modified by profiwiki\n// use WikiEditor e.g. for MsUpload\nwfLoadExtension( 'WikiEditor' );\n# make this an intranet - comment out if you want this to be a public wiki\n# The following permissions were set based on your choice in the installer\n$wgGroupPermissions['*']['createaccount'] = false;\n$wgGroupPermissions['*']['edit'] = false;\n$wgGroupPermissions['*']['read'] = false;\n# Allow properties in Templates\n$smwgNamespacesWithSemanticLinks[NS_TEMPLATE] = true;\n# WF 2015-01-20\n# allow string functions - needed for Template:Link\n$wgPFEnableStringFunctions=true;\n// allow raw HTML\n$wgRawHtml = true;\n// allow images\n$wgAllowImageTag=true;\n// InstantCommons allows wiki to use images from https://commons.wikimedia.org\n$wgUseInstantCommons = true;\n// avoid showing (expected) deprecation warnings\nerror_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE);\n# # add support for special properties\n# see https://www.semantic-mediawiki.org/wiki/Help:$smwgPageSpecialProperties\n# Modification date\n$smwgPageSpecialProperties[] = '_MDAT';\n# Creation date\n$smwgPageSpecialProperties[] = '_CDAT';\n# Is a new page\n$smwgPageSpecialProperties[] = '_NEWP';\n# Last editor is\n$smwgPageSpecialProperties[] = '_LEDT';\n# Media type\n$smwgPageSpecialProperties[] = '_MEDIA';\n# MIME type\n$smwgPageSpecialProperties[] = '_MIME';\n// https://www.mediawiki.org/wiki/Extension:UserFunctions\n$wgUFEnabledPersonalDataFunctions = ['ip','nickname','realname','useremail','username',];\n// allow user functions in main mediawiki space\n$wgUFAllowedNamespaces[NS_MAIN] = true;\n# increase query limit\n$smwgQMaxLimit = 20000;\n//Default width for the PDF object container.\n$wgPdfEmbed['width'] = 800;\n//Default height for the PDF object container.\n$wgPdfEmbed['height'] = 1090;\n//Allow user the usage of the tag\n$wgGroupPermissions['*']['embed_pdf'] = true;\n// config parameters for MsUpload\n// https://www.mediawiki.org/wiki/Extension:MsUpload\n$wgMSU_useDragDrop = true; // Should the drag & drop area be shown? (Not set by default)\n$wgMSU_showAutoCat = true; // Files uploaded while editing a category page will be added to that category\n$wgMSU_checkAutoCat = true; // Whether the checkbox for adding a category to a page is checked by default\n$wgMSU_useMsLinks = false; // Insert links in Extension:MsLinks style?\n$wgMSU_confirmReplace = true; // Show the \"Replace file?\" checkbox\n$wgMSU_imgParams = '400px'; // Default image parameters, for example \"thumb|200px\"\n$wgMSU_uploadsize = '100mb'; // Max upload size through MsUpload\n// general parameters for MsUpload\n$wgEnableWriteAPI = true; // Enable the API\n$wgEnableUploads = true; // Enable uploads\n$wgAllowJavaUploads = true; // Solves problem with Office 2007 and newer files (docx, xlsx, etc.)\n$wgGroupPermissions['user']['upload'] = true; // Allow regular users to upload files\n# add more file upload options\n$wgGroupPermissions['user']['upload_by_url'] = true;\n$wgAllowCopyUploads = true;\n$wgCopyUploadsFromSpecialUpload = true;\n# http://www.mediawiki.org/wiki/Manual:Configuring_file_uploads/de\n$wgFileExtensions = array_merge($wgFileExtensions, array('doc', 'gcode',\n'gpx','htm','html','jscad','jpg','pdf','ppt','docx', 'docxm','xlsx','xlsm','mp3','mp4','odp','otp','pptx', 'pptm','reqif','reqifz','rtf','rythm'\n,'scad','sh','stl','svg','vcf','vim','uew','xls','xml','zip'));\n# allow html\n$wgVerifyMimeType=false;\n# disable upload script checks ...\n$wgDisableUploadScriptChecks = true;\n\"\"\"\n            patch.add_text(lines)\n            patch.save()\n            pwc.dc.container.copy_to(ls_file.name, ls_path)\n\n    def update(self, mwApp):\n        \"\"\"\n        run the update script\n        \"\"\"\n        mwApp.execute(\"/root/update.sh\")\n\n    def check(self, mwApp):\n        \"\"\"\n        check\n        \"\"\"\n        mwApp.check()\n\n    def create(self, mwApp, forceRebuild: bool = False):\n        \"\"\"\n        create a profiwiki mediawiki\n        \"\"\"\n        mwApp.start(forceRebuild=forceRebuild)\n\n    def down(self, mwApp, forceRebuild: bool = False):\n        \"\"\"\n        shut down the profiwiki base mediawiki\n        \"\"\"\n        mwApp.down(forceRebuild=forceRebuild)\n\n    def list(self, mwApp):\n        \"\"\"\n        list the profi wikis\n        \"\"\"\n        print(json.dumps(mwApp.config.as_dict(), indent=2))\n        pass\n\n    def check_wikiuser(self, mwApp: DockerApplication):\n        \"\"\" \"\"\"\n        print(f\"Checking WikiUser ... for {mwApp.config.container_base_name}\")\n        wikiUsers = WikiUser.getWikiUsers(lenient=True)\n        if not mwApp.config.wikiId:\n            print(\"no WikiId configured\")\n            return\n        if not mwApp.config.wikiId in wikiUsers:\n            print(f\"no wikiUser for wikiId {mwApp.config.wikiId} found\")\n            return\n        wikiUser = wikiUsers[mwApp.config.wikiId]\n        if mwApp.config.password != wikiUser.getPassword():\n            print(f\"configured password is different then {mwApp.config.wikiId}\")\n        else:\n            print(\n                f\"wikiUser for wikiId {mwApp.config.wikiId} is available and password as configured\"\n            )\n        pass\n\n    def apache_config(self, mwApp: DockerApplication) -> str:\n        \"\"\"\n        get the apache configuration for the given mediawiki Docker application\n\n        Args:\n            mwApp(DockerApplication): the docker application to generate the configuration for\n        \"\"\"\n        config = mwApp.config\n        apache_config = f\"\"\"<VirtualHost *:80 >\n    # The ServerName directive sets the request scheme, hostname and port that\n    # the server uses to identify itself. This is used when creating\n    # redirection URLs. In the context of virtual hosts, the ServerName\n    # specifies what hostname must appear in the request's Host: header to\n    # match this virtual host. For the default virtual host (this file) this\n    # value is not decisive as it is used as a last resort host regardless.\n    # However, you must set it for any further virtual host explicitly.\n    ServerName {config.host}\n\n    ServerAdmin webmaster@{config.host}\n    #DocumentRoot /var/www/html\n\n    # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,\n    # error, crit, alert, emerg.\n    # It is also possible to configure the loglevel for particular\n    # modules, e.g.\n    #LogLevel info ssl:warn\n\n    ErrorLog ${{APACHE_LOG_DIR}}/{config.container_base_name}_error.log\n    CustomLog ${{APACHE_LOG_DIR}}/{config.container_base_name}_access.log combined\n\n    # For most configuration files from conf-available/, which are\n    # enabled or disabled at a global level, it is possible to\n    # include a line for only one particular virtual host. For example the\n    # following line enables the CGI configuration for this host only\n    # after it has been globally disabled with \"a2disconf\".\n    #Include conf-available/serve-cgi-bin.conf\n\n    # Mediawiki installations\n    ProxyPass / http://localhost:{config.port}/\n    ProxyPassReverse / http://localhost:{config.port}/\n</VirtualHost>\"\"\"\n        return apache_config\n
"},{"location":"#profiwiki.profiwiki_core.ProfiWiki.__init__","title":"__init__(prefix='pw', smw_version='4.1.3', mw_version='1.39.8', port=9079)","text":"

constructor

Source code in profiwiki/profiwiki_core.py
def __init__(\n    self,\n    prefix: str = \"pw\",\n    smw_version=\"4.1.3\",\n    mw_version=\"1.39.8\",\n    port: int = 9079,\n):\n    \"\"\"\n    constructor\n    \"\"\"\n    self.os_name = platform.system()\n    self.os_uname = os.uname()\n    self.os_release = platform.release()\n    self.args = None\n    self.config = MwClusterConfig()\n    self.config.smw_version = smw_version\n    self.config.random_password = False\n    self.config.prefix = prefix\n    self.config.base_port = port\n    self.config.sql_port = port - 1\n    self.config.port = port\n    self.config.versions = [mw_version]\n    self.config.version=mw_version\n    self.config.container_base_name = \"pw\"\n    self.config.extensionNameList = [\n        \"Admin Links\",\n        \"Diagrams\",\n        \"Graph\",\n        \"Header Tabs\",\n        \"ImageMap\",\n        \"ImageLink\",\n        \"MagicNoCache\",\n        \"Maps9\",\n        \"Mermaid\",\n        \"MsUpload\",\n        \"Nuke\",\n        \"Page Forms\",\n        \"ParserFunctions\",\n        \"PDFEmbed\",\n        \"Renameuser\",\n        \"Replace Text\",\n        \"Semantic Result Formats\",\n        \"SyntaxHighlight\",\n        \"Variables\",\n        \"UserFunctions\",\n        \"YouTube\"\n    ]\n    self.config.logo = \"https://wiki.bitplan.com/images/wiki/thumb/6/63/Profiwikiicon.png/96px-Profiwikiicon.png\"\n    self.config.__post_init__()\n    self.mwCluster = None\n    pass\n
"},{"location":"#profiwiki.profiwiki_core.ProfiWiki.apache_config","title":"apache_config(mwApp)","text":"

get the apache configuration for the given mediawiki Docker application

Parameters:

Name Type Description Default mwApp(DockerApplication)

the docker application to generate the configuration for

required Source code in profiwiki/profiwiki_core.py
    def apache_config(self, mwApp: DockerApplication) -> str:\n        \"\"\"\n        get the apache configuration for the given mediawiki Docker application\n\n        Args:\n            mwApp(DockerApplication): the docker application to generate the configuration for\n        \"\"\"\n        config = mwApp.config\n        apache_config = f\"\"\"<VirtualHost *:80 >\n    # The ServerName directive sets the request scheme, hostname and port that\n    # the server uses to identify itself. This is used when creating\n    # redirection URLs. In the context of virtual hosts, the ServerName\n    # specifies what hostname must appear in the request's Host: header to\n    # match this virtual host. For the default virtual host (this file) this\n    # value is not decisive as it is used as a last resort host regardless.\n    # However, you must set it for any further virtual host explicitly.\n    ServerName {config.host}\n\n    ServerAdmin webmaster@{config.host}\n    #DocumentRoot /var/www/html\n\n    # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,\n    # error, crit, alert, emerg.\n    # It is also possible to configure the loglevel for particular\n    # modules, e.g.\n    #LogLevel info ssl:warn\n\n    ErrorLog ${{APACHE_LOG_DIR}}/{config.container_base_name}_error.log\n    CustomLog ${{APACHE_LOG_DIR}}/{config.container_base_name}_access.log combined\n\n    # For most configuration files from conf-available/, which are\n    # enabled or disabled at a global level, it is possible to\n    # include a line for only one particular virtual host. For example the\n    # following line enables the CGI configuration for this host only\n    # after it has been globally disabled with \"a2disconf\".\n    #Include conf-available/serve-cgi-bin.conf\n\n    # Mediawiki installations\n    ProxyPass / http://localhost:{config.port}/\n    ProxyPassReverse / http://localhost:{config.port}/\n</VirtualHost>\"\"\"\n        return apache_config\n
"},{"location":"#profiwiki.profiwiki_core.ProfiWiki.check","title":"check(mwApp)","text":"

check

Source code in profiwiki/profiwiki_core.py
def check(self, mwApp):\n    \"\"\"\n    check\n    \"\"\"\n    mwApp.check()\n
"},{"location":"#profiwiki.profiwiki_core.ProfiWiki.check_wikiuser","title":"check_wikiuser(mwApp)","text":"Source code in profiwiki/profiwiki_core.py
def check_wikiuser(self, mwApp: DockerApplication):\n    \"\"\" \"\"\"\n    print(f\"Checking WikiUser ... for {mwApp.config.container_base_name}\")\n    wikiUsers = WikiUser.getWikiUsers(lenient=True)\n    if not mwApp.config.wikiId:\n        print(\"no WikiId configured\")\n        return\n    if not mwApp.config.wikiId in wikiUsers:\n        print(f\"no wikiUser for wikiId {mwApp.config.wikiId} found\")\n        return\n    wikiUser = wikiUsers[mwApp.config.wikiId]\n    if mwApp.config.password != wikiUser.getPassword():\n        print(f\"configured password is different then {mwApp.config.wikiId}\")\n    else:\n        print(\n            f\"wikiUser for wikiId {mwApp.config.wikiId} is available and password as configured\"\n        )\n    pass\n
"},{"location":"#profiwiki.profiwiki_core.ProfiWiki.create","title":"create(mwApp, forceRebuild=False)","text":"

create a profiwiki mediawiki

Source code in profiwiki/profiwiki_core.py
def create(self, mwApp, forceRebuild: bool = False):\n    \"\"\"\n    create a profiwiki mediawiki\n    \"\"\"\n    mwApp.start(forceRebuild=forceRebuild)\n
"},{"location":"#profiwiki.profiwiki_core.ProfiWiki.down","title":"down(mwApp, forceRebuild=False)","text":"

shut down the profiwiki base mediawiki

Source code in profiwiki/profiwiki_core.py
def down(self, mwApp, forceRebuild: bool = False):\n    \"\"\"\n    shut down the profiwiki base mediawiki\n    \"\"\"\n    mwApp.down(forceRebuild=forceRebuild)\n
"},{"location":"#profiwiki.profiwiki_core.ProfiWiki.getMwApp","title":"getMwApp(withGenerate=True)","text":"

get my mediawiki Docker application

Source code in profiwiki/profiwiki_core.py
def getMwApp(self, withGenerate: bool = True):\n    \"\"\"\n    get my mediawiki Docker application\n    \"\"\"\n    mwCluster = self.getMwCluster(withGenerate)\n    if not self.config.version in mwCluster.apps:\n        raise Exception(f\"Mediawiki version {self.config.version} missing {mwCluster.apps.keys()}\")\n    mwApp = mwCluster.apps[self.config.version]\n    return mwApp\n
"},{"location":"#profiwiki.profiwiki_core.ProfiWiki.getMwCluster","title":"getMwCluster(withGenerate=True)","text":"

get a mediawiki Cluster for my configuration

Parameters:

Name Type Description Default withGenerate(bool)

if True regenerate the configuration files

required

Returns:

Name Type Description MediaWikiCluster MediaWikiCluster

the MediaWiki Cluser

Source code in profiwiki/profiwiki_core.py
def getMwCluster(self, withGenerate: bool = True) -> MediaWikiCluster:\n    \"\"\"\n    get a mediawiki Cluster for my configuration\n\n    Args:\n        withGenerate(bool): if True regenerate the configuration files\n\n    Returns:\n        MediaWikiCluster: the MediaWiki Cluser\n    \"\"\"\n    if self.mwCluster is not None:\n        return self.mwCluster\n    mwCluster = MediaWikiCluster(config=self.config)\n    # generate\n    mwCluster.createApps(withGenerate=withGenerate)\n    self.mwCluster = mwCluster\n    return mwCluster\n
"},{"location":"#profiwiki.profiwiki_core.ProfiWiki.getProfiWikiContainers","title":"getProfiWikiContainers(mwApp)","text":"

get the two containers - for mediawiki and the database

Parameters:

Name Type Description Default mwApp(DockerApplication)

the MediaWiki Docker Application

required

Returns:

Name Type Description Tuple (ProfiWikiContainer, ProfiWikiContainer)

MediaWiki, Database

Source code in profiwiki/profiwiki_core.py
def getProfiWikiContainers(self, mwApp: DockerApplication):\n    \"\"\"\n    get the two containers - for mediawiki and the database\n\n    Args:\n        mwApp(DockerApplication): the MediaWiki Docker Application\n\n    Returns:\n        Tuple(ProfiWikiContainer,ProfiWikiContainer): MediaWiki, Database\n    \"\"\"\n    mw, db = mwApp.getContainers()\n    pmw = ProfiWikiContainer(mw)\n    pdb = ProfiWikiContainer(db)\n    return pmw, pdb\n
"},{"location":"#profiwiki.profiwiki_core.ProfiWiki.list","title":"list(mwApp)","text":"

list the profi wikis

Source code in profiwiki/profiwiki_core.py
def list(self, mwApp):\n    \"\"\"\n    list the profi wikis\n    \"\"\"\n    print(json.dumps(mwApp.config.as_dict(), indent=2))\n    pass\n
"},{"location":"#profiwiki.profiwiki_core.ProfiWiki.patch","title":"patch(pwc)","text":"

apply profi wiki patches to the given ProfiWikiContainer

Source code in profiwiki/profiwiki_core.py
    def patch(self, pwc: ProfiWikiContainer):\n        \"\"\"\n        apply profi wiki patches to the given ProfiWikiContainer\n        \"\"\"\n        if not pwc.dc:\n            raise (\"no container to apply patch\")\n        ls_path = \"/var/www/html/LocalSettings.php\"\n        timestamp = datetime.datetime.utcnow().strftime(\"%Y-%m-%d\")\n        with tempfile.NamedTemporaryFile(\n            mode=\"w\", prefix=\"LocalSettings_\", suffix=\".php\"\n        ) as ls_file:\n            pwc.log_action(f\"patching {ls_file.name}\")\n            pwc.dc.container.copy_from(ls_path, ls_file.name)\n            patch = Patch(file_path=ls_file.name)\n            lines = f\"\"\"// modified by profiwiki\n// use WikiEditor e.g. for MsUpload\nwfLoadExtension( 'WikiEditor' );\n# make this an intranet - comment out if you want this to be a public wiki\n# The following permissions were set based on your choice in the installer\n$wgGroupPermissions['*']['createaccount'] = false;\n$wgGroupPermissions['*']['edit'] = false;\n$wgGroupPermissions['*']['read'] = false;\n# Allow properties in Templates\n$smwgNamespacesWithSemanticLinks[NS_TEMPLATE] = true;\n# WF 2015-01-20\n# allow string functions - needed for Template:Link\n$wgPFEnableStringFunctions=true;\n// allow raw HTML\n$wgRawHtml = true;\n// allow images\n$wgAllowImageTag=true;\n// InstantCommons allows wiki to use images from https://commons.wikimedia.org\n$wgUseInstantCommons = true;\n// avoid showing (expected) deprecation warnings\nerror_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE);\n# # add support for special properties\n# see https://www.semantic-mediawiki.org/wiki/Help:$smwgPageSpecialProperties\n# Modification date\n$smwgPageSpecialProperties[] = '_MDAT';\n# Creation date\n$smwgPageSpecialProperties[] = '_CDAT';\n# Is a new page\n$smwgPageSpecialProperties[] = '_NEWP';\n# Last editor is\n$smwgPageSpecialProperties[] = '_LEDT';\n# Media type\n$smwgPageSpecialProperties[] = '_MEDIA';\n# MIME type\n$smwgPageSpecialProperties[] = '_MIME';\n// https://www.mediawiki.org/wiki/Extension:UserFunctions\n$wgUFEnabledPersonalDataFunctions = ['ip','nickname','realname','useremail','username',];\n// allow user functions in main mediawiki space\n$wgUFAllowedNamespaces[NS_MAIN] = true;\n# increase query limit\n$smwgQMaxLimit = 20000;\n//Default width for the PDF object container.\n$wgPdfEmbed['width'] = 800;\n//Default height for the PDF object container.\n$wgPdfEmbed['height'] = 1090;\n//Allow user the usage of the tag\n$wgGroupPermissions['*']['embed_pdf'] = true;\n// config parameters for MsUpload\n// https://www.mediawiki.org/wiki/Extension:MsUpload\n$wgMSU_useDragDrop = true; // Should the drag & drop area be shown? (Not set by default)\n$wgMSU_showAutoCat = true; // Files uploaded while editing a category page will be added to that category\n$wgMSU_checkAutoCat = true; // Whether the checkbox for adding a category to a page is checked by default\n$wgMSU_useMsLinks = false; // Insert links in Extension:MsLinks style?\n$wgMSU_confirmReplace = true; // Show the \"Replace file?\" checkbox\n$wgMSU_imgParams = '400px'; // Default image parameters, for example \"thumb|200px\"\n$wgMSU_uploadsize = '100mb'; // Max upload size through MsUpload\n// general parameters for MsUpload\n$wgEnableWriteAPI = true; // Enable the API\n$wgEnableUploads = true; // Enable uploads\n$wgAllowJavaUploads = true; // Solves problem with Office 2007 and newer files (docx, xlsx, etc.)\n$wgGroupPermissions['user']['upload'] = true; // Allow regular users to upload files\n# add more file upload options\n$wgGroupPermissions['user']['upload_by_url'] = true;\n$wgAllowCopyUploads = true;\n$wgCopyUploadsFromSpecialUpload = true;\n# http://www.mediawiki.org/wiki/Manual:Configuring_file_uploads/de\n$wgFileExtensions = array_merge($wgFileExtensions, array('doc', 'gcode',\n'gpx','htm','html','jscad','jpg','pdf','ppt','docx', 'docxm','xlsx','xlsm','mp3','mp4','odp','otp','pptx', 'pptm','reqif','reqifz','rtf','rythm'\n,'scad','sh','stl','svg','vcf','vim','uew','xls','xml','zip'));\n# allow html\n$wgVerifyMimeType=false;\n# disable upload script checks ...\n$wgDisableUploadScriptChecks = true;\n\"\"\"\n            patch.add_text(lines)\n            patch.save()\n            pwc.dc.container.copy_to(ls_file.name, ls_path)\n
"},{"location":"#profiwiki.profiwiki_core.ProfiWiki.system_info","title":"system_info()","text":"

collect system information

Source code in profiwiki/profiwiki_core.py
def system_info(self) -> str:\n    \"\"\"\n    collect system information\n    \"\"\"\n    info = f\"\"\"os: {self.os_name}\"\"\"\n    if \"Darwin\" in info:\n        release, _version, _machine = platform.mac_ver()\n        info += f\" MacOS {release}\"\n    else:\n        info += f\"{self.os_release}\"\n    return info\n
"},{"location":"#profiwiki.profiwiki_core.ProfiWiki.update","title":"update(mwApp)","text":"

run the update script

Source code in profiwiki/profiwiki_core.py
def update(self, mwApp):\n    \"\"\"\n    run the update script\n    \"\"\"\n    mwApp.execute(\"/root/update.sh\")\n
"},{"location":"#profiwiki.profiwiki_core.ProfiWiki.work","title":"work(args)","text":"

work as instructed by the arguments

Parameters:

Name Type Description Default args(Namespace)

the command line arguments

required Source code in profiwiki/profiwiki_core.py
def work(self, args):\n    \"\"\"\n    work as instructed by the arguments\n\n    Args:\n        args(Namespace): the command line arguments\n    \"\"\"\n    self.config.fromArgs(args)\n    # make sure the wikiId is set from the container base name\n    config_path = self.config.get_config_path()\n    if os.path.isfile(config_path) and not self.config.forceRebuild:\n        # reload the previous configuration e.g. based on container_name only\n        previous_config = self.config.load(config_path)\n        if self.config.verbose:\n            print(f\"ProfiWiki with previous configuration from {config_path}...\")\n        self.config = previous_config\n    self.config.wikiId = self.config.container_base_name\n    if args.bash:\n        cmd = f\"docker exec -it {self.config.container_base_name}-mw /bin/bash\"\n        print(cmd)\n        return\n    mwApp = self.getMwApp(withGenerate=args.forceRebuild)\n    if self.config.verbose:\n        print(\n            f\"ProfiWiki {mwApp.config.container_base_name} using port {mwApp.config.port} sqlport {mwApp.config.sql_port}\"\n        )\n    if args.force_user:\n        mwApp.createWikiUser(store=True)\n    if args.all:\n        self.create(mwApp, args.forceRebuild)\n        pmw, _pdb = self.getProfiWikiContainers(mwApp)\n        pmw.install_fontawesome()\n        pmw.install_plantuml()\n        self.patch(pmw)\n        self.update(mwApp)\n        pmw.start_cron()\n    if args.wikiuser_check:\n        self.check_wikiuser(mwApp)\n    if args.apache:\n        apache_config = self.apache_config(mwApp)\n        print(apache_config)\n    if args.create:\n        self.create(mwApp, args.forceRebuild)\n    if args.check:\n        self.check(mwApp)\n    if args.down:\n        self.down(mwApp, args.forceRebuild)\n    if args.list:\n        self.list(mwApp)\n    if args.plantuml or args.fontawesome or args.cron or args.patch:\n        pmw, _pdb = self.getProfiWikiContainers(mwApp)\n        if args.plantuml:\n            pmw.install_plantuml()\n        if args.fontawesome:\n            pmw.install_fontawesome()\n        if args.cron:\n            pmw.start_cron()\n        if args.patch:\n            self.patch(pmw)\n    if args.update:\n        self.update(mwApp)\n
"},{"location":"#profiwiki.version","title":"version","text":"

Created on 2023-04-01

@author: wf

"},{"location":"#profiwiki.version.Version","title":"Version","text":"

Bases: object

Version handling for ProfiWiki

Source code in profiwiki/version.py
class Version(object):\n    \"\"\"\n    Version handling for ProfiWiki\n    \"\"\"\n\n    name = \"pyProfiWiki\"\n    description = \"\"\"BITPlan's professional Semantic Mediawiki\"\"\"\n    version = profiwiki.__version__\n    date = \"2023-04-01\"\n    updated = \"2024-08-02\"\n    authors = \"Wolfgang Fahl\"\n    doc_url = \"https://wiki.bitplan.com/index.php/ProfiWiki\"\n    chat_url = \"https://github.com/BITPlan/ProfiWiki/discussions\"\n    cm_url = \"https://github.com/BITPlan/ProfiWiki\"\n    license = f\"\"\"Copyright 2015-2024 contributors. All rights reserved.\n  Licensed under the Apache License 2.0\n  http://www.apache.org/licenses/LICENSE-2.0\n  Distributed on an \"AS IS\" basis without warranties\n  or conditions of any kind, either express or implied.\"\"\"\n    longDescription = f\"\"\"{name} version {version}\n{description}\n  Created by {authors} on {date} last updated {updated}\"\"\"\n
"}]} \ No newline at end of file diff --git a/sitemap.xml.gz b/sitemap.xml.gz index e980b1e68fbd8c06fbbede3fe8d9a1c86ef4c6ac..4991c0a2aad0ef4682584276913e11ddb6e8b6e3 100644 GIT binary patch delta 13 Ucmb=gXP58h;CK+Wb|QNP03R&`vj6}9 delta 13 Ucmb=gXP58h;7DLyGm*Ul02-77;Q#;t