From 87fba6bd157caef67629da28ec0f4fe11c6c7a8b Mon Sep 17 00:00:00 2001 From: RogerHaase Date: Wed, 21 Feb 2024 07:47:35 -0700 Subject: [PATCH] import19 lacks support for UserGroup and WikiDict conversion; fixes #1595 Added 2 macros to display usergroup and wikidict attributes. --- src/moin/cli/migration/moin19/import19.py | 53 +++++++++++++++++++++++ src/moin/macros/ShowUserGroup.py | 22 ++++++++++ src/moin/macros/ShowWikiDict.py | 22 ++++++++++ src/moin/macros/_base.py | 10 +++++ 4 files changed, 107 insertions(+) create mode 100644 src/moin/macros/ShowUserGroup.py create mode 100644 src/moin/macros/ShowWikiDict.py diff --git a/src/moin/cli/migration/moin19/import19.py b/src/moin/cli/migration/moin19/import19.py index 230617280..477ee34f9 100644 --- a/src/moin/cli/migration/moin19/import19.py +++ b/src/moin/cli/migration/moin19/import19.py @@ -229,6 +229,12 @@ def ImportMoin19(data_dir=None, markup_out=None, namespace=None): # bumping modified time makes global and item history views more useful meta[MTIME] = meta[MTIME] + 1 meta[COMMENT] = 'Converted moin 1.9 markup to ' + markup_out + ' markup' + if meta[NAME][0].endswith('Group') and meta[USERGROUP]: + msg = 'Moin1.x user list moved to User Group metadata; item content ignored. Use ShowUserGroup macro. ' + meta[COMMENT] = msg + meta[COMMENT] + if meta[NAME][0].endswith('Dict') and meta[WIKIDICT]: + msg = 'Moin1.x Wiki Dict data moved to Wiki Dict metadata; item content ignored. Use ShowWikiDict macro. ' + meta[COMMENT] = msg + meta[COMMENT] meta[CONTENTTYPE] = CONTENTTYPE_MARKUP_OUT[markup_out] del meta[DATAID] out.seek(0) @@ -457,6 +463,11 @@ def __init__(self, item, revno, path, target_namespace): meta[TAGS].append(TEMPLATE) else: meta[TAGS] = [TEMPLATE] + if meta[NAME][0].endswith('Group'): + meta[USERGROUP] = self._parse_acl_list(content) + if meta[NAME][0].endswith('Dict'): + meta[WIKIDICT] = self._parse_wikidict(content) + # if this revision matches a custom namespace defined in wikiconfig, # then modify the meta data for namespace and name for custom_namespace in custom_namespaces: @@ -514,6 +525,48 @@ def _process_data(self, meta, data): data = process_categories(meta, data, self.backend.item_category_regex) return data + def _parse_acl_list(self, content): + """ + Return ACL list extracted from item's content + """ + ret = [] + first_user = True + start = 'not a hit yet' + lines = content.splitlines() + for line in lines: + if first_user: + parts = line.split('*') + if len(parts) == 2 and parts[1].startswith(' '): + # only select lines with consistent indentation + start = parts[0] + '* ' + first_user = False + if line.startswith(start): + parts = line.split('*') + if len(parts) == 2 and parts[1].startswith(' '): + username = parts[1].strip() + # link conversion may have enclosed all links with [[...]], maybe a leading +/-: "+[[UserName]]" + if username.startswith('[[') and username.endswith(']]'): + ret.append(username[2:-2]) + elif username.startswith('+[[') or username.startswith('-[[') and username.endswith(']]'): + username.replace('[', '') + ret.append(username[:-2]) + else: + ret.append(username) + return ret + + def _parse_wikidict(self, content): + """ + Return a dict of key, value pairs: {key: val,...} + """ + ret = {} + lines = content.splitlines() + for line in lines: + line = line.strip() + parts = line.split(':: ') + if len(parts) == 2: + ret[parts[0]] = parts[1] + return ret + def migrate_itemlinks(dom, namespace, itemlinks2chg): """ Walk the DOM tree and change itemlinks to users namespace diff --git a/src/moin/macros/ShowUserGroup.py b/src/moin/macros/ShowUserGroup.py new file mode 100644 index 000000000..da9de4601 --- /dev/null +++ b/src/moin/macros/ShowUserGroup.py @@ -0,0 +1,22 @@ +# Copyright: 2024 MoinMoin:RogerHaase +# License: GNU GPL v2 (or any later version), see LICENSE.txt for details. + +""" +Show contents of UserGroup attribute in metadata. +""" + +from moin.macros._base import MacroBlockBase, fail_message +from moin.items import Item +from moin.constants.keys import USERGROUP +from moin.i18n import _ + + +class Macro(MacroBlockBase): + def macro(self, content, arguments, page_url, alternative): + url = str(page_url.path)[1:] + try: + item = Item.create(url) + return item.meta[USERGROUP] + except KeyError: + msg = _('ShowUserGroup macro failed - metadata lacks "usergroup" attribute.') + return fail_message(msg) diff --git a/src/moin/macros/ShowWikiDict.py b/src/moin/macros/ShowWikiDict.py new file mode 100644 index 000000000..0ab9a3899 --- /dev/null +++ b/src/moin/macros/ShowWikiDict.py @@ -0,0 +1,22 @@ +# Copyright: 2024 MoinMoin:RogerHaase +# License: GNU GPL v2 (or any later version), see LICENSE.txt for details. + +""" +Show contents of WikiDict attribute in metadata. +""" + +from moin.macros._base import MacroBlockBase, fail_message +from moin.items import Item +from moin.constants.keys import WIKIDICT +from moin.i18n import _ + + +class Macro(MacroBlockBase): + def macro(self, content, arguments, page_url, alternative): + url = str(page_url.path)[1:] + try: + item = Item.create(url) + return item.meta[WIKIDICT] + except KeyError: + msg = _('ShowWikiDict macro failed - metadata lacks "wikidict" attribute.') + return fail_message(msg) diff --git a/src/moin/macros/_base.py b/src/moin/macros/_base.py index a52e439b6..b23b60cad 100644 --- a/src/moin/macros/_base.py +++ b/src/moin/macros/_base.py @@ -9,6 +9,7 @@ import re from moin.utils import iri from moin.items import Item +from moin.utils.tree import html from moin.i18n import _ from werkzeug.exceptions import abort from moin.utils.tree import moin_page, xlink @@ -61,6 +62,15 @@ def get_item_names(name='', startswith='', kind='files', skiptag=''): return item_names +def fail_message(msg, severity='error'): + """ + Return an error message in admonition-like format. + + Severity may be: attention, caution, danger, error, hint, important, note, or tip. + """ + return html.div(attrib={html.class_: '{0} moin-nowiki'.format(severity)}, children=msg) + + class MacroBase: """ Macro base class.