1.1 --- a/patches/pageparams-caching-1.8.diff Sat Mar 29 16:29:52 2014 +0100
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,215 +0,0 @@
1.4 -# HG changeset patch
1.5 -# User Paul Boddie <paul@boddie.org.uk>
1.6 -# Date 1390585706 -3600
1.7 -# Node ID 70250fe93a4f946e51eaa63accbb0152054ddab2
1.8 -# Parent d57b620213dd68126d2e5800f173d89f0602403a
1.9 -Added caching support for the "pageparams" dependency where the request
1.10 -parameters are combined with the page name to make a cache entry.
1.11 -
1.12 -diff -r d57b620213dd -r 70250fe93a4f MoinMoin/Page.py
1.13 ---- a/MoinMoin/Page.py Tue Jul 30 17:41:42 2013 +0200
1.14 -+++ b/MoinMoin/Page.py Fri Jan 24 18:48:26 2014 +0100
1.15 -@@ -41,6 +41,7 @@
1.16 -
1.17 - from MoinMoin import config, caching, user, util, wikiutil
1.18 - from MoinMoin.logfile import eventlog
1.19 -+from MoinMoin.support.python_compatibility import hash_new
1.20 -
1.21 - def is_cache_exception(e):
1.22 - args = e.args
1.23 -@@ -1336,7 +1337,7 @@
1.24 -
1.25 - def loadCache(self, request):
1.26 - """ Return page content cache or raises 'CacheNeedsUpdate' """
1.27 -- cache = caching.CacheEntry(request, self, self.getFormatterName(), scope='item')
1.28 -+ cache = caching.CacheEntry(request, self, self.getCacheKey(request), scope='item')
1.29 - attachmentsPath = self.getPagePath('attachments', check_create=0)
1.30 - if cache.needsUpdate(self._text_filename(), attachmentsPath):
1.31 - raise Exception('CacheNeedsUpdate')
1.32 -@@ -1357,7 +1358,7 @@
1.33 - """ Format content into code, update cache and return code """
1.34 - import marshal
1.35 - from MoinMoin.formatter.text_python import Formatter
1.36 -- formatter = Formatter(request, ["page"], self.formatter)
1.37 -+ formatter = Formatter(request, ["page", "pageparams"], self.formatter)
1.38 -
1.39 - # Save request state while formatting page
1.40 - saved_current_lang = request.current_lang
1.41 -@@ -1369,10 +1370,39 @@
1.42 - src = formatter.assemble_code(text)
1.43 - code = compile(src.encode(config.charset),
1.44 - self.page_name.encode(config.charset), 'exec')
1.45 -- cache = caching.CacheEntry(request, self, self.getFormatterName(), scope='item')
1.46 -+ self.enforceCacheLimit(request)
1.47 -+ cache = caching.CacheEntry(request, self, self.getCacheKey(request), scope='item')
1.48 - cache.update(marshal.dumps(code))
1.49 - return code
1.50 -
1.51 -+ def enforceCacheLimit(self, request):
1.52 -+ """ Prevent too many cache entries being stored for a page """
1.53 -+ keys = caching.get_cache_list(request, self, 'item')
1.54 -+ try:
1.55 -+ cache_limit = int(getattr(request.cfg, 'page_cache_limit', "10"))
1.56 -+ except ValueError:
1.57 -+ cache_limit = 10
1.58 -+
1.59 -+ if len(keys) >= cache_limit:
1.60 -+ items = [caching.CacheEntry(request, self, key, scope='item') for key in keys]
1.61 -+ item_ages = [(item.mtime(), item) for item in items]
1.62 -+ item_ages.sort()
1.63 -+ for item_age, item in item_ages[:-cache_limit]:
1.64 -+ item.remove()
1.65 -+
1.66 -+ def getCacheKey(self, request):
1.67 -+ """ Generate a cache key for a page using optional request information """
1.68 -+ key = self.getFormatterName()
1.69 -+ if request.args:
1.70 -+ args = request.args.items()
1.71 -+ args.sort()
1.72 -+ key_args = []
1.73 -+ for k, v in args:
1.74 -+ key_args.append("%s=%s" % (k, wikiutil.url_quote(v)))
1.75 -+ arg_str = "&".join(key_args)
1.76 -+ key = "%s:%s" % (key, hash_new('sha1', arg_str).hexdigest())
1.77 -+ return key
1.78 -+
1.79 - def _specialPageText(self, request, special_type):
1.80 - """ Output the default page content for new pages.
1.81 -
1.82 -# HG changeset patch
1.83 -# User Paul Boddie <paul@boddie.org.uk>
1.84 -# Date 1390599896 -3600
1.85 -# Node ID 02d1fa8951523776357a9a37235ad5c37f42fcc8
1.86 -# Parent 70250fe93a4f946e51eaa63accbb0152054ddab2
1.87 -Acquire the request formatter name when the page formatter has not yet been set.
1.88 -
1.89 -diff -r 70250fe93a4f -r 02d1fa895152 MoinMoin/Page.py
1.90 ---- a/MoinMoin/Page.py Fri Jan 24 18:48:26 2014 +0100
1.91 -+++ b/MoinMoin/Page.py Fri Jan 24 22:44:56 2014 +0100
1.92 -@@ -1240,15 +1240,17 @@
1.93 - request.formatter = old_formatter
1.94 -
1.95 -
1.96 -- def getFormatterName(self):
1.97 -+ def getFormatterName(self, request=None):
1.98 - """ Return a formatter name as used in the caching system
1.99 -
1.100 -+ @param request: the active request (optional)
1.101 - @rtype: string
1.102 - @return: formatter name as used in caching
1.103 - """
1.104 -- if not hasattr(self, 'formatter') or self.formatter is None:
1.105 -+ formatter = getattr(self, 'formatter', None) or request and getattr(request, 'formatter', None)
1.106 -+ if not formatter:
1.107 - return ''
1.108 -- module = self.formatter.__module__
1.109 -+ module = formatter.__module__
1.110 - return module[module.rfind('.') + 1:]
1.111 -
1.112 - def canUseCache(self, parser=None):
1.113 -@@ -1392,7 +1394,7 @@
1.114 -
1.115 - def getCacheKey(self, request):
1.116 - """ Generate a cache key for a page using optional request information """
1.117 -- key = self.getFormatterName()
1.118 -+ key = self.getFormatterName(request)
1.119 - if request.args:
1.120 - args = request.args.items()
1.121 - args.sort()
1.122 -# HG changeset patch
1.123 -# User Paul Boddie <paul@boddie.org.uk>
1.124 -# Date 1390675730 -3600
1.125 -# Node ID 561fe9439debfd095753a32d884383c315dde7ec
1.126 -# Parent 02d1fa8951523776357a9a37235ad5c37f42fcc8
1.127 -Added tracking of reported dependencies and prevented generation of specific
1.128 -cache entries for request parameter combinations when no extension requires or
1.129 -supports such specific entries.
1.130 -
1.131 -diff -r 02d1fa895152 -r 561fe9439deb MoinMoin/Page.py
1.132 ---- a/MoinMoin/Page.py Fri Jan 24 22:44:56 2014 +0100
1.133 -+++ b/MoinMoin/Page.py Sat Jan 25 19:48:50 2014 +0100
1.134 -@@ -1339,9 +1339,12 @@
1.135 -
1.136 - def loadCache(self, request):
1.137 - """ Return page content cache or raises 'CacheNeedsUpdate' """
1.138 -- cache = caching.CacheEntry(request, self, self.getCacheKey(request), scope='item')
1.139 -- attachmentsPath = self.getPagePath('attachments', check_create=0)
1.140 -- if cache.needsUpdate(self._text_filename(), attachmentsPath):
1.141 -+ for with_params in (True, False):
1.142 -+ cache = caching.CacheEntry(request, self, self.getCacheKey(request, with_params), scope='item')
1.143 -+ attachmentsPath = self.getPagePath('attachments', check_create=0)
1.144 -+ if not cache.needsUpdate(self._text_filename(), attachmentsPath):
1.145 -+ break
1.146 -+ else:
1.147 - raise Exception('CacheNeedsUpdate')
1.148 -
1.149 - import marshal
1.150 -@@ -1373,7 +1376,10 @@
1.151 - code = compile(src.encode(config.charset),
1.152 - self.page_name.encode(config.charset), 'exec')
1.153 - self.enforceCacheLimit(request)
1.154 -- cache = caching.CacheEntry(request, self, self.getCacheKey(request), scope='item')
1.155 -+ # Determine whether the parameters/args need to be incorporated into the
1.156 -+ # cache entry key.
1.157 -+ with_params = "pageparams" in formatter.getReportedDependencies()
1.158 -+ cache = caching.CacheEntry(request, self, self.getCacheKey(request, with_params), scope='item')
1.159 - cache.update(marshal.dumps(code))
1.160 - return code
1.161 -
1.162 -@@ -1392,10 +1398,10 @@
1.163 - for item_age, item in item_ages[:-cache_limit]:
1.164 - item.remove()
1.165 -
1.166 -- def getCacheKey(self, request):
1.167 -+ def getCacheKey(self, request, with_params=False):
1.168 - """ Generate a cache key for a page using optional request information """
1.169 - key = self.getFormatterName(request)
1.170 -- if request.args:
1.171 -+ if with_params and request.args:
1.172 - args = request.args.items()
1.173 - args.sort()
1.174 - key_args = []
1.175 -diff -r 02d1fa895152 -r 561fe9439deb MoinMoin/formatter/text_python.py
1.176 ---- a/MoinMoin/formatter/text_python.py Fri Jan 24 22:44:56 2014 +0100
1.177 -+++ b/MoinMoin/formatter/text_python.py Sat Jan 25 19:48:50 2014 +0100
1.178 -@@ -10,6 +10,7 @@
1.179 -
1.180 - import time
1.181 - from MoinMoin import wikiutil
1.182 -+from MoinMoin.support.python_compatibility import set
1.183 -
1.184 -
1.185 - class Formatter:
1.186 -@@ -40,6 +41,12 @@
1.187 - self.text_cmd_begin = '\nrequest.write('
1.188 - self.text_cmd_end = ')\n'
1.189 -
1.190 -+ # Record dependency requirements of certain content
1.191 -+ self.__dependencies = set()
1.192 -+
1.193 -+ def getReportedDependencies(self):
1.194 -+ return self.__dependencies
1.195 -+
1.196 - def assemble_code(self, text):
1.197 - """inserts the code into the generated text
1.198 - """
1.199 -@@ -186,7 +193,10 @@
1.200 - return self.formatter.div(on, **kw)
1.201 -
1.202 - def macro(self, macro_obj, name, args, markup=None):
1.203 -- if self.__is_static(macro_obj.get_dependencies(name)):
1.204 -+ Dependencies = macro_obj.get_dependencies(name)
1.205 -+ self.__dependencies.update(Dependencies)
1.206 -+
1.207 -+ if self.__is_static(Dependencies):
1.208 - # XXX: why is this necessary??
1.209 - macro_obj.formatter = self
1.210 - return macro_obj.execute(name, args)
1.211 -@@ -204,6 +214,7 @@
1.212 - Dependencies = wikiutil.searchAndImportPlugin(self.request.cfg, "parser", parser_name, "Dependencies")
1.213 - except (wikiutil.PluginMissingError, wikiutil.PluginAttributeError):
1.214 - Dependencies = self.defaultDependencies
1.215 -+ self.__dependencies.update(Dependencies)
1.216 -
1.217 - if self.__is_static(Dependencies):
1.218 - return self.formatter.parser(parser_name, lines)
2.1 --- a/patches/pageparams-caching-1.9.diff Sat Mar 29 16:29:52 2014 +0100
2.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2.3 @@ -1,215 +0,0 @@
2.4 -# HG changeset patch
2.5 -# User Paul Boddie <paul@boddie.org.uk>
2.6 -# Date 1390585938 -3600
2.7 -# Node ID 71d9815d2e6f5487ec87c4f5c04e5a156ffd21d3
2.8 -# Parent 5738b78f53b540ece0b48efa49b63fa4cbc09be9
2.9 -Added caching support for the "pageparams" dependency where the request
2.10 -parameters are combined with the page name to make a cache entry.
2.11 -
2.12 -diff -r 5738b78f53b5 -r 71d9815d2e6f MoinMoin/Page.py
2.13 ---- a/MoinMoin/Page.py Sat Nov 30 20:09:43 2013 +0100
2.14 -+++ b/MoinMoin/Page.py Fri Jan 24 18:52:18 2014 +0100
2.15 -@@ -41,6 +41,7 @@
2.16 -
2.17 - from MoinMoin import config, caching, user, util, wikiutil
2.18 - from MoinMoin.logfile import eventlog
2.19 -+from MoinMoin.support.python_compatibility import hash_new
2.20 -
2.21 - def is_cache_exception(e):
2.22 - args = e.args
2.23 -@@ -1351,7 +1352,7 @@
2.24 -
2.25 - def loadCache(self, request):
2.26 - """ Return page content cache or raises 'CacheNeedsUpdate' """
2.27 -- cache = caching.CacheEntry(request, self, self.getFormatterName(), scope='item')
2.28 -+ cache = caching.CacheEntry(request, self, self.getCacheKey(request), scope='item')
2.29 - attachmentsPath = self.getPagePath('attachments', check_create=0)
2.30 - if cache.needsUpdate(self._text_filename(), attachmentsPath):
2.31 - raise Exception('CacheNeedsUpdate')
2.32 -@@ -1372,7 +1373,7 @@
2.33 - """ Format content into code, update cache and return code """
2.34 - import marshal
2.35 - from MoinMoin.formatter.text_python import Formatter
2.36 -- formatter = Formatter(request, ["page"], self.formatter)
2.37 -+ formatter = Formatter(request, ["page", "pageparams"], self.formatter)
2.38 -
2.39 - # Save request state while formatting page
2.40 - saved_current_lang = request.current_lang
2.41 -@@ -1384,10 +1385,39 @@
2.42 - src = formatter.assemble_code(text)
2.43 - code = compile(src.encode(config.charset),
2.44 - self.page_name.encode(config.charset), 'exec')
2.45 -- cache = caching.CacheEntry(request, self, self.getFormatterName(), scope='item')
2.46 -+ self.enforceCacheLimit(request)
2.47 -+ cache = caching.CacheEntry(request, self, self.getCacheKey(request), scope='item')
2.48 - cache.update(marshal.dumps(code))
2.49 - return code
2.50 -
2.51 -+ def enforceCacheLimit(self, request):
2.52 -+ """ Prevent too many cache entries being stored for a page """
2.53 -+ keys = caching.get_cache_list(request, self, 'item')
2.54 -+ try:
2.55 -+ cache_limit = int(getattr(request.cfg, 'page_cache_limit', "10"))
2.56 -+ except ValueError:
2.57 -+ cache_limit = 10
2.58 -+
2.59 -+ if len(keys) >= cache_limit:
2.60 -+ items = [caching.CacheEntry(request, self, key, scope='item') for key in keys]
2.61 -+ item_ages = [(item.mtime(), item) for item in items]
2.62 -+ item_ages.sort()
2.63 -+ for item_age, item in item_ages[:-cache_limit]:
2.64 -+ item.remove()
2.65 -+
2.66 -+ def getCacheKey(self, request):
2.67 -+ """ Generate a cache key for a page using optional request information """
2.68 -+ key = self.getFormatterName()
2.69 -+ if request.args:
2.70 -+ args = request.args.items()
2.71 -+ args.sort()
2.72 -+ key_args = []
2.73 -+ for k, v in args:
2.74 -+ key_args.append("%s=%s" % (k, wikiutil.url_quote(v)))
2.75 -+ arg_str = "&".join(key_args)
2.76 -+ key = "%s:%s" % (key, hash_new('sha1', arg_str).hexdigest())
2.77 -+ return key
2.78 -+
2.79 - def _specialPageText(self, request, special_type):
2.80 - """ Output the default page content for new pages.
2.81 -
2.82 -# HG changeset patch
2.83 -# User Paul Boddie <paul@boddie.org.uk>
2.84 -# Date 1390599896 -3600
2.85 -# Node ID e3850612c891d5b6468f212acd797413c70fe18f
2.86 -# Parent 71d9815d2e6f5487ec87c4f5c04e5a156ffd21d3
2.87 -Acquire the request formatter name when the page formatter has not yet been set.
2.88 -
2.89 -diff -r 71d9815d2e6f -r e3850612c891 MoinMoin/Page.py
2.90 ---- a/MoinMoin/Page.py Fri Jan 24 18:52:18 2014 +0100
2.91 -+++ b/MoinMoin/Page.py Fri Jan 24 22:44:56 2014 +0100
2.92 -@@ -1255,15 +1255,17 @@
2.93 - request.formatter = old_formatter
2.94 -
2.95 -
2.96 -- def getFormatterName(self):
2.97 -+ def getFormatterName(self, request=None):
2.98 - """ Return a formatter name as used in the caching system
2.99 -
2.100 -+ @param request: the active request (optional)
2.101 - @rtype: string
2.102 - @return: formatter name as used in caching
2.103 - """
2.104 -- if not hasattr(self, 'formatter') or self.formatter is None:
2.105 -+ formatter = getattr(self, 'formatter', None) or request and getattr(request, 'formatter', None)
2.106 -+ if not formatter:
2.107 - return ''
2.108 -- module = self.formatter.__module__
2.109 -+ module = formatter.__module__
2.110 - return module[module.rfind('.') + 1:]
2.111 -
2.112 - def canUseCache(self, parser=None):
2.113 -@@ -1407,7 +1409,7 @@
2.114 -
2.115 - def getCacheKey(self, request):
2.116 - """ Generate a cache key for a page using optional request information """
2.117 -- key = self.getFormatterName()
2.118 -+ key = self.getFormatterName(request)
2.119 - if request.args:
2.120 - args = request.args.items()
2.121 - args.sort()
2.122 -# HG changeset patch
2.123 -# User Paul Boddie <paul@boddie.org.uk>
2.124 -# Date 1390675730 -3600
2.125 -# Node ID 908ceaf41dbe9f664f0c0813abc7b4c0611022fe
2.126 -# Parent e3850612c891d5b6468f212acd797413c70fe18f
2.127 -Added tracking of reported dependencies and prevented generation of specific
2.128 -cache entries for request parameter combinations when no extension requires or
2.129 -supports such specific entries.
2.130 -
2.131 -diff -r e3850612c891 -r 908ceaf41dbe MoinMoin/Page.py
2.132 ---- a/MoinMoin/Page.py Fri Jan 24 22:44:56 2014 +0100
2.133 -+++ b/MoinMoin/Page.py Sat Jan 25 19:48:50 2014 +0100
2.134 -@@ -1354,9 +1354,12 @@
2.135 -
2.136 - def loadCache(self, request):
2.137 - """ Return page content cache or raises 'CacheNeedsUpdate' """
2.138 -- cache = caching.CacheEntry(request, self, self.getCacheKey(request), scope='item')
2.139 -- attachmentsPath = self.getPagePath('attachments', check_create=0)
2.140 -- if cache.needsUpdate(self._text_filename(), attachmentsPath):
2.141 -+ for with_params in (True, False):
2.142 -+ cache = caching.CacheEntry(request, self, self.getCacheKey(request, with_params), scope='item')
2.143 -+ attachmentsPath = self.getPagePath('attachments', check_create=0)
2.144 -+ if not cache.needsUpdate(self._text_filename(), attachmentsPath):
2.145 -+ break
2.146 -+ else:
2.147 - raise Exception('CacheNeedsUpdate')
2.148 -
2.149 - import marshal
2.150 -@@ -1388,7 +1391,10 @@
2.151 - code = compile(src.encode(config.charset),
2.152 - self.page_name.encode(config.charset), 'exec')
2.153 - self.enforceCacheLimit(request)
2.154 -- cache = caching.CacheEntry(request, self, self.getCacheKey(request), scope='item')
2.155 -+ # Determine whether the parameters/args need to be incorporated into the
2.156 -+ # cache entry key.
2.157 -+ with_params = "pageparams" in formatter.getReportedDependencies()
2.158 -+ cache = caching.CacheEntry(request, self, self.getCacheKey(request, with_params), scope='item')
2.159 - cache.update(marshal.dumps(code))
2.160 - return code
2.161 -
2.162 -@@ -1407,10 +1413,10 @@
2.163 - for item_age, item in item_ages[:-cache_limit]:
2.164 - item.remove()
2.165 -
2.166 -- def getCacheKey(self, request):
2.167 -+ def getCacheKey(self, request, with_params=False):
2.168 - """ Generate a cache key for a page using optional request information """
2.169 - key = self.getFormatterName(request)
2.170 -- if request.args:
2.171 -+ if with_params and request.args:
2.172 - args = request.args.items()
2.173 - args.sort()
2.174 - key_args = []
2.175 -diff -r e3850612c891 -r 908ceaf41dbe MoinMoin/formatter/text_python.py
2.176 ---- a/MoinMoin/formatter/text_python.py Fri Jan 24 22:44:56 2014 +0100
2.177 -+++ b/MoinMoin/formatter/text_python.py Sat Jan 25 19:48:50 2014 +0100
2.178 -@@ -10,6 +10,7 @@
2.179 -
2.180 - import time
2.181 - from MoinMoin import wikiutil
2.182 -+from MoinMoin.support.python_compatibility import set
2.183 -
2.184 -
2.185 - class Formatter:
2.186 -@@ -40,6 +41,12 @@
2.187 - self.text_cmd_begin = '\nrequest.write('
2.188 - self.text_cmd_end = ')\n'
2.189 -
2.190 -+ # Record dependency requirements of certain content
2.191 -+ self.__dependencies = set()
2.192 -+
2.193 -+ def getReportedDependencies(self):
2.194 -+ return self.__dependencies
2.195 -+
2.196 - def assemble_code(self, text):
2.197 - """inserts the code into the generated text
2.198 - """
2.199 -@@ -186,7 +193,10 @@
2.200 - return self.formatter.div(on, **kw)
2.201 -
2.202 - def macro(self, macro_obj, name, args, markup=None):
2.203 -- if self.__is_static(macro_obj.get_dependencies(name)):
2.204 -+ Dependencies = macro_obj.get_dependencies(name)
2.205 -+ self.__dependencies.update(Dependencies)
2.206 -+
2.207 -+ if self.__is_static(Dependencies):
2.208 - # XXX: why is this necessary??
2.209 - macro_obj.formatter = self
2.210 - return macro_obj.execute(name, args)
2.211 -@@ -204,6 +214,7 @@
2.212 - Dependencies = wikiutil.searchAndImportPlugin(self.request.cfg, "parser", parser_name, "Dependencies")
2.213 - except (wikiutil.PluginMissingError, wikiutil.PluginAttributeError):
2.214 - Dependencies = self.defaultDependencies
2.215 -+ self.__dependencies.update(Dependencies)
2.216 -
2.217 - if self.__is_static(Dependencies):
2.218 - return self.formatter.parser(parser_name, lines)
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/patches/patch-cache-pageparams-1.8.diff Sat Mar 29 19:32:26 2014 +0100
3.3 @@ -0,0 +1,168 @@
3.4 +diff -r d57b620213dd MoinMoin/Page.py
3.5 +--- a/MoinMoin/Page.py Tue Jul 30 17:41:42 2013 +0200
3.6 ++++ b/MoinMoin/Page.py Sat Mar 29 16:01:13 2014 +0100
3.7 +@@ -41,6 +41,7 @@
3.8 +
3.9 + from MoinMoin import config, caching, user, util, wikiutil
3.10 + from MoinMoin.logfile import eventlog
3.11 ++from MoinMoin.support.python_compatibility import hash_new
3.12 +
3.13 + def is_cache_exception(e):
3.14 + args = e.args
3.15 +@@ -1239,15 +1240,17 @@
3.16 + request.formatter = old_formatter
3.17 +
3.18 +
3.19 +- def getFormatterName(self):
3.20 ++ def getFormatterName(self, request=None):
3.21 + """ Return a formatter name as used in the caching system
3.22 +
3.23 ++ @param request: the active request (optional)
3.24 + @rtype: string
3.25 + @return: formatter name as used in caching
3.26 + """
3.27 +- if not hasattr(self, 'formatter') or self.formatter is None:
3.28 ++ formatter = getattr(self, 'formatter', None) or request and getattr(request, 'formatter', None)
3.29 ++ if not formatter:
3.30 + return ''
3.31 +- module = self.formatter.__module__
3.32 ++ module = formatter.__module__
3.33 + return module[module.rfind('.') + 1:]
3.34 +
3.35 + def canUseCache(self, parser=None):
3.36 +@@ -1336,9 +1339,12 @@
3.37 +
3.38 + def loadCache(self, request):
3.39 + """ Return page content cache or raises 'CacheNeedsUpdate' """
3.40 +- cache = caching.CacheEntry(request, self, self.getFormatterName(), scope='item')
3.41 +- attachmentsPath = self.getPagePath('attachments', check_create=0)
3.42 +- if cache.needsUpdate(self._text_filename(), attachmentsPath):
3.43 ++ for with_params in (True, False):
3.44 ++ cache = caching.CacheEntry(request, self, self.getCacheKey(request, with_params), scope='item')
3.45 ++ attachmentsPath = self.getPagePath('attachments', check_create=0)
3.46 ++ if not cache.needsUpdate(self._text_filename(), attachmentsPath):
3.47 ++ break
3.48 ++ else:
3.49 + raise Exception('CacheNeedsUpdate')
3.50 +
3.51 + import marshal
3.52 +@@ -1357,7 +1363,7 @@
3.53 + """ Format content into code, update cache and return code """
3.54 + import marshal
3.55 + from MoinMoin.formatter.text_python import Formatter
3.56 +- formatter = Formatter(request, ["page"], self.formatter)
3.57 ++ formatter = Formatter(request, ["page", "pageparams"], self.formatter)
3.58 +
3.59 + # Save request state while formatting page
3.60 + saved_current_lang = request.current_lang
3.61 +@@ -1369,10 +1375,45 @@
3.62 + src = formatter.assemble_code(text)
3.63 + code = compile(src.encode(config.charset),
3.64 + self.page_name.encode(config.charset), 'exec')
3.65 +- cache = caching.CacheEntry(request, self, self.getFormatterName(), scope='item')
3.66 ++ self.enforceCacheLimit(request)
3.67 ++ # Determine whether the parameters/args need to be incorporated into the
3.68 ++ # cache entry key.
3.69 ++ with_params = "pageparams" in formatter.getReportedDependencies()
3.70 ++ cache = caching.CacheEntry(request, self, self.getCacheKey(request, with_params), scope='item')
3.71 + cache.update(marshal.dumps(code))
3.72 + return code
3.73 +
3.74 ++ def enforceCacheLimit(self, request):
3.75 ++ """ Prevent too many cache entries being stored for a page """
3.76 ++ keys = caching.get_cache_list(request, self, 'item')
3.77 ++ try:
3.78 ++ cache_limit = int(getattr(request.cfg, 'page_cache_limit', "10"))
3.79 ++ except ValueError:
3.80 ++ cache_limit = 10
3.81 ++
3.82 ++ if len(keys) >= cache_limit:
3.83 ++ items = [caching.CacheEntry(request, self, key, scope='item') for key in keys]
3.84 ++ item_ages = [(item.mtime(), item) for item in items]
3.85 ++ item_ages.sort()
3.86 ++ for item_age, item in item_ages[:-cache_limit]:
3.87 ++ item.remove()
3.88 ++
3.89 ++ def getCacheKey(self, request, with_params=False, key=None):
3.90 ++ """ Generate a cache key for a page using optional request information """
3.91 ++ key = key or self.getFormatterName(request)
3.92 ++ if with_params and request.args:
3.93 ++ args = request.args.items()
3.94 ++ args.sort()
3.95 ++ key_args = []
3.96 ++ for k, values in args:
3.97 ++ for v in values:
3.98 ++ if not (k == "action" and v == "refresh"):
3.99 ++ key_args.append("%s=%s" % (k, wikiutil.url_quote(v)))
3.100 ++ arg_str = "&".join(key_args)
3.101 ++ if arg_str:
3.102 ++ key = "%s:%s" % (key, hash_new('sha1', arg_str).hexdigest())
3.103 ++ return key
3.104 ++
3.105 + def _specialPageText(self, request, special_type):
3.106 + """ Output the default page content for new pages.
3.107 +
3.108 +diff -r d57b620213dd MoinMoin/action/refresh.py
3.109 +--- a/MoinMoin/action/refresh.py Tue Jul 30 17:41:42 2013 +0200
3.110 ++++ b/MoinMoin/action/refresh.py Sat Mar 29 16:01:13 2014 +0100
3.111 +@@ -14,11 +14,14 @@
3.112 + arena = request.form.get('arena', ['Page.py'])[0]
3.113 + if arena == 'Page.py':
3.114 + arena = Page(request, pagename)
3.115 +- key = request.form.get('key', ['text_html'])[0]
3.116 ++ prefix = request.form.get('key', ['text_html'])[0]
3.117 +
3.118 + # Remove cache entry (if exists), and send the page
3.119 + from MoinMoin import caching
3.120 +- caching.CacheEntry(request, arena, key, scope='item').remove()
3.121 ++ keys = caching.get_cache_list(request, arena, 'item')
3.122 ++ for key in keys:
3.123 ++ if key.startswith(prefix):
3.124 ++ caching.CacheEntry(request, arena, key, scope='item').remove()
3.125 + caching.CacheEntry(request, arena, "pagelinks", scope='item').remove()
3.126 + request.page.send_page()
3.127 +
3.128 +diff -r d57b620213dd MoinMoin/formatter/text_python.py
3.129 +--- a/MoinMoin/formatter/text_python.py Tue Jul 30 17:41:42 2013 +0200
3.130 ++++ b/MoinMoin/formatter/text_python.py Sat Mar 29 16:01:13 2014 +0100
3.131 +@@ -10,6 +10,7 @@
3.132 +
3.133 + import time
3.134 + from MoinMoin import wikiutil
3.135 ++from MoinMoin.support.python_compatibility import set
3.136 +
3.137 +
3.138 + class Formatter:
3.139 +@@ -40,6 +41,12 @@
3.140 + self.text_cmd_begin = '\nrequest.write('
3.141 + self.text_cmd_end = ')\n'
3.142 +
3.143 ++ # Record dependency requirements of certain content
3.144 ++ self.__dependencies = set()
3.145 ++
3.146 ++ def getReportedDependencies(self):
3.147 ++ return self.__dependencies
3.148 ++
3.149 + def assemble_code(self, text):
3.150 + """inserts the code into the generated text
3.151 + """
3.152 +@@ -186,7 +193,10 @@
3.153 + return self.formatter.div(on, **kw)
3.154 +
3.155 + def macro(self, macro_obj, name, args, markup=None):
3.156 +- if self.__is_static(macro_obj.get_dependencies(name)):
3.157 ++ Dependencies = macro_obj.get_dependencies(name)
3.158 ++ self.__dependencies.update(Dependencies)
3.159 ++
3.160 ++ if self.__is_static(Dependencies):
3.161 + # XXX: why is this necessary??
3.162 + macro_obj.formatter = self
3.163 + return macro_obj.execute(name, args)
3.164 +@@ -204,6 +214,7 @@
3.165 + Dependencies = wikiutil.searchAndImportPlugin(self.request.cfg, "parser", parser_name, "Dependencies")
3.166 + except (wikiutil.PluginMissingError, wikiutil.PluginAttributeError):
3.167 + Dependencies = self.defaultDependencies
3.168 ++ self.__dependencies.update(Dependencies)
3.169 +
3.170 + if self.__is_static(Dependencies):
3.171 + return self.formatter.parser(parser_name, lines)
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/patches/patch-cache-pageparams-1.9.diff Sat Mar 29 19:32:26 2014 +0100
4.3 @@ -0,0 +1,167 @@
4.4 +diff -r 5738b78f53b5 MoinMoin/Page.py
4.5 +--- a/MoinMoin/Page.py Sat Nov 30 20:09:43 2013 +0100
4.6 ++++ b/MoinMoin/Page.py Sat Mar 29 16:23:44 2014 +0100
4.7 +@@ -41,6 +41,7 @@
4.8 +
4.9 + from MoinMoin import config, caching, user, util, wikiutil
4.10 + from MoinMoin.logfile import eventlog
4.11 ++from MoinMoin.support.python_compatibility import hash_new
4.12 +
4.13 + def is_cache_exception(e):
4.14 + args = e.args
4.15 +@@ -1254,15 +1255,17 @@
4.16 + request.formatter = old_formatter
4.17 +
4.18 +
4.19 +- def getFormatterName(self):
4.20 ++ def getFormatterName(self, request=None):
4.21 + """ Return a formatter name as used in the caching system
4.22 +
4.23 ++ @param request: the active request (optional)
4.24 + @rtype: string
4.25 + @return: formatter name as used in caching
4.26 + """
4.27 +- if not hasattr(self, 'formatter') or self.formatter is None:
4.28 ++ formatter = getattr(self, 'formatter', None) or request and getattr(request, 'formatter', None)
4.29 ++ if not formatter:
4.30 + return ''
4.31 +- module = self.formatter.__module__
4.32 ++ module = formatter.__module__
4.33 + return module[module.rfind('.') + 1:]
4.34 +
4.35 + def canUseCache(self, parser=None):
4.36 +@@ -1351,9 +1354,12 @@
4.37 +
4.38 + def loadCache(self, request):
4.39 + """ Return page content cache or raises 'CacheNeedsUpdate' """
4.40 +- cache = caching.CacheEntry(request, self, self.getFormatterName(), scope='item')
4.41 +- attachmentsPath = self.getPagePath('attachments', check_create=0)
4.42 +- if cache.needsUpdate(self._text_filename(), attachmentsPath):
4.43 ++ for with_params in (True, False):
4.44 ++ cache = caching.CacheEntry(request, self, self.getCacheKey(request, with_params), scope='item')
4.45 ++ attachmentsPath = self.getPagePath('attachments', check_create=0)
4.46 ++ if not cache.needsUpdate(self._text_filename(), attachmentsPath):
4.47 ++ break
4.48 ++ else:
4.49 + raise Exception('CacheNeedsUpdate')
4.50 +
4.51 + import marshal
4.52 +@@ -1372,7 +1378,7 @@
4.53 + """ Format content into code, update cache and return code """
4.54 + import marshal
4.55 + from MoinMoin.formatter.text_python import Formatter
4.56 +- formatter = Formatter(request, ["page"], self.formatter)
4.57 ++ formatter = Formatter(request, ["page", "pageparams"], self.formatter)
4.58 +
4.59 + # Save request state while formatting page
4.60 + saved_current_lang = request.current_lang
4.61 +@@ -1384,10 +1390,44 @@
4.62 + src = formatter.assemble_code(text)
4.63 + code = compile(src.encode(config.charset),
4.64 + self.page_name.encode(config.charset), 'exec')
4.65 +- cache = caching.CacheEntry(request, self, self.getFormatterName(), scope='item')
4.66 ++ self.enforceCacheLimit(request)
4.67 ++ # Determine whether the parameters/args need to be incorporated into the
4.68 ++ # cache entry key.
4.69 ++ with_params = "pageparams" in formatter.getReportedDependencies()
4.70 ++ cache = caching.CacheEntry(request, self, self.getCacheKey(request, with_params), scope='item')
4.71 + cache.update(marshal.dumps(code))
4.72 + return code
4.73 +
4.74 ++ def enforceCacheLimit(self, request):
4.75 ++ """ Prevent too many cache entries being stored for a page """
4.76 ++ keys = caching.get_cache_list(request, self, 'item')
4.77 ++ try:
4.78 ++ cache_limit = int(getattr(request.cfg, 'page_cache_limit', "10"))
4.79 ++ except ValueError:
4.80 ++ cache_limit = 10
4.81 ++
4.82 ++ if len(keys) >= cache_limit:
4.83 ++ items = [caching.CacheEntry(request, self, key, scope='item') for key in keys]
4.84 ++ item_ages = [(item.mtime(), item) for item in items]
4.85 ++ item_ages.sort()
4.86 ++ for item_age, item in item_ages[:-cache_limit]:
4.87 ++ item.remove()
4.88 ++
4.89 ++ def getCacheKey(self, request, with_params=False, key=None):
4.90 ++ """ Generate a cache key for a page using optional request information """
4.91 ++ key = key or self.getFormatterName(request)
4.92 ++ if with_params and request.args:
4.93 ++ args = request.args.items(True)
4.94 ++ args.sort()
4.95 ++ key_args = []
4.96 ++ for k, v in args:
4.97 ++ if not (k == "action" and v == "refresh"):
4.98 ++ key_args.append("%s=%s" % (k, wikiutil.url_quote(v)))
4.99 ++ arg_str = "&".join(key_args)
4.100 ++ if arg_str:
4.101 ++ key = "%s:%s" % (key, hash_new('sha1', arg_str).hexdigest())
4.102 ++ return key
4.103 ++
4.104 + def _specialPageText(self, request, special_type):
4.105 + """ Output the default page content for new pages.
4.106 +
4.107 +diff -r 5738b78f53b5 MoinMoin/action/refresh.py
4.108 +--- a/MoinMoin/action/refresh.py Sat Nov 30 20:09:43 2013 +0100
4.109 ++++ b/MoinMoin/action/refresh.py Sat Mar 29 16:23:44 2014 +0100
4.110 +@@ -14,11 +14,14 @@
4.111 + arena = request.values.get('arena', 'Page.py')
4.112 + if arena == 'Page.py':
4.113 + arena = Page(request, pagename)
4.114 +- key = request.values.get('key', 'text_html')
4.115 ++ prefix = request.values.get('key', 'text_html')
4.116 +
4.117 + # Remove cache entry (if exists), and send the page
4.118 + from MoinMoin import caching
4.119 +- caching.CacheEntry(request, arena, key, scope='item').remove()
4.120 ++ keys = caching.get_cache_list(request, arena, 'item')
4.121 ++ for key in keys:
4.122 ++ if key.startswith(prefix):
4.123 ++ caching.CacheEntry(request, arena, key, scope='item').remove()
4.124 + caching.CacheEntry(request, arena, "pagelinks", scope='item').remove()
4.125 + request.page.send_page()
4.126 +
4.127 +diff -r 5738b78f53b5 MoinMoin/formatter/text_python.py
4.128 +--- a/MoinMoin/formatter/text_python.py Sat Nov 30 20:09:43 2013 +0100
4.129 ++++ b/MoinMoin/formatter/text_python.py Sat Mar 29 16:23:44 2014 +0100
4.130 +@@ -10,6 +10,7 @@
4.131 +
4.132 + import time
4.133 + from MoinMoin import wikiutil
4.134 ++from MoinMoin.support.python_compatibility import set
4.135 +
4.136 +
4.137 + class Formatter:
4.138 +@@ -40,6 +41,12 @@
4.139 + self.text_cmd_begin = '\nrequest.write('
4.140 + self.text_cmd_end = ')\n'
4.141 +
4.142 ++ # Record dependency requirements of certain content
4.143 ++ self.__dependencies = set()
4.144 ++
4.145 ++ def getReportedDependencies(self):
4.146 ++ return self.__dependencies
4.147 ++
4.148 + def assemble_code(self, text):
4.149 + """inserts the code into the generated text
4.150 + """
4.151 +@@ -186,7 +193,10 @@
4.152 + return self.formatter.div(on, **kw)
4.153 +
4.154 + def macro(self, macro_obj, name, args, markup=None):
4.155 +- if self.__is_static(macro_obj.get_dependencies(name)):
4.156 ++ Dependencies = macro_obj.get_dependencies(name)
4.157 ++ self.__dependencies.update(Dependencies)
4.158 ++
4.159 ++ if self.__is_static(Dependencies):
4.160 + # XXX: why is this necessary??
4.161 + macro_obj.formatter = self
4.162 + return macro_obj.execute(name, args)
4.163 +@@ -204,6 +214,7 @@
4.164 + Dependencies = wikiutil.searchAndImportPlugin(self.request.cfg, "parser", parser_name, "Dependencies")
4.165 + except (wikiutil.PluginMissingError, wikiutil.PluginAttributeError):
4.166 + Dependencies = self.defaultDependencies
4.167 ++ self.__dependencies.update(Dependencies)
4.168 +
4.169 + if self.__is_static(Dependencies):
4.170 + return self.formatter.parser(parser_name, lines)