diff --git a/pages/__init__.py b/pages/__init__.py index 15fe195..ee5b9bf 100644 --- a/pages/__init__.py +++ b/pages/__init__.py @@ -1,4 +1,6 @@ +from datetime import datetime from django.urls.base import reverse +import zoneinfo def url_page(request, rel_path, **kwargs): @@ -18,3 +20,12 @@ def url_edit(request, rel_path): def get_search_query(request): return request.GET.get('q') + + +def timestamp_to_datetime(request, tm): + from users.models import get_userprofile + # + up = get_userprofile(request.user) + tz = zoneinfo.ZoneInfo(up.timezone) + # + return datetime.fromtimestamp(tm, tz) diff --git a/pages/help.py b/pages/help.py index e49d25b..322ed9b 100644 --- a/pages/help.py +++ b/pages/help.py @@ -34,8 +34,47 @@ ACCESS = mycreole.render_simple(_(""" = TBD """)) -SEARCH = mycreole.render_simple(_(""" -= TBD +SEARCH = mycreole.render_simple(_( + """ += Search +The search looks up full words in //title (page basename)// and //page_src (the creole source)// without giving \ +special search commands in the search string. + +=== Search fields +* title (TEXT) +* page_src (TEXT) +* creation_time (DATETIME) +* modified_time (DATETIME) +* modified_user (TEXT) + +== Search syntax (Whoosh) +=== Logic operators +* AND +** **Example:** "foo AND bar" - Search will find all items with foo and bar. +* OR +** **Example:** "foo OR bar" - Search will find all items with foo, bar or with foo and bar. +* NOT +** **Example:** "foo NOT bar" - Search will find all items with foo and no bar. +=== Search in specific fields +A search pattern like //foo:bar// does look for //bar// in the field named //foo//. + +This search pattern can also be combined with other search text via logical operators. +=== Search for specific content +* **Wildcards:** +* **Range:** +** From To: +** Above: +** Below: +* **Named constants:** +** //now//: Current date +** //-[num]y//: Current date minus [num] years +** //+[num]mo//: Current date plus [num] months +** //-[num]d//: Current date minus [num] days +** ... + +== Examples +* [[/search/?q=modified_user:system-page|modified_user:system-page]] results in a list of all system pages. +* [[/search/?q=modified_time%3A%5B-5d+to+now%5D| modified_time:[-5d to now] ]] results in a list of all pages which have been modified within the last 5 days. """)) help_pages = { diff --git a/pages/page.py b/pages/page.py index 5b00b5b..0cf5fbd 100644 --- a/pages/page.py +++ b/pages/page.py @@ -1,4 +1,3 @@ -from datetime import datetime from django.conf import settings from django.utils.translation import gettext as _ import fstools @@ -9,8 +8,7 @@ import mycreole import os import shutil import time -from users.models import get_userprofile -import zoneinfo +from . import timestamp_to_datetime logger = logging.getLogger(settings.ROOT_LOGGER_NAME).getChild(__name__) @@ -167,14 +165,8 @@ class creole_page(base_page): return "" def render_meta(self): - def str_date(tm): - up = get_userprofile(self._request.user) - tz = zoneinfo.ZoneInfo(up.timezone) - # - return datetime.fromtimestamp(tm, tz).strftime('%Y-%m-%d %H:%M') - # - ctime = str_date(self._meta_data.get(self._meta_data.KEY_CREATION_TIME)) - mtime = str_date(self._meta_data.get(self._meta_data.KEY_MODIFIED_TIME)) + ctime = timestamp_to_datetime(self._meta_data.get(self._meta_data.KEY_CREATION_TIME)).strftime('%Y-%m-%d %H:%M') + mtime = timestamp_to_datetime(self._meta_data.get(self._meta_data.KEY_MODIFIED_TIME)).strftime('%Y-%m-%d %H:%M') user = self._meta_data.get(self._meta_data.KEY_MODIFIED_USER) # meta = f'|{_("Created")}:|{ctime}|\n' diff --git a/pages/search.py b/pages/search.py index 26db305..d6e0442 100644 --- a/pages/search.py +++ b/pages/search.py @@ -1,9 +1,10 @@ +from datetime import datetime from django.conf import settings import fstools import logging import os -from whoosh.fields import Schema, ID, TEXT +from whoosh.fields import Schema, ID, TEXT, DATETIME from whoosh.qparser.dateparse import DateParserPlugin from whoosh import index, qparser @@ -16,7 +17,11 @@ SCHEMA = Schema( id=ID(unique=True, stored=True), # Page title=TEXT, - page_src=TEXT + page_src=TEXT, + # metadata + creation_time=DATETIME, + modified_time=DATETIME, + modified_user=TEXT ) @@ -55,8 +60,13 @@ def add_item(ix, bp: base_page): # data = dict( id=bp.rel_path, + # title=bp.title, - page_src=bp.raw_page_src + page_src=bp.raw_page_src, + # + creation_time=datetime.fromtimestamp(bp._meta_data.get(bp._meta_data.KEY_CREATION_TIME)), + modified_time=datetime.fromtimestamp(bp._meta_data.get(bp._meta_data.KEY_MODIFIED_TIME)), + modified_user=bp._meta_data.get(bp._meta_data.KEY_MODIFIED_USER) ) with ix.writer() as w: logger.info('Adding document with id=%s to the search index.', data.get('id')) @@ -93,4 +103,3 @@ def update_item(bp: base_page): ix = load_index() delete_item(ix, bp) add_item(ix, bp) - diff --git a/pages/views.py b/pages/views.py index 8f176c1..c6da829 100644 --- a/pages/views.py +++ b/pages/views.py @@ -1,4 +1,5 @@ from django.conf import settings +from django.contrib import messages as django_messages from django.shortcuts import render from django.http import HttpResponse, HttpResponseRedirect from django.utils.translation import gettext as _ @@ -107,7 +108,7 @@ def search(request): sr = whoosh_search(search_txt) if sr is None: - messages.error(request, _('Invalid search pattern: %s') % repr(search_txt)) + django_messages.error(request, _('Invalid search pattern: %s') % repr(search_txt)) sr = [] page_content = "= Searchresults\n" for rel_path in sr: