Changeset 1510
- Timestamp:
- 27.03.2008 16:59:44 (2 months ago)
- Files:
-
- trunk/pylucid/PyLucid/db/__init__.py (modified) (1 diff)
- trunk/pylucid/PyLucid/index.py (modified) (7 diffs)
- trunk/pylucid/PyLucid/install/tests.py (modified) (3 diffs)
- trunk/pylucid/PyLucid/middlewares/cache.py (added)
- trunk/pylucid/PyLucid/middlewares/common.py (modified) (3 diffs)
- trunk/pylucid/PyLucid/middlewares/pagestats.py (deleted)
- trunk/pylucid/PyLucid/models.py (modified) (5 diffs)
- trunk/pylucid/PyLucid/settings_example.py (modified) (2 diffs)
- trunk/pylucid/PyLucid/template_addons/filters.py (modified) (1 diff)
- trunk/pylucid/tests/cache.py (added)
- trunk/pylucid/tests/internal_pages.py (modified) (1 diff)
- trunk/pylucid/tests/plugin_backlinks.py (modified) (2 diffs)
- trunk/pylucid/tests/plugin_main_menu.py (modified) (2 diffs)
- trunk/pylucid/tests/stylesheet.py (modified) (3 diffs)
- trunk/pylucid/tests/utils/BrowserDebug.py (modified) (1 diff)
- trunk/pylucid/tests/__init__.py (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/pylucid/PyLucid/db/__init__.py
r1079 r1510 1 #!/usr/bin/python2 # -*- coding: UTF-8 -*-3 4 """5 shared DB Objects.6 """7 8 import pagetrunk/pylucid/PyLucid/index.py
r1507 r1510 18 18 """ 19 19 20 import datetime, md521 22 20 from django.http import HttpResponse, HttpResponsePermanentRedirect, \ 23 21 HttpResponseRedirect 22 from django.conf import settings 24 23 from django.template import RequestContext 25 from django. core.cache import cache24 from django.utils.safestring import mark_safe 26 25 from django.utils.translation import ugettext as _ 27 from django.utils.safestring import mark_safe 28 from django.conf import settings 29 30 from PyLucid import models 31 26 27 from PyLucid.models import Page 32 28 from PyLucid.system import plugin_manager 29 from PyLucid.system.URLs import URLs 30 from PyLucid.system.page_msg import PageMessages 33 31 from PyLucid.system.response import SimpleStringIO 34 32 from PyLucid.system.exceptions import AccessDenied 35 from PyLucid.system. page_msg import PageMessages33 from PyLucid.system.context_processors import add_dynamic_context, add_css_tag 36 34 from PyLucid.system.detect_page import get_current_page_obj, \ 37 35 get_default_page_id 38 from PyLucid.system.URLs import URLs 39 from PyLucid.system.context_processors import add_dynamic_context, add_css_tag 40 from PyLucid.system.utils import setup_debug 36 from PyLucid.tools.utils import escape, escape_django_tags 41 37 from PyLucid.tools.content_processors import apply_markup, \ 42 38 render_string_template, redirect_warnings 43 from PyLucid.tools.utils import escape, escape_django_tags44 39 from PyLucid.plugins_internal.page_style.page_style import replace_add_data 45 40 … … 135 130 136 131 137 def patch_response_headers(response, cache_timeout, ETag, last_modified):138 """139 Adds some useful headers to the given HttpResponse object:140 ETag, Last-Modified, Expires and Cache-Control141 142 Original version: django.utils.cache.patch_response_headers()143 """144 response['ETag'] = ETag145 response['Last-Modified'] = last_modified.strftime(146 '%a, %d %b %Y %H:%M:%S GMT'147 )148 now = datetime.datetime.utcnow()149 expires = now + datetime.timedelta(0, cache_timeout)150 response['Expires'] = expires.strftime('%a, %d %b %Y %H:%M:%S GMT')151 152 153 def get_cached_data(url):154 """155 -Build the cache_key from the given url. Use the last page shortcut.156 -retuned the cache_key and the page data.157 """158 if url == "":159 # Request without a shortcut -> request the default page160 shortcut = "/"161 else:162 # Note: We use append_slash, but the url pattern striped the last163 # slash out.164 # e.g.: '/page1/page2/page3' -> ['/page1/page2', 'page3'] -> 'page3'165 shortcut = url.rsplit("/", 1)[-1]166 167 cache_key = settings.PAGE_CACHE_PREFIX + shortcut168 #print "Used cache key:", cache_key169 170 # Get the page data from the cache.171 response = cache.get(cache_key)172 173 return cache_key, response174 175 176 132 def index(request, url): 177 133 """ … … 181 137 the page shortcut from the url. 182 138 """ 183 # Cache only for anonymous users. Otherwise users how are log-in don't see184 # the dynamic integrate admin menu.185 use_cache = request.user.is_anonymous()186 187 if use_cache:188 # Try to get the cms page request from the cache189 cache_key, response = get_cached_data(url)190 if response:191 # This page has been cached in the past, use the cache data:192 return response193 194 setup_debug(request)195 196 139 try: 197 140 current_page_obj = get_current_page_obj(request, url) … … 211 154 212 155 context = _get_context(request, current_page_obj) 156 213 157 # Get the response for the requested cms page: 214 158 response = _render_cms_page(request, context) 215 159 216 if use_cache: 217 # It's a anonymous user -> Cache the cms page. 218 cache_timeout = settings.CACHE_MIDDLEWARE_SECONDS 219 # Add some headers for the browser cache 220 patch_response_headers( 221 response, cache_timeout, 222 ETag = md5.new(cache_key).hexdigest(), 223 last_modified = current_page_obj.lastupdatetime, 224 ) 225 # Save the page into the cache 226 cache.set(cache_key, response, cache_timeout) 160 if getattr(request, "_use_cache", None) == None: 161 # Set _use_cache information for the PyLucid cache middleware, but only 162 # if it was set to true or false in the past 163 request._use_cache = True 227 164 228 165 return response 166 229 167 230 168 def _get_page(request, page_id): … … 233 171 TODO: Check int(page_id)! 234 172 """ 235 setup_debug(request)236 237 173 try: 238 current_page_obj = models.Page.objects.get(id=int(page_id))239 except models.Page.DoesNotExist:174 current_page_obj = Page.objects.get(id=int(page_id)) 175 except Page.DoesNotExist: 240 176 # The ID in the url is wrong -> goto the default page 241 177 default_page_id = get_default_page_id() 242 current_page_obj = models.Page.objects.get(id=default_page_id)178 current_page_obj = Page.objects.get(id=default_page_id) 243 179 244 180 user = request.user … … 256 192 257 193 return current_page_obj 194 258 195 259 196 def handle_command(request, page_id, module_name, method_name, url_args): … … 329 266 return HttpResponsePermanentRedirect(url) 330 267 268 331 269 def permalink(request, page_id): 332 270 """ trunk/pylucid/PyLucid/install/tests.py
r1302 r1510 4 4 """ 5 5 6 import os, cgi, sys, time 7 8 from django.conf import settings 9 10 from django import newforms as forms 11 from django.core import management 12 from django.core.cache import cache 13 6 14 from PyLucid.install.BaseInstall import BaseInstall 7 15 from PyLucid.system.response import SimpleStringIO 8 9 from django.core import management10 from django import newforms as forms11 12 import os, cgi, sys, time13 16 14 17 … … 22 25 print txt 23 26 print "-"*80 27 28 def _test_cache(self): 29 """ 30 Test the cache backend. 31 """ 32 if settings.CACHE_BACKEND.startswith("dummy"): 33 return 34 self._print_infoline( 35 "Test cache backend '%s':" % settings.CACHE_BACKEND 36 ) 37 cache_key = "cache test" 38 content = "A cache test content..." 39 cache_timeout = 50 40 print "Save into cache with key '%s'." % cache_key 41 cache.set(cache_key, content, cache_timeout) 42 print "Try to get the saved content from the cache." 43 cached_content = cache.get(cache_key) 44 if cached_content == None: 45 print " * Get None back. Cache didn't work!" 46 return 47 elif cached_content==content: 48 print " * Cache works fine ;)" 49 else: 50 # Should never appears 51 print " * Error! Cache content not the same!" 52 53 print "Try to delete the cache entry." 54 cache.delete(cache_key) 55 cached_content = cache.get(cache_key) 56 if cached_content == None: 57 print "OK, entry deleted." 58 else: 59 print "Error: entry not deleted!" 60 24 61 25 62 def _verbose_try_import(self, module_name): … … 109 146 110 147 def print_info(self): 148 self._test_cache() 149 111 150 self._print_infoline("Tests for the memcache backend:") 112 151 self._verbose_try_import("cmemcache") trunk/pylucid/PyLucid/middlewares/common.py
r1507 r1510 31 31 from PyLucid.system.exceptions import LowLevelError 32 32 from PyLucid.system.template import render_help_page 33 from PyLucid.system.utils import setup_debug 33 34 34 35 … … 58 59 """ 59 60 def process_request(self, request): 61 # add the attribute "debug" to the request object. 62 setup_debug(request) 63 60 64 try: 61 65 session_middleware.process_request(request) … … 64 68 except Exception, e: 65 69 raise_non_table_error(e) 66 67 70 68 71 def process_view(self, request, view_func, view_args, view_kwargs): trunk/pylucid/PyLucid/models.py
r1507 r1510 18 18 import os, posixpath, pickle 19 19 20 from django.conf import settings 20 21 from django.db import models 21 from django.co ntrib.auth.models import User, Group22 from django.contrib.auth.models import U NUSABLE_PASSWORD22 from django.core.cache import cache 23 from django.contrib.auth.models import User, Group, UNUSABLE_PASSWORD 23 24 from django.utils.translation import ugettext as _ 24 from django.conf import settings25 25 26 26 from PyLucid.tools.shortcuts import getUniqueShortcut 27 27 from PyLucid.tools import crypt 28 28 from PyLucid.system.utils import get_uri_base 29 #from PyLucid.db.cache import delete_page_cache 29 30 30 31 … … 38 39 ) 39 40 41 def delete_page_cache(): 42 """ 43 Delete all pages in the cache. 44 Needed, if: 45 - A template has been edited 46 - The menu changes (edit the page name, position, parent link) 47 TODO: move this function from models.py into a other nice place... 48 """ 49 for items in Page.objects.values('shortcut').iterator(): 50 shortcut = items["shortcut"] 51 cache_key = settings.PAGE_CACHE_PREFIX + shortcut 52 cache.delete(cache_key) 53 40 54 41 55 class Page(models.Model): 42 56 """ 43 57 A CMS Page Object 58 59 TODO: We should refactor the "pre_save" behavior, use signals: 60 http://code.djangoproject.com/wiki/Signals 44 61 """ 45 62 # Explicite id field, so we can insert a help_text ;) … … 239 256 self._check_parent(self.id) 240 257 258 # Delete all pages in the cache. 259 # FIXME: This is only needed, if the menu changed: e.g.: if the page 260 # position, shortcut, parent cahnges... 261 delete_page_cache() 262 241 263 # Rebuild shortcut / make shortcut unique: 242 264 self._prepare_shortcut() 265 266 # Delete old page cache, if exist 267 cache_key = settings.PAGE_CACHE_PREFIX + self.shortcut 268 cache.delete(cache_key) 243 269 244 270 super(Page, self).save() # Call the "real" save() method … … 711 737 pass 712 738 739 #Delete the page cache if a stylesheet was edited. 740 delete_page_cache() 741 713 742 super(Style, self).save() # Call the "real" save() method 714 743 … … 729 758 description = models.TextField() 730 759 content = models.TextField() 760 761 def save(self): 762 """ 763 Delete the page cache if a template was edited. 764 """ 765 delete_page_cache() 766 767 super(Template, self).save() # Call the "real" save() method 731 768 732 769 class Admin: trunk/pylucid/PyLucid/settings_example.py
r1505 r1510 90 90 'PyLucid.middlewares.common.PyLucidCommonMiddleware', 91 91 92 'PyLucid.middlewares.cache.CacheMiddleware', 93 92 94 'django.middleware.common.CommonMiddleware', 93 95 'django.middleware.doc.XViewMiddleware', … … 95 97 # Add a human readable anchor to every html headline: 96 98 'PyLucid.middlewares.headline_anchor.HeadlineAnchor', 97 98 # Insert a statistic line into the generated page:99 'PyLucid.middlewares.pagestats.PageStatsMiddleware',100 99 ) 101 100 trunk/pylucid/PyLucid/template_addons/filters.py
r1420 r1510 58 58 """ 59 59 Converts a time duration into a friendly text representation. 60 Note: Used in PageStatsMiddleware, too.60 Note: Used in the PyLucid cache middleware, too. 61 61 """ 62 62 if t<1: trunk/pylucid/tests/internal_pages.py
r1476 r1510 54 54 Page.objects.all().delete() # Delete all existins pages 55 55 56 self.template = tests.create_template( TEST_TEMPLATE)56 self.template = tests.create_template(content = TEST_TEMPLATE) 57 57 58 58 # Create the test pages defined in content_test_utils.py trunk/pylucid/tests/plugin_backlinks.py
r1454 r1510 41 41 Page.objects.all().delete() # Delete all existins pages 42 42 43 self.template = tests.create_template("{% lucidTag back_links %}") 43 self.template = tests.create_template( 44 content = "{% lucidTag back_links %}" 45 ) 44 46 45 47 # Create the test pages defined in content_test_utils.py … … 74 76 print_last_page="True" 75 77 """ 76 77 78 self.template.content = ( 78 79 '{% lucidTag back_links print_last_page="True" %}' trunk/pylucid/tests/plugin_main_menu.py
r1454 r1510 36 36 Page.objects.all().delete() # Delete all existins pages 37 37 38 self.template = tests.create_template("{% lucidTag main_menu %}") 38 self.template = tests.create_template( 39 content = "{% lucidTag main_menu %}" 40 ) 39 41 40 42 tests.create_pages(tests.TEST_PAGES, template=self.template) … … 97 99 Page.objects.all().delete() # Delete all existins pages 98 100 99 self.template = tests.create_template("{% lucidTag main_menu %}") 101 self.template = tests.create_template( 102 content = "{% lucidTag main_menu %}" 103 ) 100 104 101 105 def test_base(self): trunk/pylucid/tests/stylesheet.py
r1476 r1510 52 52 Page.objects.all().delete() # Delete all existins pages 53 53 54 self.template = tests.create_template("{% lucidTag page_style %}") 54 self.template = tests.create_template( 55 content = "{% lucidTag page_style %}" 56 ) 55 57 self.style = tests.create_stylesheet( 56 58 name = "TestStyle", content = TEST_STYLE_CONTENT, … … 90 92 """ Return the stylesheet link contains in the root cms page. """ 91 93 response = self.client.get("/") 94 from_cache = response.get("from_cache", None) 95 print from_cache 92 96 content = response.content 93 97 links = self._exctract_stylelinks(content) … … 150 154 must_link = self._get_stylelink() 151 155 is_link = self._get_content_link() 152 assert is_link == must_link156 self.failUnlessEqual(must_link, is_link) 153 157 154 158 def test_command_link(self): trunk/pylucid/tests/utils/BrowserDebug.py
r1501 r1510 58 58 stack_info = "".join(stack) 59 59 60 info = ( 61 "\n<br /><hr />\n" 62 "<h3>Unittest info</h3>\n" 63 "<dl>\n" 64 "<dt>url:</dt><dd>%s</dd>\n" 65 "<dt>traceback:</dt><dd><pre>%s</pre></dd>\n" 66 "</dl>\n" 67 "</body>" 68 ) % (url, stack_info) 69 70 content = content.replace("</body>", info) 60 if "</body>" in content: 61 info = ( 62 "\n<br /><hr />\n" 63 "<h3>Unittest info</h3>\n" 64 "<dl>\n" 65 "<dt>url:</dt><dd>%s</dd>\n" 66 "<dt>response info:</dt><dd><pre>%s</pre></dd>\n" 67 "<dt>traceback:</dt><dd><pre>%s</pre></dd>\n" 68 "</dl>\n" 69 "</body>" 70 ) % (url, response, stack_info) 71 content = content.replace("</body>", info) 72 else: 73 # Not a html page? 74 content += "\n<pre>\n" 75 content += "-" * 79 76 content += ( 77 "\nUnittest info\n" 78 "=============\n" 79 "url: %s\n" 80 "response info:\n%s\n" 81 "traceback:\n%s\n</pre>" 82 ) % (url, response, stack_info) 71 83 72 84 trunk/pylucid/tests/__init__.py
r1507 r1510 225 225 is_list2 = pprint.pformat(is_list) 226 226 should_be_list2 = pprint.pformat(should_be_list) 227 print "\nThe two lists are not the same:" 227 228 for line in make_diff(should_be_list2, is_list2): 228 229 print line … … 313 314 314 315 # _________________________________________________________________________ 315 # common tests: 316 # link snapshot: 317 316 318 def link_snapshot_test(self, snapshot): 317 319 """ … … 330 332 331 333 self.assertLists(is_links, should_be_links, sort=False) 334 335 def create_link_snapshot(self, print_result=True): 336 """ 337 Build a a reference snapshot for a unittest. 338 Display it via pprint and returned it, too. 339 Usefull for copy&paste the output into this source file :) 340 """ 341 if print_result: 342 print "Build a snapshot for the unittest compare:" 343 print "-"*79 344 data = {} 345 for page in Page.objects.all(): 346 url = page.get_absolute_url() 347 348 response = self.client.get(url) 349 self.failUnlessEqual(response.status_code, 200) 350 351 content = response.content.strip() 352 links = self.get_links(content) 353 354 data[url] = links 355 356 if print_result: 357 pprint.pprint(data) 358 print "-"*79 359 return data 332 360 333 361 … … 391 419 392 420 393 def create_template( content):421 def create_template(**kwargs): 394 422 """ 395 423 Delete all existing templates, create a new one and return the instance. … … 397 425 Template.objects.all().delete() 398 426 399 template = Template( content = content)427 template = Template(**kwargs) 400 428 template.save() 401 429 return template … … 421 449 default_template = Template.objects.all()[0] 422 450 default_style = Style.objects.all()[0] 423 default_markup = 0 # html with dout TinyMCE451 default_markup = 0 # html without TinyMCE 424 452 425 453 page = Page( 426 454 name = data.get("name", "New Page"), 427 455 shortcut = data.get("shortcut", None), 456 content = data.get("content", "TestPageContent"), 428 457 template = data.get("template", default_template), 429 458 style = data.get("style", default_style),
