1.1 --- a/actions/EventAggregatorUpdate.py Wed Jan 22 19:19:12 2014 +0100
1.2 +++ b/actions/EventAggregatorUpdate.py Fri Jan 24 22:53:15 2014 +0100
1.3 @@ -2,17 +2,17 @@
1.4 """
1.5 MoinMoin - EventAggregatorUpdate Action
1.6
1.7 - @copyright: 2012, 2013 by Paul Boddie <paul@boddie.org.uk>
1.8 + @copyright: 2012, 2013, 2014 by Paul Boddie <paul@boddie.org.uk>
1.9 @license: GNU GPL (v2 or later), see COPYING.txt for details.
1.10 """
1.11
1.12 from EventAggregatorSupport.Actions import get_date_functions
1.13 from EventAggregatorSupport import *
1.14 from MoinDateSupport import getParameterMonth
1.15 -from MoinMoin.Page import Page
1.16 -from MoinMoin import config
1.17 +from MoinMoin.Page import Page, is_cache_exception
1.18 +from MoinMoin import caching, config, log
1.19
1.20 -Dependencies = ['pages']
1.21 +logging = log.getLogger(__name__)
1.22
1.23 # Action function.
1.24
1.25 @@ -28,6 +28,15 @@
1.26 form = get_form(request)
1.27 page = Page(request, pagename)
1.28
1.29 + # Attempt to get any previously cached view.
1.30 +
1.31 + key = page.getCacheKey(request)
1.32 + cache = caching.CacheEntry(request, page, key, scope='item')
1.33 +
1.34 + if cache.exists():
1.35 + send(request, cache.content())
1.36 + return
1.37 +
1.38 # Find settings from the request parameters only.
1.39
1.40 calendar_name = form.get("calendar", [None])[0]
1.41 @@ -83,8 +92,24 @@
1.42 first, last, category_names, remote_sources, search_pattern, template_name,
1.43 parent_name, mode, raw_resolution, resolution, name_usage, map_name)
1.44
1.45 + output = view.render(all_shown_events)
1.46 +
1.47 + # Attempt to cache the output and then send it.
1.48 +
1.49 + try:
1.50 + page.enforceCacheLimit(request)
1.51 + cache.update(output.encode(config.charset))
1.52 + except caching.CacheError, exc:
1.53 + logging.warning("Could not cache output for EventAggregatorUpdate in page %s: %s" % (pagename, str(exc)))
1.54 +
1.55 + send(request, output)
1.56 +
1.57 +def send(request, output):
1.58 +
1.59 + "Send via the 'request' the given 'output' as a response."
1.60 +
1.61 send_headers = get_send_headers(request)
1.62 send_headers(["Content-Type: text/html; charset=%s" % config.charset])
1.63 - request.write(view.render(all_shown_events))
1.64 + request.write(output)
1.65
1.66 # vim: tabstop=4 expandtab shiftwidth=4
2.1 --- a/macros/EventAggregator.py Wed Jan 22 19:19:12 2014 +0100
2.2 +++ b/macros/EventAggregator.py Fri Jan 24 22:53:15 2014 +0100
2.3 @@ -14,7 +14,7 @@
2.4 from MoinDateSupport import getFormMonth
2.5 from MoinMoin import wikiutil
2.6
2.7 -Dependencies = ["pages"]
2.8 +Dependencies = ["pageparams"]
2.9
2.10 # Macro functions.
2.11
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/patches/pageparams-caching-1.8.diff Fri Jan 24 22:53:15 2014 +0100
3.3 @@ -0,0 +1,118 @@
3.4 +# HG changeset patch
3.5 +# User Paul Boddie <paul@boddie.org.uk>
3.6 +# Date 1390585706 -3600
3.7 +# Node ID 70250fe93a4f946e51eaa63accbb0152054ddab2
3.8 +# Parent d57b620213dd68126d2e5800f173d89f0602403a
3.9 +Added caching support for the "pageparams" dependency where the request
3.10 +parameters are combined with the page name to make a cache entry.
3.11 +
3.12 +diff -r d57b620213dd -r 70250fe93a4f MoinMoin/Page.py
3.13 +--- a/MoinMoin/Page.py Tue Jul 30 17:41:42 2013 +0200
3.14 ++++ b/MoinMoin/Page.py Fri Jan 24 18:48:26 2014 +0100
3.15 +@@ -41,6 +41,7 @@
3.16 +
3.17 + from MoinMoin import config, caching, user, util, wikiutil
3.18 + from MoinMoin.logfile import eventlog
3.19 ++from MoinMoin.support.python_compatibility import hash_new
3.20 +
3.21 + def is_cache_exception(e):
3.22 + args = e.args
3.23 +@@ -1336,7 +1337,7 @@
3.24 +
3.25 + def loadCache(self, request):
3.26 + """ Return page content cache or raises 'CacheNeedsUpdate' """
3.27 +- cache = caching.CacheEntry(request, self, self.getFormatterName(), scope='item')
3.28 ++ cache = caching.CacheEntry(request, self, self.getCacheKey(request), scope='item')
3.29 + attachmentsPath = self.getPagePath('attachments', check_create=0)
3.30 + if cache.needsUpdate(self._text_filename(), attachmentsPath):
3.31 + raise Exception('CacheNeedsUpdate')
3.32 +@@ -1357,7 +1358,7 @@
3.33 + """ Format content into code, update cache and return code """
3.34 + import marshal
3.35 + from MoinMoin.formatter.text_python import Formatter
3.36 +- formatter = Formatter(request, ["page"], self.formatter)
3.37 ++ formatter = Formatter(request, ["page", "pageparams"], self.formatter)
3.38 +
3.39 + # Save request state while formatting page
3.40 + saved_current_lang = request.current_lang
3.41 +@@ -1369,10 +1370,39 @@
3.42 + src = formatter.assemble_code(text)
3.43 + code = compile(src.encode(config.charset),
3.44 + self.page_name.encode(config.charset), 'exec')
3.45 +- cache = caching.CacheEntry(request, self, self.getFormatterName(), scope='item')
3.46 ++ self.enforceCacheLimit(request)
3.47 ++ cache = caching.CacheEntry(request, self, self.getCacheKey(request), scope='item')
3.48 + cache.update(marshal.dumps(code))
3.49 + return code
3.50 +
3.51 ++ def enforceCacheLimit(self, request):
3.52 ++ """ Prevent too many cache entries being stored for a page """
3.53 ++ keys = caching.get_cache_list(request, self, 'item')
3.54 ++ try:
3.55 ++ cache_limit = int(getattr(request.cfg, 'page_cache_limit', "10"))
3.56 ++ except ValueError:
3.57 ++ cache_limit = 10
3.58 ++
3.59 ++ if len(keys) >= cache_limit:
3.60 ++ items = [caching.CacheEntry(request, self, key, scope='item') for key in keys]
3.61 ++ item_ages = [(item.mtime(), item) for item in items]
3.62 ++ item_ages.sort()
3.63 ++ for item_age, item in item_ages[:-cache_limit]:
3.64 ++ item.remove()
3.65 ++
3.66 ++ def getCacheKey(self, request):
3.67 ++ """ Generate a cache key for a page using optional request information """
3.68 ++ key = self.getFormatterName()
3.69 ++ if request.args:
3.70 ++ args = request.args.items()
3.71 ++ args.sort()
3.72 ++ key_args = []
3.73 ++ for k, v in args:
3.74 ++ key_args.append("%s=%s" % (k, wikiutil.url_quote(v)))
3.75 ++ arg_str = "&".join(key_args)
3.76 ++ key = "%s:%s" % (key, hash_new('sha1', arg_str).hexdigest())
3.77 ++ return key
3.78 ++
3.79 + def _specialPageText(self, request, special_type):
3.80 + """ Output the default page content for new pages.
3.81 +
3.82 +# HG changeset patch
3.83 +# User Paul Boddie <paul@boddie.org.uk>
3.84 +# Date 1390599896 -3600
3.85 +# Node ID 02d1fa8951523776357a9a37235ad5c37f42fcc8
3.86 +# Parent 70250fe93a4f946e51eaa63accbb0152054ddab2
3.87 +Acquire the request formatter name when the page formatter has not yet been set.
3.88 +
3.89 +diff -r 70250fe93a4f -r 02d1fa895152 MoinMoin/Page.py
3.90 +--- a/MoinMoin/Page.py Fri Jan 24 18:48:26 2014 +0100
3.91 ++++ b/MoinMoin/Page.py Fri Jan 24 22:44:56 2014 +0100
3.92 +@@ -1240,15 +1240,17 @@
3.93 + request.formatter = old_formatter
3.94 +
3.95 +
3.96 +- def getFormatterName(self):
3.97 ++ def getFormatterName(self, request=None):
3.98 + """ Return a formatter name as used in the caching system
3.99 +
3.100 ++ @param request: the active request (optional)
3.101 + @rtype: string
3.102 + @return: formatter name as used in caching
3.103 + """
3.104 +- if not hasattr(self, 'formatter') or self.formatter is None:
3.105 ++ formatter = getattr(self, 'formatter', None) or request and getattr(request, 'formatter', None)
3.106 ++ if not formatter:
3.107 + return ''
3.108 +- module = self.formatter.__module__
3.109 ++ module = formatter.__module__
3.110 + return module[module.rfind('.') + 1:]
3.111 +
3.112 + def canUseCache(self, parser=None):
3.113 +@@ -1392,7 +1394,7 @@
3.114 +
3.115 + def getCacheKey(self, request):
3.116 + """ Generate a cache key for a page using optional request information """
3.117 +- key = self.getFormatterName()
3.118 ++ key = self.getFormatterName(request)
3.119 + if request.args:
3.120 + args = request.args.items()
3.121 + args.sort()
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/patches/pageparams-caching-1.9.diff Fri Jan 24 22:53:15 2014 +0100
4.3 @@ -0,0 +1,118 @@
4.4 +# HG changeset patch
4.5 +# User Paul Boddie <paul@boddie.org.uk>
4.6 +# Date 1390585938 -3600
4.7 +# Node ID 71d9815d2e6f5487ec87c4f5c04e5a156ffd21d3
4.8 +# Parent 5738b78f53b540ece0b48efa49b63fa4cbc09be9
4.9 +Added caching support for the "pageparams" dependency where the request
4.10 +parameters are combined with the page name to make a cache entry.
4.11 +
4.12 +diff -r 5738b78f53b5 -r 71d9815d2e6f MoinMoin/Page.py
4.13 +--- a/MoinMoin/Page.py Sat Nov 30 20:09:43 2013 +0100
4.14 ++++ b/MoinMoin/Page.py Fri Jan 24 18:52:18 2014 +0100
4.15 +@@ -41,6 +41,7 @@
4.16 +
4.17 + from MoinMoin import config, caching, user, util, wikiutil
4.18 + from MoinMoin.logfile import eventlog
4.19 ++from MoinMoin.support.python_compatibility import hash_new
4.20 +
4.21 + def is_cache_exception(e):
4.22 + args = e.args
4.23 +@@ -1351,7 +1352,7 @@
4.24 +
4.25 + def loadCache(self, request):
4.26 + """ Return page content cache or raises 'CacheNeedsUpdate' """
4.27 +- cache = caching.CacheEntry(request, self, self.getFormatterName(), scope='item')
4.28 ++ cache = caching.CacheEntry(request, self, self.getCacheKey(request), scope='item')
4.29 + attachmentsPath = self.getPagePath('attachments', check_create=0)
4.30 + if cache.needsUpdate(self._text_filename(), attachmentsPath):
4.31 + raise Exception('CacheNeedsUpdate')
4.32 +@@ -1372,7 +1373,7 @@
4.33 + """ Format content into code, update cache and return code """
4.34 + import marshal
4.35 + from MoinMoin.formatter.text_python import Formatter
4.36 +- formatter = Formatter(request, ["page"], self.formatter)
4.37 ++ formatter = Formatter(request, ["page", "pageparams"], self.formatter)
4.38 +
4.39 + # Save request state while formatting page
4.40 + saved_current_lang = request.current_lang
4.41 +@@ -1384,10 +1385,39 @@
4.42 + src = formatter.assemble_code(text)
4.43 + code = compile(src.encode(config.charset),
4.44 + self.page_name.encode(config.charset), 'exec')
4.45 +- cache = caching.CacheEntry(request, self, self.getFormatterName(), scope='item')
4.46 ++ self.enforceCacheLimit(request)
4.47 ++ cache = caching.CacheEntry(request, self, self.getCacheKey(request), scope='item')
4.48 + cache.update(marshal.dumps(code))
4.49 + return code
4.50 +
4.51 ++ def enforceCacheLimit(self, request):
4.52 ++ """ Prevent too many cache entries being stored for a page """
4.53 ++ keys = caching.get_cache_list(request, self, 'item')
4.54 ++ try:
4.55 ++ cache_limit = int(getattr(request.cfg, 'page_cache_limit', "10"))
4.56 ++ except ValueError:
4.57 ++ cache_limit = 10
4.58 ++
4.59 ++ if len(keys) >= cache_limit:
4.60 ++ items = [caching.CacheEntry(request, self, key, scope='item') for key in keys]
4.61 ++ item_ages = [(item.mtime(), item) for item in items]
4.62 ++ item_ages.sort()
4.63 ++ for item_age, item in item_ages[:-cache_limit]:
4.64 ++ item.remove()
4.65 ++
4.66 ++ def getCacheKey(self, request):
4.67 ++ """ Generate a cache key for a page using optional request information """
4.68 ++ key = self.getFormatterName()
4.69 ++ if request.args:
4.70 ++ args = request.args.items()
4.71 ++ args.sort()
4.72 ++ key_args = []
4.73 ++ for k, v in args:
4.74 ++ key_args.append("%s=%s" % (k, wikiutil.url_quote(v)))
4.75 ++ arg_str = "&".join(key_args)
4.76 ++ key = "%s:%s" % (key, hash_new('sha1', arg_str).hexdigest())
4.77 ++ return key
4.78 ++
4.79 + def _specialPageText(self, request, special_type):
4.80 + """ Output the default page content for new pages.
4.81 +
4.82 +# HG changeset patch
4.83 +# User Paul Boddie <paul@boddie.org.uk>
4.84 +# Date 1390599896 -3600
4.85 +# Node ID e3850612c891d5b6468f212acd797413c70fe18f
4.86 +# Parent 71d9815d2e6f5487ec87c4f5c04e5a156ffd21d3
4.87 +Acquire the request formatter name when the page formatter has not yet been set.
4.88 +
4.89 +diff -r 71d9815d2e6f -r e3850612c891 MoinMoin/Page.py
4.90 +--- a/MoinMoin/Page.py Fri Jan 24 18:52:18 2014 +0100
4.91 ++++ b/MoinMoin/Page.py Fri Jan 24 22:44:56 2014 +0100
4.92 +@@ -1255,15 +1255,17 @@
4.93 + request.formatter = old_formatter
4.94 +
4.95 +
4.96 +- def getFormatterName(self):
4.97 ++ def getFormatterName(self, request=None):
4.98 + """ Return a formatter name as used in the caching system
4.99 +
4.100 ++ @param request: the active request (optional)
4.101 + @rtype: string
4.102 + @return: formatter name as used in caching
4.103 + """
4.104 +- if not hasattr(self, 'formatter') or self.formatter is None:
4.105 ++ formatter = getattr(self, 'formatter', None) or request and getattr(request, 'formatter', None)
4.106 ++ if not formatter:
4.107 + return ''
4.108 +- module = self.formatter.__module__
4.109 ++ module = formatter.__module__
4.110 + return module[module.rfind('.') + 1:]
4.111 +
4.112 + def canUseCache(self, parser=None):
4.113 +@@ -1407,7 +1409,7 @@
4.114 +
4.115 + def getCacheKey(self, request):
4.116 + """ Generate a cache key for a page using optional request information """
4.117 +- key = self.getFormatterName()
4.118 ++ key = self.getFormatterName(request)
4.119 + if request.args:
4.120 + args = request.args.items()
4.121 + args.sort()