Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deactivate exists checks for page trail and ignore non-existent items #1782

Merged
merged 2 commits into from
Oct 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/moin/_tests/test_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,10 +217,10 @@ def test_trail(self):
assert result == expected

# item name added to trail
theUser.add_trail("item_added")
theUser.add_trail("item_added", [])
theUser = user.User(name=name, password=password)
result = theUser.get_trail()
expected = ["MoinTest/item_added"]
expected = [("MoinTest/item_added", [])]
assert result == expected

# Sessions -------------------------------------------------------
Expand Down
9 changes: 5 additions & 4 deletions src/moin/apps/frontend/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@
from moin import user
from moin.constants.keys import * # noqa
from moin.constants.namespaces import * # noqa
from moin.constants.itemtypes import ITEMTYPE_DEFAULT, ITEMTYPE_TICKET
from moin.constants.itemtypes import ITEMTYPE_DEFAULT, ITEMTYPE_TICKET, ITEMTYPE_NONEXISTENT
from moin.constants.contenttypes import * # noqa
from moin.constants.rights import SUPERUSER
from moin.constants.misc import FLASH_REPEAT
Expand Down Expand Up @@ -524,14 +524,14 @@ def add_presenter(wrapped, view, add_trail=False, abort404=True):
@frontend.route(f"/+{view}/<itemname:item_name>", defaults=dict(rev=CURRENT))
@wraps(wrapped)
def wrapper(item_name, rev):
if add_trail:
flaskg.user.add_trail(item_name)
try:
item = Item.create(item_name, rev_id=rev)
except AccessDenied:
abort(403)
if abort404 and isinstance(item, NonExistent):
abort(404, item_name)
if add_trail:
flaskg.user.add_trail(item_name, aliases=item.meta.revision.fqnames)
return wrapped(item)

return wrapper
Expand Down Expand Up @@ -588,7 +588,8 @@ def show_item(item_name, rev):
return redirect(url_for_item(fqname))
try:
item = Item.create(item_name, rev_id=rev)
flaskg.user.add_trail(item_name)
if item.itemtype != ITEMTYPE_NONEXISTENT:
flaskg.user.add_trail(item_name, aliases=item.meta.revision.fqnames)
item_is_deleted = flash_if_item_deleted(item_name, rev, item)
item_may = get_item_permissions(fqname, item)
result = item.do_show(rev, item_is_deleted=item_is_deleted, item_may=item_may)
Expand Down
18 changes: 9 additions & 9 deletions src/moin/templates/utils.html
Original file line number Diff line number Diff line change
Expand Up @@ -233,13 +233,13 @@
{%- endif %}
{%- endmacro -%}

{% macro page_trail_link(wiki_name, fqname, exists) %}
{% macro page_trail_link(wiki_name, fqname) %}
{%- if wiki_name -%}
<a href="{{ item_href }}"{{ " " }} title="{{ wiki_name }}" class="{% if err %}moin-badinterwiki{% else %}moin-interwiki{% endif %}">
{{ fqname|shorten_fqname }}
</a>
{%- else -%}
<a href="{{ url_for('frontend.show_item', item_name=fqname) }}"{{ " " }} {% if not exists -%}class="moin-nonexistent"{%- endif -%}>
<a href="{{ url_for('frontend.show_item', item_name=fqname) }}"{{ " " }}>
{{ fqname|shorten_fqname }}
</a>
{%- endif %}
Expand All @@ -257,30 +257,30 @@
<li class="moin-panel-heading">{{ _('Page Trail') }}</li>
{%- set trail_items = breadcrumbs() %}
{%- if trail_items %}
{%- for wiki_name, fqname, item_href, exists, err in trail_items %}
{%- for wiki_name, fqname, item_href, aliases, err in trail_items %}
{%- if not loop.last %}
<li>
{{ page_trail_link(wiki_name, fqname, exists) }}
{{ alias_list(theme_supp.get_fqnames(fqname)) }}
{{ page_trail_link(wiki_name, fqname) }}
{{ alias_list(aliases) }}
<i class="fa fa-angle-double-right fa-fw"></i>
</li>
{%- endif %}
{%- if loop.last %}
<li>
<span class="moin-big">
{%- for segment_name, segment_path, exists in theme_supp.location_breadcrumbs(fqname) -%}
{%- for segment_name, segment_path in theme_supp.location_breadcrumbs(fqname) -%}
{%- if not loop.last %}
<a href="{{ url_for('frontend.show_item', item_name=segment_path) }}" {%- if not exists -%}class="moin-nonexistent"{%- endif -%}>
<a href="{{ url_for('frontend.show_item', item_name=segment_path) }}">
{{ segment_name|shorten_fqname }}
</a>
{%- else %}
<a href="{{ url_for('frontend.show_item', item_name=segment_path) }}" {% if not exists %}class="moin-nonexistent"{% endif %}>
<a href="{{ url_for('frontend.show_item', item_name=segment_path) }}">
{{ segment_name|shorten_fqname }}
</a>
{%- endif %}
{%- endfor %}
</span>
{{ alias_list(theme_supp.get_fqnames(fqname)) }}
{{ alias_list(aliases) }}
</li>
{%- if title_name %}
<li>
Expand Down
23 changes: 4 additions & 19 deletions src/moin/themes/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -332,14 +332,13 @@ def location_breadcrumbs(self, fqname):
namespace as a prefix.

:rtype: list
:returns: location breadcrumbs items in tuple (segment_name, fq_name, exists)
:returns: location breadcrumbs items in tuple (segment_name, fq_name)
"""
breadcrumbs = []
current_item = ""
if not isinstance(fqname, CompositeName):
fqname = split_fqname(fqname)
if fqname.field != NAME_EXACT:
# flaskg.unprotected_storage.get_item(**fqname.query)
return [(fqname, fqname, bool(self.storage.get_item(**fqname.query)))]
namespace = segment1_namespace = fqname.namespace
item_name = fqname.value
Expand All @@ -349,7 +348,7 @@ def location_breadcrumbs(self, fqname):
current_item += segment
fq_current = CompositeName(namespace, NAME_EXACT, current_item)
fq_segment = CompositeName(segment1_namespace, NAME_EXACT, segment)
breadcrumbs.append((fq_segment, fq_current, bool(self.storage.get_item(**fq_current.query))))
breadcrumbs.append((fq_segment, fq_current))
current_item += "/"
segment1_namespace = ""
return breadcrumbs
Expand All @@ -364,18 +363,15 @@ def path_breadcrumbs(self):
user = self.user
breadcrumbs = []
trail = user.get_trail()
for interwiki_item_name in trail:
for interwiki_item_name, aliases in trail:
wiki_name, namespace, field, item_name = split_interwiki(interwiki_item_name)
fqname = CompositeName(namespace, field, item_name)
err = not is_known_wiki(wiki_name)
href = url_for_item(wiki_name=wiki_name, **fqname.split)
if is_local_wiki(wiki_name):
exists = bool(self.storage.get_item(**fqname.query))
wiki_name = "" # means "this wiki" for the theme code
else:
exists = True # we can't detect existance of remote items
if item_name:
breadcrumbs.append((wiki_name, fqname, href, exists, err))
breadcrumbs.append((wiki_name, fqname, href, aliases, err))
return breadcrumbs

def userhome(self):
Expand Down Expand Up @@ -561,17 +557,6 @@ def login_url(self):
url = url or url_for("frontend.login")
return url

def get_fqnames(self, fqname):
"""
Return the list of other fqnames associated with the item.
"""
if fqname.field != NAME_EXACT:
return []
item = self.storage.get_item(**fqname.query)
fqnames = item.fqnames
fqnames.remove(fqname)
return fqnames or []

def get_namespaces(self, ns=None):
"""
Return the list of tuples (composite name, namespace) referring to namespaces other
Expand Down
12 changes: 6 additions & 6 deletions src/moin/themes/_tests/test_navi_bar.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ def test_split_navilink(self, theme):

def test_location_breadcrumbs(self, theme):
test_result = ThemeSupport.location_breadcrumbs(theme, "some/place/test_item")
test_segment_name_1, test_item_name_1, test_item_exists_1 = test_result[0]
test_segment_name_2, test_item_name_2, test_item_exists_2 = test_result[1]
test_segment_name_3, test_item_name_3, test_item_exists_3 = test_result[2]
test_segment_name_1, test_item_name_1 = test_result[0]
test_segment_name_2, test_item_name_2 = test_result[1]
test_segment_name_3, test_item_name_3 = test_result[2]

assert test_segment_name_1.namespace == ""
assert test_item_name_1.namespace == ""
Expand All @@ -59,9 +59,9 @@ def test_location_breadcrumbs(self, theme):
assert test_item_name_3.value == "some/place/test_item"

test_result = ThemeSupport.location_breadcrumbs(theme, "users/some/place/test_item")
test_segment_name_1, test_item_name_1, test_item_exists_1 = test_result[0]
test_segment_name_2, test_item_name_2, test_item_exists_2 = test_result[1]
test_segment_name_3, test_item_name_3, test_item_exists_3 = test_result[2]
test_segment_name_1, test_item_name_1 = test_result[0]
test_segment_name_2, test_item_name_2 = test_result[1]
test_segment_name_3, test_item_name_3 = test_result[2]

assert test_segment_name_1.namespace == "users"
assert test_item_name_1.namespace == "users"
Expand Down
24 changes: 18 additions & 6 deletions src/moin/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
from moin.constants.misc import ANON
from moin.i18n import _
from moin.mail import sendmail
from moin.utils.interwiki import getInterwikiHome, getInterwikiName
from moin.utils.interwiki import getInterwikiHome, getInterwikiName, CompositeName
from moin.utils.crypto import generate_token, valid_token, make_uuid
from moin.utils.subscriptions import get_matched_subscription_patterns
from moin.storage.error import NoSuchItemError, NoSuchRevisionError
Expand Down Expand Up @@ -732,27 +732,39 @@ def quickunlink(self, pagename):

# Trail ------------------------------------------------------------------

def add_trail(self, item_name):
def add_trail(self, item_name, aliases=None):
"""Add item name to trail.
Store aliases as tuple

:param item_name: the item name (unicode) to add to the trail
:param aliases: a list of aliases for this item
"""
full_name = item_name
item_name = getInterwikiName(item_name)
trail_in_session = session.get("trail", [])
trail = trail_in_session[:]
trail = [i for i in trail if i != item_name] # avoid dupes
trail.append(item_name) # append current item name at end
aliases_trail = []
for alias in aliases:
if alias.fullname != full_name:
aliases_trail.append((alias.namespace, alias.field, alias.value))
trail = [i for i in trail if i != (item_name, aliases_trail)] # avoid dupes
trail.append((item_name, aliases_trail)) # append current item name and aliases at end
trail = trail[-self._cfg.trail_size :] # limit trail length
if trail != trail_in_session:
session["trail"] = trail

def get_trail(self):
"""Return list of recently visited item names.

convert aliases to CompositeName
:rtype: list
:returns: item names (unicode) in trail
"""
return session.get("trail", [])
trail_session = session.get("trail", [])
trail = []
for entry in trail_session:
aliases = [CompositeName(*alias) for alias in entry[1]]
trail.append((entry[0], aliases))
return trail

# Other ------------------------------------------------------------------

Expand Down