Revision: 455
Author: ralfoide
Date: Tue Sep 7 00:27:42 2010
Log: Several minor fixes and some new unit-tests.
This is work in progress.
http://code.google.com/p/rig3/source/detail?r=455
Added:
/trunk/rig3serv/src/tests/site/test_site_default.py
/trunk/rig3serv/src/tests/test_rig3_pipeline.py
Deleted:
/trunk/rig3serv/src/tests/site/test_site_defaut.py
Modified:
/trunk/rig3serv/misc/Design.txt
/trunk/rig3serv/src/rig/parser/izu_parser.py
/trunk/rig3serv/src/rig/site/site_default.py
/trunk/rig3serv/src/rig/source_reader.py
/trunk/rig3serv/src/rig/template/buffer.py
/trunk/rig3serv/src/rig/template/tag.py
/trunk/rig3serv/src/rig/template/template.py
/trunk/rig3serv/src/test_rig3.py
/trunk/rig3serv/src/tests/parser/test_izu_parser.py
/trunk/rig3serv/src/tests/template/test_template.py
/trunk/rig3serv/src/tests/z_last/render_testdata.py
/trunk/rig3serv/src/tests/z_last/test_rig3_live.py
/trunk/rig3serv/testdata/album/blog2/2007-10-07 11.00_Folder 2/index.izu
/trunk/rig3serv/testdata/templates/default/html_entry.html
=======================================
--- /dev/null
+++ /trunk/rig3serv/src/tests/site/test_site_default.py Tue Sep 7 00:27:42
2010
@@ -0,0 +1,1124 @@
+#!/usr/bin/python
+#-----------------------------------------------------------------------------|
+"""
+Unit tests for Site
+
+Part of Rig3.
+Copyright (C) 2007-2009 ralfoide gmail com
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <
http://www.gnu.org/licenses/>.
+
+"""
+__author__ = "ralfoide at gmail com"
+
+import os
+import types
+from datetime import datetime
+
+from tests.rig_test_case import RigTestCase
+
+from rig.site.site_default import SiteDefault, ContentEntry
+from rig.site_base import DEFAULT_THEME, SiteItem
+from rig.sites_settings import SiteSettings
+from rig.parser.dir_parser import DirParser, RelDir, RelFile
+from rig.source_reader import SourceDirReader
+from rig.source_item import SourceDir, SourceSettings, SourceContent
+from rig.sites_settings import SiteSettings, SitesSettings
+from rig.sites_settings import DEFAULT_ITEMS_PER_PAGE
+
+#------------------------
+class MockSiteDefault(SiteDefault):
+ """
+ Behaves like a SiteDefault() but overrides the base template directory
location
+ to use testdata/templates instead.
+
+ Also traps the last _Filltemplate parameters.
+ """
+ def __init__(self, test_case, log, dry_run, force, site_settings):
+ self._test_case = test_case
+ self._fill_template_params = {}
+ self._write_file_params = []
+ super(MockSiteDefault, self).__init__(log, dry_run, force,
site_settings)
+
+ # override the Cache.Clear method by ours
+ self._cache_clear_count = 0
+ self._org_cache_clear = self._cache.Clear
+ setattr(self._cache, "Clear", self._CacheClearOverride)
+
+ def _TemplateDir(self):
+ """"
+ Uses testdata/templates/ instead of templates/
+ """
+ return os.path.join(self._test_case.getTestDataPath(), "templates")
+
+ def _FillTemplate(self, template, **keywords):
+ """
+ Keeps a copy of the _FillTemplate parameters and then calls the
original.
+ Trapped parameters are available in
+ self._fill_template_params[template] => list(keyword dict.)
+ """
+ if not template in self._fill_template_params:
+ self._fill_template_params[template] = []
+ self._fill_template_params[template].append(dict(keywords))
+ return super(MockSiteDefault, self)._FillTemplate(template,
**keywords)
+
+ def _WriteFile(self, data, dest_dir, leafname):
+ """
+ Keeps a copy of all parameters given to _WriteFile.
+ This implementation does NOT call the base class so that nothing
gets
+ written anywhere.
+
+ Trapped parameters are available in
+ self._write_file_params => list(data, dest_dir, leafname)
+ See GetWriteFileData(n, m) below.
+ """
+ self._write_file_params.append((data, dest_dir, leafname))
+
+ _DATA = 0
+ _DEST_DIR = 1
+ _LEAFNAME = 2
+
+ def GetWriteFileData(self, tuple_index):
+ """
+ Returns a *copy* of the self._write_file_params list
+ with items rearranged.
+ - tuple_index: _DATA, _DEST_DIR or _LEAFNAME, the value to return.
+
+ This basically remaps (data, dest_dir, leafname) to whatever you
like
+ to test, e.g. list[ value: leafname ] or list[ value: data ].
+ """
+ return [ p[tuple_index] for p in self._write_file_params ]
+
+ def _CacheClearOverride(self):
+ """
+ Override self._cache.Clear to count the number of calls then
+ call the original implementation.
+ """
+ self._cache_clear_count += 1
+ self._org_cache_clear()
+
+ def CacheClearCount(self, reset):
+ """
+ Returns the number of cache clear done so far.
+ If reset is true, resets the count to 0.
+ """
+ c = self._cache_clear_count
+ if reset:
+ self._cache_clear_count = 0
+ return c
+
+#------------------------
+class SiteDefaultTest(RigTestCase):
+
+ def setUp(self):
+ self._tempdir = self.MakeTempDir()
+ self._cachedir = self.MakeTempDir()
+ self.sis, self.sos = self._computeSisSos()
+
+ self.keywords = self.sis.AsDict()
+ self.keywords.update(self.sos.AsDict())
+
+ def _computeSisSos(self):
+ source = SourceDirReader(self.Log(),
+ site_settings=None,
+ source_settings=None,
+
path=os.path.join(self.getTestDataPath(), "album"))
+ sis = SiteSettings(public_name="Test Album",
+ source_list=[ source ],
+ dest_dir=self._tempdir,
+ cache_dir=self._cachedir,
+ theme=DEFAULT_THEME,
+ base_url="
http://www.example.com",
+ encoding="iso-8859-1")
+ sos =
SourceSettings(rig_base="
http://example.com/photos/index.php")
+ return sis, sos
+
+ def tearDown(self):
+ self.RemoveDir(self._tempdir)
+ self.RemoveDir(self._cachedir)
+
+ def testSimpleFileName(self):
+ m = MockSiteDefault(self, self.Log(), False, True, self.sis)
+ self.assertEquals("filename_txt",
m._SimpleFileName("filename.txt"))
+ self.assertEquals("abc-de-f-g-h", m._SimpleFileName("abc---de
f-g h"))
+ self.assertEquals("abc-de-f-g-h",
m._SimpleFileName("abc///de\\\\f/g\\h"))
+ self.assertEquals("a-ab_12_txt",
m._SimpleFileName("a//\\ab!@#$12%^&@&*()_+.<>,txt"))
+ self.assertEquals("long_3e3a06df",
m._SimpleFileName("long_filename.txt", maxlen=13))
+ self.assertEquals("someverylon_7eea09fa",
m._SimpleFileName("someverylongfilename.txt", maxlen=20))
+ self.assertEquals("the-unit-test-is-the-proof",
m._SimpleFileName("the unit test is the proof", 50))
+ self.assertEquals("the-unit-test-is_81bc09a5",
m._SimpleFileName("the unit test is the proof", 25))
+
+ # the default for mangled_name_len is 50
+ self.assertEquals("the-unit-test-is-the-proof",
m._SimpleFileName("the unit test is the proof",
+
self.sis.mangled_name_len))
+ self.sis.mangled_name_len = 25
+ self.assertEquals("the-unit-test-is_81bc09a5",
m._SimpleFileName("the unit test is the proof"))
+ # 0 deactivates the mangling
+ self.sis.mangled_name_len = 0
+ self.assertEquals("the-unit-test-is-the-proof",
m._SimpleFileName("the unit test is the proof"))
+
+ def testFillTemplate(self):
+ m = MockSiteDefault(self, self.Log(), False, True, self.sis)
+
+ keywords = dict(self.keywords)
+ keywords["title"] = "MyTitle"
+ keywords["entries"] = [
+ ContentEntry("content entry1", "entry1", None, "url1"),
+ ContentEntry("content entry2", "entry2", None, "url2") ]
+ keywords["curr_category"] = ""
+ keywords["all_categories"] = []
+ keywords["toc_categories"] = []
+ keywords["last_gen_ts"] = datetime(2007, 11, 12, 14, 15, 16)
+ keywords["last_content_ts"] = datetime(2001, 3, 14, 15, 9, 2)
+ keywords["rig3_version"] = "3.1.4.15"
+
+ html = m._FillTemplate(SiteDefault._TEMPLATE_HTML_INDEX,
**keywords)
+ self.assertIsInstance(str, html)
+ self.assertTrue(SiteDefault._TEMPLATE_HTML_INDEX in
m._fill_template_params)
+ self.assertTrue(1,
len(m._fill_template_params[SiteDefault._TEMPLATE_HTML_INDEX]))
+ self.assertDictEquals(keywords,
m._fill_template_params[SiteDefault._TEMPLATE_HTML_INDEX][0])
+ self.assertListEquals([], m.GetWriteFileData(m._LEAFNAME))
+ self.assertHtmlEquals(
+ r"""<html lang="en-US">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html;
charset=UTF-8"/>
+ <link rel="stylesheet" type="text/css"
href="media/style.css" />
+ <title>Test Album - MyTitle</title>
+ </head>
+ <body>
+ (placeholder for image header)<br/>
+ blog name is Test Album<br/>
+ categories are All<br/>
+ content entry1
+ content entry2
+ <p>
+ Most recent entry: 2001-03-14 15:09:02 --
+ Generated on 2007-11-12 14:15:16 by <a
href="
http://code.google.com/p/rig3/">Rig3 3.1.4.15</a>
+ </body>
+ </html>""",
+ html)
+
+ keywords = dict(self.keywords)
+ keywords["title"] = "MyTitle"
+ keywords["sections"] = { "en": "Main <b>Text Content</b> as HTML",
+ "images": "<a href='page_url'><img
src='image_url'/></a>" }
+ html = m._FillTemplate(SiteDefault._TEMPLATE_HTML_ENTRY,
**keywords)
+ self.assertIsInstance(str, html)
+ self.assertTrue(SiteDefault._TEMPLATE_HTML_ENTRY in
m._fill_template_params)
+ self.assertTrue(1,
len(m._fill_template_params[SiteDefault._TEMPLATE_HTML_ENTRY]))
+ self.assertDictEquals(keywords,
m._fill_template_params[SiteDefault._TEMPLATE_HTML_ENTRY][0])
+ self.assertListEquals([], m.GetWriteFileData(m._LEAFNAME))
+ self.assertHtmlEquals(
+ r"""<div class="entry">
+ <h2>MyTitle</h2>
+ Main <b>Text Content</b> as HTML
+ <br/>
+ <a href='page_url'><img src='image_url'/></a>
+ <br/>
+ </div>
+ """,
+ html)
+
+ def testDateAndTitleFromTitle(self):
+ m = MockSiteDefault(self, self.Log(), False, True, self.sis)
+
+ self.assertEquals((None, "27"),
m._DateAndTitleFromTitle("27"))
+ self.assertEquals((None, "2007"),
m._DateAndTitleFromTitle("2007"))
+ self.assertEquals((None, "2007-1"),
m._DateAndTitleFromTitle("2007-1"))
+
+ # lack of day is the same as using day=01
+ self.assertEquals((datetime(2007, 10, 1), ""),
+ m._DateAndTitleFromTitle("2007-10"))
+
+ # here we don't interpret "YYYYMM[-]2" as a day because it lacks 2
digits,
+ # instead it gets interpreted as the title.
+ self.assertEquals((datetime(2007, 10, 1), "2"),
+ m._DateAndTitleFromTitle("2007102"))
+ self.assertEquals((datetime(2007, 10, 1), "2"),
+ m._DateAndTitleFromTitle("2007-10-2"))
+
+ self.assertEquals((datetime(2007, 10, 27), ""),
+ m._DateAndTitleFromTitle("20071027"))
+ self.assertEquals((datetime(2007, 10, 27), "rest"),
+ m._DateAndTitleFromTitle("2007-10-27 rest"))
+ self.assertEquals((datetime(2007, 10, 27), "rest of the line.."),
+ m._DateAndTitleFromTitle("2007/10/27_rest of the
line.."))
+ self.assertEquals((datetime(2007, 10, 27), "whitespace"),
+ m._DateAndTitleFromTitle("2007-10/27
whitespace "))
+ self.assertEquals((datetime(2007, 10, 27, 12, 13, 14), ""),
m._DateAndTitleFromTitle("20071027121314"))
+ self.assertEquals((datetime(2007, 10, 27, 12, 13, 14), ""),
m._DateAndTitleFromTitle("2007-10-27-12-13-14"))
+ self.assertEquals((datetime(2007, 10, 27, 12, 13, 14), ""),
m._DateAndTitleFromTitle("2007-10-27 12-13-14"))
+ self.assertEquals((datetime(2007, 10, 27, 12, 13, 14), ""),
m._DateAndTitleFromTitle("2007/10/27 12:13:14"))
+ self.assertEquals((datetime(2007, 10, 27, 12, 13, 14), ""),
m._DateAndTitleFromTitle("2007-10/27,12/13/14"))
+
+ self.assertEquals((None, "white space"),
m._DateAndTitleFromTitle("_white space_"))
+ self.assertEquals((None, "white space"),
m._DateAndTitleFromTitle("_white_space_"))
+ self.assertEquals((None, "white space"),
m._DateAndTitleFromTitle(" ___\twhite_\r\n\f_ __space_ \r\t\n\f___ "))
+
+
+ def testDateAndTitleFromTitle_ErrorCases(self):
+ m = MockSiteDefault(self, self.Log(), False, True, self.sis)
+
+ # Hour is invalid: 44>23... log warning and ignore hour in this
case
+ self.assertEquals((datetime(2007, 10, 27), ""),
+ m._DateAndTitleFromTitle("20071027-4400"))
+
+ # Day must be in 1..31
+ self.assertRaises(ValueError, m._DateAndTitleFromTitle, "20071034")
+
+ # Month must be in 1..12
+ self.assertRaises(ValueError, m._DateAndTitleFromTitle, "20071527")
+
+ # Year must be in range 1..9999
+ self.assertRaises(ValueError, m._DateAndTitleFromTitle, "00001027")
+ self.assertEquals((datetime(1, 10, 27), ""),
+ m._DateAndTitleFromTitle("00011027"))
+ self.assertEquals((datetime(9999, 10, 27), ""),
+ m._DateAndTitleFromTitle("99991027"))
+
+ def testGenerateItems_Izu(self):
+ m = MockSiteDefault(self, self.Log(), False, True,
self.sis).MakeDestDirs()
+ source_dir = os.path.join(self.getTestDataPath(), "album", "blog1")
+ item = m.GenerateItem(SourceDir(datetime.today(),
+
RelDir(source_dir, "2007-10-07_Folder 1"),
+ [ "index.izu" ],
+ self.sos))
+ self.assertNotEquals(None, item)
+ self.assertEquals(datetime(2007, 10, 07), item.date)
+ self.assertHtmlMatches(r'<div class="entry">.+</div>',
item.content_gen(SiteDefault._TEMPLATE_HTML_ENTRY))
+ self.assertListEquals([ "foo", "bar", "other" ], item.categories,
sort=True)
+
+ def testGenerateItems_Html(self):
+ m = MockSiteDefault(self, self.Log(), False, True,
self.sis).MakeDestDirs()
+ source_dir = os.path.join(self.getTestDataPath(), "album", "blog2")
+ item = m.GenerateItem(SourceDir(datetime.today(),
+
RelDir(source_dir, "2006-05_Movies"),
+ [ "index.html" ],
+ self.sos))
+ self.assertNotEquals(None, item)
+ self.assertEquals(datetime(2006, 5, 28, 17, 18, 5), item.date)
+ self.assertHtmlMatches(r'<div class="entry">.+<!-- \[izu:.+\]
-->blog 2 <table.+>.+</table>.+</div>',
+
item.content_gen(SiteDefault._TEMPLATE_HTML_ENTRY))
+ self.assertListEquals([ "videos" ], item.categories, sort=True)
+
+ def testImgPattern(self):
+ m = MockSiteDefault(self, self.Log(), False, True,
self.sis).MakeDestDirs()
+ self.assertEquals(None, m._IMG_PATTERN.match("myimage.jpg"))
+ self.assertEquals(None, m._IMG_PATTERN.match("PICT1200.jpg"))
+ self.assertEquals(None, m._IMG_PATTERN.match("R12345-Some
Name.bmp"))
+ self.assertEquals(None, m._IMG_PATTERN.match("R12345-Some
Name.gif"))
+ self.assertDictEquals({ "index": "1000",
+ "rating": "_",
+ "name": " Old Index ",
+ "ext": ".jpg" },
+ m._IMG_PATTERN.match("1000_ Old
Index .jpg").groupdict())
+ self.assertDictEquals({ "index": "R12345",
+ "rating": "_",
+ "name": "Some Name",
+ "ext": ".jpg" },
+ m._IMG_PATTERN.match("R12345_Some
Name.jpg").groupdict())
+ self.assertDictEquals({ "index": "X12345",
+ "rating": "-",
+ "name": "Some Movie",
+ "ext": ".original.mov" },
+ m._IMG_PATTERN.match("X12345-Some
Movie.original.mov").groupdict())
+ self.assertDictEquals({ "index": "Y31415",
+ "rating": "+",
+ "name": "Web Version",
+ "ext": ".web.mov" },
+ m._IMG_PATTERN.match("Y31415+Web
Version.web.mov").groupdict())
+ self.assertDictEquals({ "index": "Z31415",
+ "rating": ".",
+ "name": "Web Version",
+ "ext": ".web.wmv" },
+ m._IMG_PATTERN.match("Z31415.Web
Version.web.wmv").groupdict())
+
+ def testGetRigLink(self):
+ m = MockSiteDefault(self, self.Log(), False, True, self.sis)
+
+ expected = (
+ '<a title="2007-11-08 Album Title" '
+ 'href="
http://example.com/photos/index.php?album=My%20Albums/Year_2007/2007-11-08%20Album%20Title&img=Best%20of%202007.jpg">'
+ '<img title="Best of 2007" alt="Best of 2007"
src="
http://example.com/photos/index.php?th=&album=My%20Albums/Year_2007/2007-11-08%20Album%20Title&img=Best%20of%202007.jpg&sz=400&q=75"/>'
+ '</a>'
+ )
+
+ self.assertHtmlEquals(
+ expected,
+ m._GetRigLink(self.keywords,
+ RelDir("base", "My Albums/Year_2007/2007-11-08
Album Title"),
+ "Best of 2007.jpg",
+ 400))
+
+ expected = (
+ '<a title="2007-11-08 Album Title" '
+ 'href="
http://example.com/photos/index.php?album=My%20Albums/Year_2007/2007-11-08%20Album%20Title&img=Best%20of%202007.jpg">'
+ '<img title="Best of 2007" alt="Best of 2007"
src="
http://example.com/photos/index.php?th=&album=My%20Albums/Year_2007/2007-11-08%20Album%20Title&img=Best%20of%202007.jpg&sz=-1&q=75"/>'
+ '</a>'
+ )
+
+ self.assertHtmlEquals(
+ expected,
+ m._GetRigLink(self.keywords,
+ RelDir("base", "My Albums/Year_2007/2007-11-08
Album Title"),
+ "Best of 2007.jpg",
+ -1))
+
+ expected = (
+ '<a title="2007-11-08 Album & Title" '
+ 'href="
http://example.com/photos/index.php?album=My%20Albums/Year_2007/2007-11-08%20Album%20%26%20Title">'
+ '2007-11-08 Album & Title</a>'
+ )
+
+ self.assertHtmlEquals(
+ expected,
+ m._GetRigLink(self.keywords,
+ RelDir("base", "My Albums/Year_2007/2007-11-08
Album & Title"),
+ None,
+ -1))
+
+ def testGenerateImages(self):
+ m = MockSiteDefault(self, self.Log(), False, True, self.sis)
+
+ keywords = self.keywords
+
+ self.assertEquals(
+ None,
+ m._GenerateImages(RelDir("base", ""), [], keywords))
+
+ self.assertEquals(
+ None,
+ m._GenerateImages(RelDir("base", ""), [ "index.izu",
+ "index.html",
+ "image.jpeg" ],
+ keywords ))
+
+ self.assertEquals(
+ None,
+ m._GenerateImages(RelDir("base", ""), [ "J1234_sound.mp3" ],
keywords))
+
+ self.assertHtmlEquals(
+ "See more images for " + m._GetRigLink(keywords,
RelDir("base", ""), None, -1),
+ m._GenerateImages(RelDir("base", ""), [ "J1234.image.jpg" ],
keywords))
+
+ self.assertHtmlEquals(
+ '<table class="image-table"><tr><td>\n' +
m._GetRigLink(keywords, RelDir("base", ""), "J1234-image.jpg", 300)
+ '</td></tr></table>',
+ m._GenerateImages(RelDir("base", ""), [ "J1234-image.jpg" ],
keywords))
+
+ def testGenerateIndexPage(self):
+ m = MockSiteDefault(self, self.Log(), False, True,
self.sis).MakeDestDirs()
+
+ m._GenerateIndexPage(
+ path="",
+ rel_base="",
+ curr_category=None,
+ all_categories=[],
+ items=[],
+ month_pages=[])
+ params = m._fill_template_params
+
+ for key in [ "rig_img_url",
+ "rig_thumb_url",
+ "source_list",
+ "header_img_height",
+ "tracking_code",
+ "header_img_url",
+ "rig_album_url",
+ "img_gen_script",
+ "entries",
+ "last_content_ts",
+ "rig_img_size",
+ "month_pages",
+ "rig3_version",
+ "title",
+ "rel_base_url",
+ "base_url",
+ "public_name",
+ "theme",
+ "all_categories",
+ "dest_dir",
+ "cat_filter",
+ "toc_categories",
+ "last_gen_ts" ]:
+ self.assertTrue(key in
params[SiteDefault._TEMPLATE_HTML_INDEX][0],
+ "Missing [%s] in %s" % (key, params))
+
+ def testRigAlbumLink(self):
+ m = MockSiteDefault(self, self.Log(), False, True,
self.sis).MakeDestDirs()
+
+ keywords = self.keywords
+ keywords.update(SourceSettings(rig_base=None).AsDict())
+ self.assertEquals("", m._RigAlbumLink(keywords, "my album"))
+
+
keywords.update(SourceSettings(rig_base="
http://my.rig/index.php").AsDict())
+ self.assertEquals("
http://my.rig/index.php?album=my%20album",
+ m._RigAlbumLink(keywords, "my album"))
+
+ def testRigImgLink(self):
+ m = MockSiteDefault(self, self.Log(), False, True,
self.sis).MakeDestDirs()
+
+ keywords = self.keywords
+ keywords.update(SourceSettings(rig_base=None).AsDict())
+ self.assertEquals("", m._RigImgLink(keywords, "my album", "my
image.jpg"))
+
+
keywords.update(SourceSettings(rig_base="
http://my.rig/index.php").AsDict())
+
self.assertEquals("
http://my.rig/index.php?album=my%20album&img=my%20image.jpg",
+ m._RigImgLink(keywords, "my album", "my
image.jpg"))
+
+ def testRigThumbLink(self):
+ m = MockSiteDefault(self, self.Log(), False, True,
self.sis).MakeDestDirs()
+
+ keywords = self.keywords
+ keywords.update(SourceSettings(rig_base=None).AsDict())
+ self.assertEquals("", m._RigThumbLink(keywords, "my album", "my
image.jpg", 640))
+
+
keywords.update(SourceSettings(rig_base="
http://my.rig/index.php").AsDict())
+
self.assertEquals("
http://my.rig/index.php?th=&album=my%20album&img=my%20image.jpg&sz=640&q=75",
+ m._RigThumbLink(keywords, "my album", "my
image.jpg", 640))
+
+ def testGeneratePages_0Empty(self):
+ """
+ Printing an empty list of items only generates an index page
+ """
+ m = MockSiteDefault(self, self.Log(), False, True,
self.sis).MakeDestDirs()
+ self.assertListEquals([], m.GetWriteFileData(m._LEAFNAME))
+
+ m.GeneratePages(categories=[], items=[])
+ self.assertListEquals([ "index.html", "atom.xml" ],
m.GetWriteFileData(m._LEAFNAME))
+
+ def testGeneratePages_0Cats(self):
+ """
+ Printing 3 times + 1 the number of items per page generates 4 pages
+ """
+ m = MockSiteDefault(self, self.Log(), False, True,
self.sis).MakeDestDirs()
+
+ items = []
+ cats = []
+ for x in xrange(0, DEFAULT_ITEMS_PER_PAGE * 3 + 1):
+ # x % 12 => we'll generate 12 month pages
+ si = SiteItem(source_item=None,
+ date=datetime(2000, 1 + (x % 12), 1 + (x % 28),
x % 24, x % 60, x % 60),
+ title="blah",
+ permalink="item",
+ content_gen=lambda t, x: "content",
+ categories=cats)
+ items.append(si)
+
+ m.GeneratePages(cats, items)
+ self.assertListEquals(
+ [ "2000-12.html", "2000-11.html", "2000-10.html", "2000-09.html",
+ "2000-08.html", "2000-07.html", "2000-06.html", "2000-05.html",
+ "2000-04.html", "2000-03.html", "2000-02.html", "2000-01.html",
+ "index.html", "atom.xml",
+ "post_2000-12-24_blah.html",
+ "post_2000-12-20_blah.html",
+ "post_2000-12-12_blah.html",
+ "post_2000-12-08_blah.html",
+ "post_2000-12-04_blah.html",
+ "post_2000-11-23_blah.html",
+ "post_2000-11-19_blah.html",
+ "post_2000-11-11_blah.html",
+ "post_2000-11-07_blah.html",
+ "post_2000-11-03_blah.html",
+ "post_2000-10-22_blah.html",
+ "post_2000-10-18_blah.html",
+ "post_2000-10-10_blah.html",
+ "post_2000-10-06_blah.html",
+ "post_2000-10-02_blah.html",
+ "post_2000-09-21_blah.html",
+ "post_2000-09-17_blah.html",
+ "post_2000-09-09_blah.html",
+ "post_2000-09-05_blah.html",
+ "post_2000-09-01_blah.html",
+ "post_2000-08-28_blah.html",
+ "post_2000-08-20_blah.html",
+ "post_2000-08-16_blah.html",
+ "post_2000-08-08_blah.html",
+ "post_2000-08-04_blah.html",
+ "post_2000-07-27_blah.html",
+ "post_2000-07-19_blah.html",
+ "post_2000-07-15_blah.html",
+ "post_2000-07-07_blah.html",
+ "post_2000-07-03_blah.html",
+ "post_2000-06-26_blah.html",
+ "post_2000-06-18_blah.html",
+ "post_2000-06-14_blah.html",
+ "post_2000-06-06_blah.html",
+ "post_2000-06-02_blah.html",
+ "post_2000-05-25_blah.html",
+ "post_2000-05-17_blah.html",
+ "post_2000-05-13_blah.html",
+ "post_2000-05-05_blah.html",
+ "post_2000-05-01_blah.html",
+ "post_2000-04-28_blah.html",
+ "post_2000-04-24_blah.html",
+ "post_2000-04-16_blah.html",
+ "post_2000-04-12_blah.html",
+ "post_2000-04-04_blah.html",
+ "post_2000-03-27_blah.html",
+ "post_2000-03-23_blah.html",
+ "post_2000-03-15_blah.html",
+ "post_2000-03-11_blah.html",
+ "post_2000-03-03_blah.html",
+ "post_2000-02-26_blah.html",
+ "post_2000-02-22_blah.html",
+ "post_2000-02-14_blah.html",
+ "post_2000-02-10_blah.html",
+ "post_2000-02-02_blah.html",
+ "post_2000-01-25_blah.html",
+ "post_2000-01-21_blah.html",
+ "post_2000-01-13_blah.html",
+ "post_2000-01-09_blah.html",
+ "post_2000-01-05_blah.html",
+ "post_2000-01-01_blah.html",
+ ],
+ m.GetWriteFileData(m._LEAFNAME))
+
+ # check that "all_entries" in index & month pages contain the full
list
+ # of items, not just the ones for the page (i.e. all_entries !=
entries)
+ self.assertTrue(SiteDefault._TEMPLATE_HTML_MONTH in
m._fill_template_params)
+ for keywords in
m._fill_template_params[SiteDefault._TEMPLATE_HTML_MONTH]:
+ self.assertEquals(len(items), len(keywords["all_entries"]))
+
+ self.assertTrue(SiteDefault._TEMPLATE_HTML_INDEX in
m._fill_template_params)
+ for keywords in
m._fill_template_params[SiteDefault._TEMPLATE_HTML_INDEX]:
+ self.assertEquals(len(items), len(keywords["all_entries"]))
+
+ def testGeneratePages_1Cat(self):
+ """
+ Print items with only one category, this does not generate
+ category indexes.
+ """
+ m = MockSiteDefault(self, self.Log(), False, True,
self.sis).MakeDestDirs()
+
+ items = []
+ cats = [ "first" ]
+ for x in xrange(0, DEFAULT_ITEMS_PER_PAGE + 1):
+ # x % 7 => we'll generate 7 month pages
+ si = SiteItem(source_item=None,
+ date=datetime(2000, 1 + (x % 7), 1 + (x % 28),
x % 24, x % 60, x % 60),
+ title="blah",
+ permalink="item",
+ content_gen=lambda t, x: "content",
+ categories=cats)
+ items.append(si)
+
+ m.GeneratePages(cats, items)
+ self.assertListEquals(
+ [ "2000-07.html", "2000-06.html", "2000-05.html",
+ "2000-04.html", "2000-03.html", "2000-02.html", "2000-01.html",
+ "index.html", "atom.xml",
+# "post_2000-07-21_blah.html",TODO EDIT
+# "post_2000-07-14_blah.html",
+# "post_2000-07-07_blah.html",
+# "post_2000-06-20_blah.html",
+# "post_2000-06-13_blah.html",
+# "post_2000-06-06_blah.html",
+# "post_2000-05-19_blah.html",
+# "post_2000-05-12_blah.html",
+# "post_2000-05-05_blah.html",
+# "post_2000-04-18_blah.html",
+# "post_2000-04-11_blah.html",
+# "post_2000-04-04_blah.html",
+# "post_2000-03-17_blah.html",
+# "post_2000-03-10_blah.html",
+# "post_2000-03-03_blah.html",
+# "post_2000-02-16_blah.html",
+# "post_2000-02-09_blah.html",
+# "post_2000-02-02_blah.html",
+# "post_2000-01-15_blah.html",
+# "post_2000-01-08_blah.html",
+ ],
+ m.GetWriteFileData(m._LEAFNAME))
+
+ def testGeneratePages_2Cats(self):
+ """
+ With two categories, we get category pages too
+ """
+ m = MockSiteDefault(self, self.Log(), False, True,
self.sis).MakeDestDirs()
+
+ items = []
+ cats = [ "first", "second" ]
+ for x in xrange(0, DEFAULT_ITEMS_PER_PAGE + 1):
+ # x % 5 => we'll generate 5 month pages
+ si = SiteItem(source_item=None,
+ date=datetime(2000, 1 + (x % 5), 1 + (x % 28),
x % 24, x % 60, x % 60),
+ title="blah",
+ permalink="item",
+ content_gen=lambda t, x: "content",
+ categories=cats)
+ items.append(si)
+
+ m.GeneratePages(cats, items)
+ self.assertListEquals(
+
[ "2000-05.html", "2000-04.html", "2000-03.html", "2000-02.html", "2000-01.html",
+ "index.html", "atom.xml",
+ os.path.join("cat", "first", "2000-05.html"),
+ os.path.join("cat", "first", "2000-04.html"),
+ os.path.join("cat", "first", "2000-03.html"),
+ os.path.join("cat", "first", "2000-02.html"),
+ os.path.join("cat", "first", "2000-01.html"),
+ os.path.join("cat", "first", "index.html"),
+ os.path.join("cat", "first", "atom.xml"),
+ os.path.join("cat", "first", "post_2000-05-20_blah.html"),
+ os.path.join("cat", "first", "post_2000-05-15_blah.html"),
+ os.path.join("cat", "first", "post_2000-05-10_blah.html"),
+ os.path.join("cat", "first", "post_2000-05-05_blah.html"),
+ os.path.join("cat", "first", "post_2000-04-19_blah.html"),
+ os.path.join("cat", "first", "post_2000-04-14_blah.html"),
+ os.path.join("cat", "first", "post_2000-04-09_blah.html"),
+ os.path.join("cat", "first", "post_2000-04-04_blah.html"),
+ os.path.join("cat", "first", "post_2000-03-18_blah.html"),
+ os.path.join("cat", "first", "post_2000-03-13_blah.html"),
+ os.path.join("cat", "first", "post_2000-03-08_blah.html"),
+ os.path.join("cat", "first", "post_2000-03-03_blah.html"),
+ os.path.join("cat", "first", "post_2000-02-17_blah.html"),
+ os.path.join("cat", "first", "post_2000-02-12_blah.html"),
+ os.path.join("cat", "first", "post_2000-02-07_blah.html"),
+ os.path.join("cat", "first", "post_2000-02-02_blah.html"),
+ os.path.join("cat", "first", "post_2000-01-21_blah.html"),
+ os.path.join("cat", "first", "post_2000-01-16_blah.html"),
+ os.path.join("cat", "first", "post_2000-01-11_blah.html"),
+ os.path.join("cat", "first", "post_2000-01-06_blah.html"),
+ os.path.join("cat", "first", "post_2000-01-01_blah.html"),
+ os.path.join("cat", "second", "2000-05.html"),
+ os.path.join("cat", "second", "2000-04.html"),
+ os.path.join("cat", "second", "2000-03.html"),
+ os.path.join("cat", "second", "2000-02.html"),
+ os.path.join("cat", "second", "2000-01.html"),
+ os.path.join("cat", "second", "index.html"),
+ os.path.join("cat", "second", "atom.xml"),
+ os.path.join("cat", "second", "post_2000-05-20_blah.html"),
+ os.path.join("cat", "second", "post_2000-05-15_blah.html"),
+ os.path.join("cat", "second", "post_2000-05-10_blah.html"),
+ os.path.join("cat", "second", "post_2000-05-05_blah.html"),
+ os.path.join("cat", "second", "post_2000-04-19_blah.html"),
+ os.path.join("cat", "second", "post_2000-04-14_blah.html"),
+ os.path.join("cat", "second", "post_2000-04-09_blah.html"),
+ os.path.join("cat", "second", "post_2000-04-04_blah.html"),
+ os.path.join("cat", "second", "post_2000-03-18_blah.html"),
+ os.path.join("cat", "second", "post_2000-03-13_blah.html"),
+ os.path.join("cat", "second", "post_2000-03-08_blah.html"),
+ os.path.join("cat", "second", "post_2000-03-03_blah.html"),
+ os.path.join("cat", "second", "post_2000-02-17_blah.html"),
+ os.path.join("cat", "second", "post_2000-02-12_blah.html"),
+ os.path.join("cat", "second", "post_2000-02-07_blah.html"),
+ os.path.join("cat", "second", "post_2000-02-02_blah.html"),
+ os.path.join("cat", "second", "post_2000-01-21_blah.html"),
+ os.path.join("cat", "second", "post_2000-01-16_blah.html"),
+ os.path.join("cat", "second", "post_2000-01-11_blah.html"),
+ os.path.join("cat", "second", "post_2000-01-06_blah.html"),
+ os.path.join("cat", "second", "post_2000-01-01_blah.html"),
+ ],
+ m.GetWriteFileData(m._LEAFNAME))
+
+ def testGeneratePages_3Cats(self):
+ """
+ More categories: 4 main pages but each category has only 2 pages
+ """
+ m = MockSiteDefault(self, self.Log(), False, True,
self.sis).MakeDestDirs()
+
+ items = []
+ cats = [ "first", "second", "three" ]
+ for x in xrange(0, DEFAULT_ITEMS_PER_PAGE * 3 + 3):
+ # x % 3 => we'll generate 3 month pages and we have 3
categories
+ # so each category ends up in the same month.
+ si = SiteItem(source_item=None,
+ date=datetime(2000, 1 + (x % 3), 1 + (x % 28),
x % 24, x % 60, x % 60),
+ title="blah",
+ permalink="item",
+ content_gen=lambda t, x: "content",
+ categories=[ cats[x % 3] ])
+ items.append(si)
+
+ m.GeneratePages(cats, items)
+ self.assertListEquals(
+ [ "2000-03.html", "2000-02.html", "2000-01.html",
+ "index.html", "atom.xml",
+ os.path.join("cat", "first", "2000-01.html"),
+ os.path.join("cat", "first", "index.html"),
+ os.path.join("cat", "first", "atom.xml"),
+ os.path.join("cat", "first", "post_2000-01-28_blah.html"),
+ os.path.join("cat", "first", "post_2000-01-27_blah.html"),
+ os.path.join("cat", "first", "post_2000-01-25_blah.html"),
+ os.path.join("cat", "first", "post_2000-01-24_blah.html"),
+ os.path.join("cat", "first", "post_2000-01-22_blah.html"),
+ os.path.join("cat", "first", "post_2000-01-21_blah.html"),
+ os.path.join("cat", "first", "post_2000-01-19_blah.html"),
+ os.path.join("cat", "first", "post_2000-01-18_blah.html"),
+ os.path.join("cat", "first", "post_2000-01-16_blah.html"),
+ os.path.join("cat", "first", "post_2000-01-15_blah.html"),
+ os.path.join("cat", "first", "post_2000-01-13_blah.html"),
+ os.path.join("cat", "first", "post_2000-01-12_blah.html"),
+ os.path.join("cat", "first", "post_2000-01-10_blah.html"),
+ os.path.join("cat", "first", "post_2000-01-09_blah.html"),
+ os.path.join("cat", "first", "post_2000-01-07_blah.html"),
+ os.path.join("cat", "first", "post_2000-01-06_blah.html"),
+ os.path.join("cat", "first", "post_2000-01-05_blah.html"),
+ os.path.join("cat", "first", "post_2000-01-04_blah.html"),
+ os.path.join("cat", "first", "post_2000-01-03_blah.html"),
+ os.path.join("cat", "first", "post_2000-01-02_blah.html"),
+ os.path.join("cat", "first", "post_2000-01-01_blah.html"),
+ os.path.join("cat", "second", "2000-02.html"),
+ os.path.join("cat", "second", "index.html"),
+ os.path.join("cat", "second", "atom.xml"),
+ os.path.join("cat", "second", "post_2000-02-28_blah.html"),
+ os.path.join("cat", "second", "post_2000-02-26_blah.html"),
+ os.path.join("cat", "second", "post_2000-02-25_blah.html"),
+ os.path.join("cat", "second", "post_2000-02-23_blah.html"),
+ os.path.join("cat", "second", "post_2000-02-22_blah.html"),
+ os.path.join("cat", "second", "post_2000-02-20_blah.html"),
+ os.path.join("cat", "second", "post_2000-02-19_blah.html"),
+ os.path.join("cat", "second", "post_2000-02-17_blah.html"),
+ os.path.join("cat", "second", "post_2000-02-16_blah.html"),
+ os.path.join("cat", "second", "post_2000-02-14_blah.html"),
+ os.path.join("cat", "second", "post_2000-02-13_blah.html"),
+ os.path.join("cat", "second", "post_2000-02-11_blah.html"),
+ os.path.join("cat", "second", "post_2000-02-10_blah.html"),
+ os.path.join("cat", "second", "post_2000-02-08_blah.html"),
+ os.path.join("cat", "second", "post_2000-02-07_blah.html"),
+ os.path.join("cat", "second", "post_2000-02-06_blah.html"),
+ os.path.join("cat", "second", "post_2000-02-05_blah.html"),
+ os.path.join("cat", "second", "post_2000-02-04_blah.html"),
+ os.path.join("cat", "second", "post_2000-02-03_blah.html"),
+ os.path.join("cat", "second", "post_2000-02-02_blah.html"),
+ os.path.join("cat", "second", "post_2000-02-01_blah.html"),
+ os.path.join("cat", "three", "2000-03.html"),
+ os.path.join("cat", "three", "index.html"),
+ os.path.join("cat", "three", "atom.xml"),
+ os.path.join("cat", "three", "post_2000-03-27_blah.html"),
+ os.path.join("cat", "three", "post_2000-03-26_blah.html"),
+ os.path.join("cat", "three", "post_2000-03-24_blah.html"),
+ os.path.join("cat", "three", "post_2000-03-23_blah.html"),
+ os.path.join("cat", "three", "post_2000-03-21_blah.html"),
+ os.path.join("cat", "three", "post_2000-03-20_blah.html"),
+ os.path.join("cat", "three", "post_2000-03-18_blah.html"),
+ os.path.join("cat", "three", "post_2000-03-17_blah.html"),
+ os.path.join("cat", "three", "post_2000-03-15_blah.html"),
+ os.path.join("cat", "three", "post_2000-03-14_blah.html"),
+ os.path.join("cat", "three", "post_2000-03-12_blah.html"),
+ os.path.join("cat", "three", "post_2000-03-11_blah.html"),
+ os.path.join("cat", "three", "post_2000-03-09_blah.html"),
+ os.path.join("cat", "three", "post_2000-03-08_blah.html"),
+ os.path.join("cat", "three", "post_2000-03-07_blah.html"),
+ os.path.join("cat", "three", "post_2000-03-06_blah.html"),
+ os.path.join("cat", "three", "post_2000-03-05_blah.html"),
+ os.path.join("cat", "three", "post_2000-03-04_blah.html"),
+ os.path.join("cat", "three", "post_2000-03-03_blah.html"),
+ os.path.join("cat", "three", "post_2000-03-02_blah.html"),
+ os.path.join("cat", "three", "post_2000-03-01_blah.html"),
+ ],
+ m.GetWriteFileData(m._LEAFNAME))
+
+ def testGeneratePages_UseCurrMonth(self):
+ """
+ Test that index contains all items from the first month when
+ use_curr_month_in_index is True, even if it's more than
+ num_item_page.
+ """
+ self.sis.use_curr_month_in_index = True
+ self.sis.num_item_page = 2
+ m = MockSiteDefault(self, self.Log(), False, True,
self.sis).MakeDestDirs()
+
+ items = []
+ cats = []
+ # generate 2 months with 5 items per month each
+ for mo in xrange(0, 2):
+ for d in xrange(0, 5):
+ si = SiteItem(source_item=None,
+ date=datetime(2000, 1 + mo, 1 + d, 0, 0, 0),
+ title="blah",
+ permalink="item",
+ content_gen=lambda t, x: "content",
+ categories=cats)
+ items.append(si)
+
+ m.GeneratePages(cats, items)
+
+ self.assertListEquals(
+ [ "2000-02.html", "2000-01.html",
+ "index.html", "atom.xml",
+ "post_2000-02-05_blah.html",
+ "post_2000-02-04_blah.html",
+ "post_2000-02-03_blah.html",
+ "post_2000-02-02_blah.html",
+ "post_2000-02-01_blah.html",
+ "post_2000-01-05_blah.html",
+ "post_2000-01-04_blah.html",
+ "post_2000-01-03_blah.html",
+ "post_2000-01-02_blah.html",
+ "post_2000-01-01_blah.html"
+ ],
+ m.GetWriteFileData(m._LEAFNAME))
+
+ self.assertTrue(SiteDefault._TEMPLATE_HTML_INDEX in
m._fill_template_params)
+ self.assertTrue(1,
len(m._fill_template_params[SiteDefault._TEMPLATE_HTML_INDEX]))
+ self.assertTrue("entries" in
m._fill_template_params[SiteDefault._TEMPLATE_HTML_INDEX][0])
+ self.assertListEquals(
+ [ datetime(2000, 2, 5, 0, 0),
+ datetime(2000, 2, 4, 0, 0),
+ datetime(2000, 2, 3, 0, 0),
+ datetime(2000, 2, 2, 0, 0),
+ datetime(2000, 2, 1, 0, 0) ],
+ [ j.date
+ for j in
m._fill_template_params[SiteDefault._TEMPLATE_HTML_INDEX][0]["entries"] ])
+
+ # Now if we set num_item_page to 7, we'll get the 5 items of the
last month
+ # plus 2 from the next month
+
+ self.sis.num_item_page = 7
+ m = MockSiteDefault(self, self.Log(), False, True,
self.sis).MakeDestDirs()
+
+ m.GeneratePages(cats, items)
+
+ self.assertListEquals(
+ [ "2000-02.html", "2000-01.html",
+ "index.html", "atom.xml",
+ "post_2000-02-05_blah.html",
+ "post_2000-02-04_blah.html",
+ "post_2000-02-03_blah.html",
+ "post_2000-02-02_blah.html",
+ "post_2000-02-01_blah.html",
+ "post_2000-01-05_blah.html",
+ "post_2000-01-04_blah.html",
+ "post_2000-01-03_blah.html",
+ "post_2000-01-02_blah.html",
+ "post_2000-01-01_blah.html"
+ ],
+ m.GetWriteFileData(m._LEAFNAME))
+
+ self.assertTrue(SiteDefault._TEMPLATE_HTML_INDEX in
m._fill_template_params)
+ self.assertTrue(1,
len(m._fill_template_params[SiteDefault._TEMPLATE_HTML_INDEX]))
+ self.assertTrue("entries" in
m._fill_template_params[SiteDefault._TEMPLATE_HTML_INDEX][0])
+ self.assertListEquals(
+ [ datetime(2000, 2, 5, 0, 0),
+ datetime(2000, 2, 4, 0, 0),
+ datetime(2000, 2, 3, 0, 0),
+ datetime(2000, 2, 2, 0, 0),
+ datetime(2000, 2, 1, 0, 0),
+ datetime(2000, 1, 5, 0, 0),
+ datetime(2000, 1, 4, 0, 0) ],
+ [ j.date
+ for j in
m._fill_template_params[SiteDefault._TEMPLATE_HTML_INDEX][0]["entries"] ])
+
+ def testGeneratePages_DontUseCurrMonth(self):
+ """
+ Test that index contains N max items independantly of the first
month when
+ use_curr_month_in_index is False.
+ """
+ self.sis.use_curr_month_in_index = False
+ self.sis.num_item_page = 2
+ m = MockSiteDefault(self, self.Log(), False, True,
self.sis).MakeDestDirs()
+
+ items = []
+ cats = []
+ # generate 2 months with 5 items per month each
+ for mo in xrange(0, 2):
+ for d in xrange(0, 5):
+ si = SiteItem(source_item=None,
+ date=datetime(2000, 1 + mo, 1 + d, 0, 0, 0),
+ title="blah",
+ permalink="item",
+ content_gen=lambda t, x: "content",
+ categories=cats)
+ items.append(si)
+
+ m.GeneratePages(cats, items)
+
+ self.assertListEquals(
+ [ "2000-02.html", "2000-01.html",
+ "index.html", "atom.xml",
+ "post_2000-02-05_blah.html",
+ "post_2000-02-04_blah.html",
+ "post_2000-02-03_blah.html",
+ "post_2000-02-02_blah.html",
+ "post_2000-02-01_blah.html",
+ "post_2000-01-05_blah.html",
+ "post_2000-01-04_blah.html",
+ "post_2000-01-03_blah.html",
+ "post_2000-01-02_blah.html",
+ "post_2000-01-01_blah.html"
+ ],
+ m.GetWriteFileData(m._LEAFNAME))
+
+ self.assertTrue(SiteDefault._TEMPLATE_HTML_INDEX in
m._fill_template_params)
+ self.assertTrue(1,
len(m._fill_template_params[SiteDefault._TEMPLATE_HTML_INDEX]))
+ self.assertTrue("entries" in
m._fill_template_params[SiteDefault._TEMPLATE_HTML_INDEX][0])
+ self.assertListEquals(
+ [ datetime(2000, 2, 5, 0, 0),
+ datetime(2000, 2, 4, 0, 0) ],
+ [ j.date
+ for j in
m._fill_template_params[SiteDefault._TEMPLATE_HTML_INDEX][0]["entries"] ])
+
+ # Now if we set num_item_page to 7, we'll get the 5 items of the
last month
+ # plus 2 from the next month
+
+ self.sis.num_item_page = 7
+ m = MockSiteDefault(self, self.Log(), False, True,
self.sis).MakeDestDirs()
+
+ m.GeneratePages(cats, items)
+
+ self.assertListEquals(
+ [ "2000-02.html", "2000-01.html",
+ "index.html", "atom.xml",
+ "post_2000-02-05_blah.html",
+ "post_2000-02-04_blah.html",
+ "post_2000-02-03_blah.html",
+ "post_2000-02-02_blah.html",
+ "post_2000-02-01_blah.html",
+ "post_2000-01-05_blah.html",
+ "post_2000-01-04_blah.html",
+ "post_2000-01-03_blah.html",
+ "post_2000-01-02_blah.html",
+ "post_2000-01-01_blah.html"
+ ],
+ m.GetWriteFileData(m._LEAFNAME))
+
+ self.assertTrue(SiteDefault._TEMPLATE_HTML_INDEX in
m._fill_template_params)
+ self.assertTrue(1,
len(m._fill_template_params[SiteDefault._TEMPLATE_HTML_INDEX]))
+ self.assertTrue("entries" in
m._fill_template_params[SiteDefault._TEMPLATE_HTML_INDEX][0])
+ self.assertListEquals(
+ [ datetime(2000, 2, 5, 0, 0),
+ datetime(2000, 2, 4, 0, 0),
+ datetime(2000, 2, 3, 0, 0),
+ datetime(2000, 2, 2, 0, 0),
+ datetime(2000, 2, 1, 0, 0),
+ datetime(2000, 1, 5, 0, 0),
+ datetime(2000, 1, 4, 0, 0) ],
***The diff for this file has been truncated for email.***
=======================================
--- /dev/null
+++ /trunk/rig3serv/src/tests/test_rig3_pipeline.py Tue Sep 7 00:27:42 2010
@@ -0,0 +1,150 @@
+#!/usr/bin/python
+#-----------------------------------------------------------------------------|
+"""
+Unit tests for Rig3 site generation.
+
+This is not a live test. It simulates the various steps of the "pipeline"
+from rig3, manually. It's more designed to be a concrete example of what's
+going on and depends a lot on implementation details of Rig3 and SiteBase
+to kind of mirror what's going on behind the scene.
+
+Part of Rig3.
+Copyright (C) 2007-2009 ralfoide gmail com
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <
http://www.gnu.org/licenses/>.
+
+"""
+__author__ = "ralfoide gmail com"
+
+import types
+import os
+
+from tests.rig_test_case import RigTestCase
+from rig3 import Rig3
+from rig.site_base import SiteBase
+from rig.site import CreateSite
+
+_DEST_DIR = "test_dest" # in testdata dir
+
+#------------------------
+class RenderPipeline(RigTestCase):
+
+ def setUp(self):
+ self._pwd = os.getcwd()
+ self._testdata = self.getTestDataPath()
+ # all paths are relative to the testdata dir
+ os.chdir(self._testdata)
+ # cleanup output and make sure it's not there anymore
+ self.RemoveDir(_DEST_DIR)
+ self.assertFalse(os.path.exists(_DEST_DIR))
+ os.mkdir(_DEST_DIR)
+ self.assertTrue(os.path.exists(_DEST_DIR))
+
+ def tearDown(self):
+ os.chdir(self._pwd)
+
+ def testRig3Pipeline(self):
+ """
+ Tests the "outer" rig3 pipeline, that is processing an RC config
file,
+ processing the sites and invoking the process of the source items,
+ categories and page generation.
+
+ This looks at making sure the proper methods are invoked as many
times
+ as expected rather than actually looking at the generated data.
+ """
+
+ # First parse the args
+ test = self
+ r = Rig3()
+ t = self._testdata
+ rc = os.path.join(t, "z_last_render_testdata.rc")
+ args = [ "rig3", "-c", rc, "--force" ]
+ r.ParseArgs(args)
+
+ def PatchProcessSites(self):
+ # ProcessSites() will now create the site and process it.
+ # Let's do that manually here
+ s = r._sites_settings
+
+ test.assertListEquals(
+ [ "test_default", "test_magic" ],
+ s.Sites())
+
+ # We'll test only the first site
+ site_id = "test_default"
+ sis = s.GetSiteSettings(site_id)
+ site = CreateSite(r._log,
+ r._dry_run,
+ r._force,
+ sis)
+
+ # the testdata.rc has 2 sources lines with 3 sources types
+ # defined on each line (dir, file and blog)
+ test.assertEquals(6, len(sis.source_list))
+
+ # site.Process() should invoke _ProcessSourceItems()
+ # (for each each source list) and then _CollectCategories()
+ # once, and then finally GeneratePages()... lets patch them to
+ # inject counters.
+ site.old_ProcessSourceItems = site._ProcessSourceItems
+ site.old_CollectCategories = site._CollectCategories
+ site.old_GeneratePages = site.GeneratePages
+
+ site.count_ProcessSourceItems = 0
+ site.count_CollectCategories = 0
+ site.count_GeneratePages = 0
+
+ def Patch_ProcessSourceItems(self, source, site_items, dups):
+ self.count_ProcessSourceItems += 1
+ return self.old_ProcessSourceItems(source, site_items,
dups)
+
+ def Patch_CollectCategories(self, site_items):
+ self.count_CollectCategories += 1
+ return self.old_CollectCategories(site_items)
+
+ def Patch_GeneratePages(self, categories, site_items):
+ self.count_GeneratePages += 1
+ return self.old_GeneratePages(categories, site_items)
+
+ site._ProcessSourceItems =
types.MethodType(Patch_ProcessSourceItems, site, SiteBase)
+ site._CollectCategories =
types.MethodType(Patch_CollectCategories, site, SiteBase)
+ site.GeneratePages = types.MethodType(Patch_GeneratePages,
site, SiteBase)
+ site.Process()
+
+ test.assertEquals(6, site.count_ProcessSourceItems)
+ test.assertEquals(1, site.count_CollectCategories)
+ test.assertEquals(1, site.count_GeneratePages)
+
+ site.Dispose()
+
+ # Rig3.Run() loads site settings then invokes ProcessSites().
+ # we use monkey patching to invoke PatchProcessSites() from Run()
+ # instead.
+ r.ProcessSites = types.MethodType(PatchProcessSites, r, Rig3)
+ r.Run()
+
+ # Finally close the Rig3 instance
+ r.Close()
+
+
+
+#------------------------
+# Local Variables:
+# mode: python
+# tab-width: 4
+# py-continuation-offset: 4
+# py-indent-offset: 4
+# sentence-end-double-space: nil
+# fill-column: 79
+# End:
=======================================
--- /trunk/rig3serv/src/tests/site/test_site_defaut.py Sun Aug 29 21:19:47
2010
+++ /dev/null
@@ -1,1043 +0,0 @@
-#!/usr/bin/python
-#-----------------------------------------------------------------------------|
-"""
-Unit tests for Site
-
-Part of Rig3.
-Copyright (C) 2007-2009 ralfoide gmail com
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see <
http://www.gnu.org/licenses/>.
-
-"""
-__author__ = "ralfoide at gmail com"
-
-import os
-from datetime import datetime
-
-from tests.rig_test_case import RigTestCase
-
-from rig.site.site_default import SiteDefault, ContentEntry
-from rig.site_base import DEFAULT_THEME, SiteItem
-from rig.sites_settings import SiteSettings
-from rig.parser.dir_parser import DirParser, RelDir
-from rig.source_reader import SourceDirReader
-from rig.source_item import SourceDir, SourceSettings
-from rig.sites_settings import SiteSettings, SitesSettings
-from rig.sites_settings import DEFAULT_ITEMS_PER_PAGE
-
-#------------------------
-class MockSiteDefault(SiteDefault):
- """
- Behaves like a SiteDefault() but overrides the base template directory
location
- to use testdata/templates instead.
-
- Also traps the last _Filltemplate parameters.
- """
- def __init__(self, test_case, log, dry_run, force, site_settings):
- self._test_case = test_case
- self._fill_template_params = {}
- self._write_file_params = []
- super(MockSiteDefault, self).__init__(log, dry_run, force,
site_settings)
-
- # override the Cache.Clear method by ours
- self._cache_clear_count = 0
- self._org_cache_clear = self._cache.Clear
- setattr(self._cache, "Clear", self._CacheClearOverride)
-
- def _TemplateDir(self):
- """"
- Uses testdata/templates/ instead of templates/
- """
- return os.path.join(self._test_case.getTestDataPath(), "templates")
-
- def _FillTemplate(self, template, **keywords):
- """
- Keeps a copy of the _FillTemplate parameters and then calls the
original.
- Trapped parameters are available in
- self._fill_template_params[template] => list(keyword dict.)
- """
- if not template in self._fill_template_params:
- self._fill_template_params[template] = []
- self._fill_template_params[template].append(dict(keywords))
- return super(MockSiteDefault, self)._FillTemplate(template,
**keywords)
-
- def _WriteFile(self, data, dest_dir, leafname):
- """
- Keeps a copy of all parameters given to _WriteFile.
- This implementation does NOT call the base class so that nothing
gets
- written anywhere.
-
- Trapped parameters are available in
- self._write_file_params => list(data, dest_dir, leafname)
- See GetWriteFileData(n, m) below.
- """
- self._write_file_params.append((data, dest_dir, leafname))
-
- _DATA = 0
- _DEST_DIR = 1
- _LEAFNAME = 2
-
- def GetWriteFileData(self, tuple_index):
- """
- Returns a *copy* of the self._write_file_params list
- with items rearranged.
- - tuple_index: _DATA, _DEST_DIR or _LEAFNAME, the value to return.
-
- This basically remaps (data, dest_dir, leafname) to whatever you
like
- to test, e.g. list[ value: leafname ] or list[ value: data ].
- """
- return [ p[tuple_index] for p in self._write_file_params ]
-
- def _CacheClearOverride(self):
- """
- Override self._cache.Clear to count the number of calls then
- call the original implementation.
- """
- self._cache_clear_count += 1
- self._org_cache_clear()
-
- def CacheClearCount(self, reset):
- """
- Returns the number of cache clear done so far.
- If reset is true, resets the count to 0.
- """
- c = self._cache_clear_count
- if reset:
- self._cache_clear_count = 0
- return c
-
-#------------------------
-class SiteDefaultTest(RigTestCase):
-
- def setUp(self):
- self._tempdir = self.MakeTempDir()
- self._cachedir = self.MakeTempDir()
- self.sis, self.sos = self._computeSisSos()
-
- self.keywords = self.sis.AsDict()
- self.keywords.update(self.sos.AsDict())
-
- def _computeSisSos(self):
- source = SourceDirReader(self.Log(),
- site_settings=None,
- source_settings=None,
-
path=os.path.join(self.getTestDataPath(), "album"))
- sis = SiteSettings(public_name="Test Album",
- source_list=[ source ],
- dest_dir=self._tempdir,
- cache_dir=self._cachedir,
- theme=DEFAULT_THEME,
- base_url="
http://www.example.com",
- encoding="iso-8859-1")
- sos =
SourceSettings(rig_base="
http://example.com/photos/index.php")
- return sis, sos
-
- def tearDown(self):
- self.RemoveDir(self._tempdir)
- self.RemoveDir(self._cachedir)
-
- def testSimpleFileName(self):
- m = MockSiteDefault(self, self.Log(), False, True, self.sis)
- self.assertEquals("filename_txt",
m._SimpleFileName("filename.txt"))
- self.assertEquals("abc-de-f-g-h", m._SimpleFileName("abc---de
f-g h"))
- self.assertEquals("abc-de-f-g-h",
m._SimpleFileName("abc///de\\\\f/g\\h"))
- self.assertEquals("a-ab_12_txt",
m._SimpleFileName("a//\\ab!@#$12%^&@&*()_+.<>,txt"))
- self.assertEquals("long_3e3a06df",
m._SimpleFileName("long_filename.txt", maxlen=13))
- self.assertEquals("someverylon_7eea09fa",
m._SimpleFileName("someverylongfilename.txt", maxlen=20))
- self.assertEquals("the-unit-test-is-the-proof",
m._SimpleFileName("the unit test is the proof", 50))
- self.assertEquals("the-unit-test-is_81bc09a5",
m._SimpleFileName("the unit test is the proof", 25))
-
- # the default for mangled_name_len is 50
- self.assertEquals("the-unit-test-is-the-proof",
m._SimpleFileName("the unit test is the proof",
-
self.sis.mangled_name_len))
- self.sis.mangled_name_len = 25
- self.assertEquals("the-unit-test-is_81bc09a5",
m._SimpleFileName("the unit test is the proof"))
- # 0 deactivates the mangling
- self.sis.mangled_name_len = 0
- self.assertEquals("the-unit-test-is-the-proof",
m._SimpleFileName("the unit test is the proof"))
-
- def testFillTemplate(self):
- m = MockSiteDefault(self, self.Log(), False, True, self.sis)
-
- keywords = dict(self.keywords)
- keywords["title"] = "MyTitle"
- keywords["entries"] = [
- ContentEntry("content entry1", "entry1", None, "url1"),
- ContentEntry("content entry2", "entry2", None, "url2") ]
- keywords["curr_category"] = ""
- keywords["all_categories"] = []
- keywords["toc_categories"] = []
- keywords["last_gen_ts"] = datetime(2007, 11, 12, 14, 15, 16)
- keywords["last_content_ts"] = datetime(2001, 3, 14, 15, 9, 2)
- keywords["rig3_version"] = "3.1.4.15"
-
- html = m._FillTemplate(SiteDefault._TEMPLATE_HTML_INDEX,
**keywords)
- self.assertIsInstance(str, html)
- self.assertTrue(SiteDefault._TEMPLATE_HTML_INDEX in
m._fill_template_params)
- self.assertTrue(1,
len(m._fill_template_params[SiteDefault._TEMPLATE_HTML_INDEX]))
- self.assertDictEquals(keywords,
m._fill_template_params[SiteDefault._TEMPLATE_HTML_INDEX][0])
- self.assertListEquals([], m.GetWriteFileData(m._LEAFNAME))
- self.assertHtmlEquals(
- r"""<html lang="en-US">
- <head>
- <meta http-equiv="Content-Type" content="text/html;
charset=UTF-8"/>
- <link rel="stylesheet" type="text/css"
href="media/style.css" />
- <title>Test Album - MyTitle</title>
- </head>
- <body>
- (placeholder for image header)<br/>
- blog name is Test Album<br/>
- categories are All<br/>
- content entry1
- content entry2
- <p>
- Most recent entry: 2001-03-14 15:09:02 --
- Generated on 2007-11-12 14:15:16 by <a
href="
http://code.google.com/p/rig3/">Rig3 3.1.4.15</a>
- </body>
- </html>""",
- html)
-
- keywords = dict(self.keywords)
- keywords["title"] = "MyTitle"
- keywords["sections"] = { "en": "Main <b>Text Content</b> as HTML",
- "images": "<a href='page_url'><img
src='image_url'/></a>" }
- html = m._FillTemplate(SiteDefault._TEMPLATE_HTML_ENTRY,
**keywords)
- self.assertIsInstance(str, html)
- self.assertTrue(SiteDefault._TEMPLATE_HTML_ENTRY in
m._fill_template_params)
- self.assertTrue(1,
len(m._fill_template_params[SiteDefault._TEMPLATE_HTML_ENTRY]))
- self.assertDictEquals(keywords,
m._fill_template_params[SiteDefault._TEMPLATE_HTML_ENTRY][0])
- self.assertListEquals([], m.GetWriteFileData(m._LEAFNAME))
- self.assertHtmlEquals(
- r"""<div class="entry">
- <h2>MyTitle</h2>
- Main <b>Text Content</b> as HTML
- <br/>
- <a href='page_url'><img src='image_url'/></a>
- <br/>
- </div>
- """,
- html)
-
- def testDateAndTitleFromTitle(self):
- m = MockSiteDefault(self, self.Log(), False, True, self.sis)
-
- self.assertEquals((None, "27"),
m._DateAndTitleFromTitle("27"))
- self.assertEquals((None, "2007"),
m._DateAndTitleFromTitle("2007"))
- self.assertEquals((None, "2007-1"),
m._DateAndTitleFromTitle("2007-1"))
-
- # lack of day is the same as using day=01
- self.assertEquals((datetime(2007, 10, 1), ""),
- m._DateAndTitleFromTitle("2007-10"))
-
- # here we don't interpret "YYYYMM[-]2" as a day because it lacks 2
digits,
- # instead it gets interpreted as the title.
- self.assertEquals((datetime(2007, 10, 1), "2"),
- m._DateAndTitleFromTitle("2007102"))
- self.assertEquals((datetime(2007, 10, 1), "2"),
- m._DateAndTitleFromTitle("2007-10-2"))
-
- self.assertEquals((datetime(2007, 10, 27), ""),
- m._DateAndTitleFromTitle("20071027"))
- self.assertEquals((datetime(2007, 10, 27), "rest"),
- m._DateAndTitleFromTitle("2007-10-27 rest"))
- self.assertEquals((datetime(2007, 10, 27), "rest of the line.."),
- m._DateAndTitleFromTitle("2007/10/27_rest of the
line.."))
- self.assertEquals((datetime(2007, 10, 27), "whitespace"),
- m._DateAndTitleFromTitle("2007-10/27
whitespace "))
- self.assertEquals((datetime(2007, 10, 27, 12, 13, 14), ""),
m._DateAndTitleFromTitle("20071027121314"))
- self.assertEquals((datetime(2007, 10, 27, 12, 13, 14), ""),
m._DateAndTitleFromTitle("2007-10-27-12-13-14"))
- self.assertEquals((datetime(2007, 10, 27, 12, 13, 14), ""),
m._DateAndTitleFromTitle("2007-10-27 12-13-14"))
- self.assertEquals((datetime(2007, 10, 27, 12, 13, 14), ""),
m._DateAndTitleFromTitle("2007/10/27 12:13:14"))
- self.assertEquals((datetime(2007, 10, 27, 12, 13, 14), ""),
m._DateAndTitleFromTitle("2007-10/27,12/13/14"))
-
- self.assertEquals((None, "white space"),
m._DateAndTitleFromTitle("_white space_"))
- self.assertEquals((None, "white space"),
m._DateAndTitleFromTitle("_white_space_"))
- self.assertEquals((None, "white space"),
m._DateAndTitleFromTitle(" ___\twhite_\r\n\f_ __space_ \r\t\n\f___ "))
-
-
- def testDateAndTitleFromTitle_ErrorCases(self):
- m = MockSiteDefault(self, self.Log(), False, True, self.sis)
-
- # Hour is invalid: 44>23... log warning and ignore hour in this
case
- self.assertEquals((datetime(2007, 10, 27), ""),
- m._DateAndTitleFromTitle("20071027-4400"))
-
- # Day must be in 1..31
- self.assertRaises(ValueError, m._DateAndTitleFromTitle, "20071034")
-
- # Month must be in 1..12
- self.assertRaises(ValueError, m._DateAndTitleFromTitle, "20071527")
-
- # Year must be in range 1..9999
- self.assertRaises(ValueError, m._DateAndTitleFromTitle, "00001027")
- self.assertEquals((datetime(1, 10, 27), ""),
- m._DateAndTitleFromTitle("00011027"))
- self.assertEquals((datetime(9999, 10, 27), ""),
- m._DateAndTitleFromTitle("99991027"))
-
- def testGenerateItems_Izu(self):
- m = MockSiteDefault(self, self.Log(), False, True,
self.sis).MakeDestDirs()
- source_dir = os.path.join(self.getTestDataPath(), "album", "blog1")
- item = m.GenerateItem(SourceDir(datetime.today(),
-
RelDir(source_dir, "2007-10-07_Folder 1"),
- [ "index.izu" ],
- self.sos))
- self.assertNotEquals(None, item)
- self.assertEquals(datetime(2007, 10, 07), item.date)
- self.assertHtmlMatches(r'<div class="entry">.+</div>',
item.content_gen(SiteDefault._TEMPLATE_HTML_ENTRY))
- self.assertListEquals([ "foo", "bar", "other" ], item.categories,
sort=True)
-
- def testGenerateItems_Html(self):
- m = MockSiteDefault(self, self.Log(), False, True,
self.sis).MakeDestDirs()
- source_dir = os.path.join(self.getTestDataPath(), "album", "blog2")
- item = m.GenerateItem(SourceDir(datetime.today(),
-
RelDir(source_dir, "2006-05_Movies"),
- [ "index.html" ],
- self.sos))
- self.assertNotEquals(None, item)
- self.assertEquals(datetime(2006, 5, 28, 17, 18, 5), item.date)
- self.assertHtmlMatches(r'<div class="entry">.+<!-- \[izu:.+\]
-->blog 2 <table.+>.+</table>.+</div>',
-
item.content_gen(SiteDefault._TEMPLATE_HTML_ENTRY))
- self.assertListEquals([ "videos" ], item.categories, sort=True)
-
- def testImgPattern(self):
- m = MockSiteDefault(self, self.Log(), False, True,
self.sis).MakeDestDirs()
- self.assertEquals(None, m._IMG_PATTERN.match("myimage.jpg"))
- self.assertEquals(None, m._IMG_PATTERN.match("PICT1200.jpg"))
- self.assertEquals(None, m._IMG_PATTERN.match("R12345-Some
Name.bmp"))
- self.assertEquals(None, m._IMG_PATTERN.match("R12345-Some
Name.gif"))
- self.assertDictEquals({ "index": "1000",
- "rating": "_",
- "name": " Old Index ",
- "ext": ".jpg" },
- m._IMG_PATTERN.match("1000_ Old
Index .jpg").groupdict())
- self.assertDictEquals({ "index": "R12345",
- "rating": "_",
- "name": "Some Name",
- "ext": ".jpg" },
- m._IMG_PATTERN.match("R12345_Some
Name.jpg").groupdict())
- self.assertDictEquals({ "index": "X12345",
- "rating": "-",
- "name": "Some Movie",
- "ext": ".original.mov" },
- m._IMG_PATTERN.match("X12345-Some
Movie.original.mov").groupdict())
- self.assertDictEquals({ "index": "Y31415",
- "rating": "+",
- "name": "Web Version",
- "ext": ".web.mov" },
- m._IMG_PATTERN.match("Y31415+Web
Version.web.mov").groupdict())
- self.assertDictEquals({ "index": "Z31415",
- "rating": ".",
- "name": "Web Version",
- "ext": ".web.wmv" },
- m._IMG_PATTERN.match("Z31415.Web
Version.web.wmv").groupdict())
-
- def testGetRigLink(self):
- m = MockSiteDefault(self, self.Log(), False, True, self.sis)
-
- expected = (
- '<a title="2007-11-08 Album Title" '
- 'href="
http://example.com/photos/index.php?album=My%20Albums/Year_2007/2007-11-08%20Album%20Title&img=Best%20of%202007.jpg">'
- '<img title="Best of 2007" alt="Best of 2007"
src="
http://example.com/photos/index.php?th=&album=My%20Albums/Year_2007/2007-11-08%20Album%20Title&img=Best%20of%202007.jpg&sz=400&q=75"/>'
- '</a>'
- )
-
- self.assertHtmlEquals(
- expected,
- m._GetRigLink(self.keywords,
- RelDir("base", "My Albums/Year_2007/2007-11-08
Album Title"),
- "Best of 2007.jpg",
- 400))
-
- expected = (
- '<a title="2007-11-08 Album Title" '
- 'href="
http://example.com/photos/index.php?album=My%20Albums/Year_2007/2007-11-08%20Album%20Title&img=Best%20of%202007.jpg">'
- '<img title="Best of 2007" alt="Best of 2007"
src="
http://example.com/photos/index.php?th=&album=My%20Albums/Year_2007/2007-11-08%20Album%20Title&img=Best%20of%202007.jpg&sz=-1&q=75"/>'
- '</a>'
- )
-
- self.assertHtmlEquals(
- expected,
- m._GetRigLink(self.keywords,
- RelDir("base", "My Albums/Year_2007/2007-11-08
Album Title"),
- "Best of 2007.jpg",
- -1))
-
- expected = (
- '<a title="2007-11-08 Album & Title" '
- 'href="
http://example.com/photos/index.php?album=My%20Albums/Year_2007/2007-11-08%20Album%20%26%20Title">'
- '2007-11-08 Album & Title</a>'
- )
-
- self.assertHtmlEquals(
- expected,
- m._GetRigLink(self.keywords,
- RelDir("base", "My Albums/Year_2007/2007-11-08
Album & Title"),
- None,
- -1))
-
- def testGenerateImages(self):
- m = MockSiteDefault(self, self.Log(), False, True, self.sis)
-
- keywords = self.keywords
-
- self.assertEquals(
- None,
- m._GenerateImages(RelDir("base", ""), [], keywords))
-
- self.assertEquals(
- None,
- m._GenerateImages(RelDir("base", ""), [ "index.izu",
- "index.html",
- "image.jpeg" ],
- keywords ))
-
- self.assertEquals(
- None,
- m._GenerateImages(RelDir("base", ""), [ "J1234_sound.mp3" ],
keywords))
-
- self.assertHtmlEquals(
- "See more images for " + m._GetRigLink(keywords,
RelDir("base", ""), None, -1),
- m._GenerateImages(RelDir("base", ""), [ "J1234.image.jpg" ],
keywords))
-
- self.assertHtmlEquals(
- '<table class="image-table"><tr><td>\n' +
m._GetRigLink(keywords, RelDir("base", ""), "J1234-image.jpg", 300)
+ '</td></tr></table>',
- m._GenerateImages(RelDir("base", ""), [ "J1234-image.jpg" ],
keywords))
-
- def testGenerateIndexPage(self):
- m = MockSiteDefault(self, self.Log(), False, True,
self.sis).MakeDestDirs()
-
- m._GenerateIndexPage("", "", [], [], [], [])
- params = m._fill_template_params
-
- for key in [ "rig_img_url",
- "rig_thumb_url",
- "source_list",
- "header_img_height",
- "tracking_code",
- "header_img_url",
- "rig_album_url",
- "img_gen_script",
- "entries",
- "last_content_ts",
- "rig_img_size",
- "month_pages",
- "rig3_version",
- "title",
- "rel_base_url",
- "base_url",
- "public_name",
- "theme",
- "all_categories",
- "dest_dir",
- "cat_filter",
- "toc_categories",
- "last_gen_ts" ]:
- self.assertTrue(key in
params[SiteDefault._TEMPLATE_HTML_INDEX][0],
- "Missing [%s] in %s" % (key, params))
-
- def testRigAlbumLink(self):
- m = MockSiteDefault(self, self.Log(), False, True,
self.sis).MakeDestDirs()
-
- keywords = self.keywords
- keywords.update(SourceSettings(rig_base=None).AsDict())
- self.assertEquals("", m._RigAlbumLink(keywords, "my album"))
-
-
keywords.update(SourceSettings(rig_base="
http://my.rig/index.php").AsDict())
- self.assertEquals("
http://my.rig/index.php?album=my%20album",
- m._RigAlbumLink(keywords, "my album"))
-
- def testRigImgLink(self):
- m = MockSiteDefault(self, self.Log(), False, True,
self.sis).MakeDestDirs()
-
- keywords = self.keywords
- keywords.update(SourceSettings(rig_base=None).AsDict())
- self.assertEquals("", m._RigImgLink(keywords, "my album", "my
image.jpg"))
-
-
keywords.update(SourceSettings(rig_base="
http://my.rig/index.php").AsDict())
-
self.assertEquals("
http://my.rig/index.php?album=my%20album&img=my%20image.jpg",
- m._RigImgLink(keywords, "my album", "my
image.jpg"))
-
- def testRigThumbLink(self):
- m = MockSiteDefault(self, self.Log(), False, True,
self.sis).MakeDestDirs()
-
- keywords = self.keywords
- keywords.update(SourceSettings(rig_base=None).AsDict())
- self.assertEquals("", m._RigThumbLink(keywords, "my album", "my
image.jpg", 640))
-
-
keywords.update(SourceSettings(rig_base="
http://my.rig/index.php").AsDict())
-
self.assertEquals("
http://my.rig/index.php?th=&album=my%20album&img=my%20image.jpg&sz=640&q=75",
- m._RigThumbLink(keywords, "my album", "my
image.jpg", 640))
-
- def testGeneratePages_0Empty(self):
- """
- Printing an empty list of items only generates an index page
- """
- m = MockSiteDefault(self, self.Log(), False, True,
self.sis).MakeDestDirs()
- self.assertListEquals([], m.GetWriteFileData(m._LEAFNAME))
-
- m.GeneratePages(categories=[], items=[])
- self.assertListEquals([ "index.html", "atom.xml" ],
m.GetWriteFileData(m._LEAFNAME))
-
- def testGeneratePages_0Cats(self):
- """
- Printing 3 times + 1 the number of items per page generates 4 pages
- """
- m = MockSiteDefault(self, self.Log(), False, True,
self.sis).MakeDestDirs()
-
- items = []
- cats = []
- for x in xrange(0, DEFAULT_ITEMS_PER_PAGE * 3 + 1):
- # x % 12 => we'll generate 12 month pages
- si = SiteItem(source_item=None,
- date=datetime(2000, 1 + (x % 12), 1 + (x % 28),
x % 24, x % 60, x % 60),
- title="blah",
- permalink="item",
- content_gen=lambda t, x: "content",
- categories=cats)
- items.append(si)
-
- m.GeneratePages(cats, items)
- self.assertListEquals(
- [ "2000-12.html", "2000-11.html", "2000-10.html", "2000-09.html",
- "2000-08.html", "2000-07.html", "2000-06.html", "2000-05.html",
- "2000-04.html", "2000-03.html", "2000-02.html", "2000-01.html",
- "index.html", "atom.xml",
- "post_2000-12-24_blah.html",
- "post_2000-12-20_blah.html",
- "post_2000-12-12_blah.html",
- "post_2000-12-08_blah.html",
- "post_2000-12-04_blah.html",
- "post_2000-11-23_blah.html",
- "post_2000-11-19_blah.html",
- "post_2000-11-11_blah.html",
- "post_2000-11-07_blah.html",
- "post_2000-11-03_blah.html",
- "post_2000-10-22_blah.html",
- "post_2000-10-18_blah.html",
- "post_2000-10-10_blah.html",
- "post_2000-10-06_blah.html",
- "post_2000-10-02_blah.html",
- "post_2000-09-21_blah.html",
- "post_2000-09-17_blah.html",
- "post_2000-09-09_blah.html",
- "post_2000-09-05_blah.html",
- "post_2000-09-01_blah.html",
- "post_2000-08-28_blah.html",
- "post_2000-08-20_blah.html",
- "post_2000-08-16_blah.html",
- "post_2000-08-08_blah.html",
- "post_2000-08-04_blah.html",
- "post_2000-07-27_blah.html",
- "post_2000-07-19_blah.html",
- "post_2000-07-15_blah.html",
- "post_2000-07-07_blah.html",
- "post_2000-07-03_blah.html",
- "post_2000-06-26_blah.html",
- "post_2000-06-18_blah.html",
- "post_2000-06-14_blah.html",
- "post_2000-06-06_blah.html",
- "post_2000-06-02_blah.html",
- "post_2000-05-25_blah.html",
- "post_2000-05-17_blah.html",
- "post_2000-05-13_blah.html",
- "post_2000-05-05_blah.html",
- "post_2000-05-01_blah.html",
- "post_2000-04-28_blah.html",
- "post_2000-04-24_blah.html",
- "post_2000-04-16_blah.html",
- "post_2000-04-12_blah.html",
- "post_2000-04-04_blah.html",
- "post_2000-03-27_blah.html",
- "post_2000-03-23_blah.html",
- "post_2000-03-15_blah.html",
- "post_2000-03-11_blah.html",
- "post_2000-03-03_blah.html",
- "post_2000-02-26_blah.html",
- "post_2000-02-22_blah.html",
- "post_2000-02-14_blah.html",
- "post_2000-02-10_blah.html",
- "post_2000-02-02_blah.html",
- "post_2000-01-25_blah.html",
- "post_2000-01-21_blah.html",
- "post_2000-01-13_blah.html",
- "post_2000-01-09_blah.html",
- "post_2000-01-05_blah.html",
- "post_2000-01-01_blah.html",
- ],
- m.GetWriteFileData(m._LEAFNAME))
-
- # check that "all_entries" in index & month pages contain the full
list
- # of items, not just the ones for the page (i.e. all_entries !=
entries)
- self.assertTrue(SiteDefault._TEMPLATE_HTML_MONTH in
m._fill_template_params)
- for keywords in
m._fill_template_params[SiteDefault._TEMPLATE_HTML_MONTH]:
- self.assertEquals(len(items), len(keywords["all_entries"]))
-
- self.assertTrue(SiteDefault._TEMPLATE_HTML_INDEX in
m._fill_template_params)
- for keywords in
m._fill_template_params[SiteDefault._TEMPLATE_HTML_INDEX]:
- self.assertEquals(len(items), len(keywords["all_entries"]))
-
- def testGeneratePages_1Cat(self):
- """
- Print items with only one category, this does not generate
- category indexes.
- """
- m = MockSiteDefault(self, self.Log(), False, True,
self.sis).MakeDestDirs()
-
- items = []
- cats = [ "first" ]
- for x in xrange(0, DEFAULT_ITEMS_PER_PAGE + 1):
- # x % 7 => we'll generate 7 month pages
- si = SiteItem(source_item=None,
- date=datetime(2000, 1 + (x % 7), 1 + (x % 28),
x % 24, x % 60, x % 60),
- title="blah",
- permalink="item",
- content_gen=lambda t, x: "content",
- categories=cats)
- items.append(si)
-
- m.GeneratePages(cats, items)
- self.assertListEquals(
- [ "2000-07.html", "2000-06.html", "2000-05.html",
- "2000-04.html", "2000-03.html", "2000-02.html", "2000-01.html",
- "index.html", "atom.xml",
-# "post_2000-07-21_blah.html",TODO EDIT
-# "post_2000-07-14_blah.html",
-# "post_2000-07-07_blah.html",
-# "post_2000-06-20_blah.html",
-# "post_2000-06-13_blah.html",
-# "post_2000-06-06_blah.html",
-# "post_2000-05-19_blah.html",
-# "post_2000-05-12_blah.html",
-# "post_2000-05-05_blah.html",
-# "post_2000-04-18_blah.html",
-# "post_2000-04-11_blah.html",
-# "post_2000-04-04_blah.html",
-# "post_2000-03-17_blah.html",
-# "post_2000-03-10_blah.html",
-# "post_2000-03-03_blah.html",
-# "post_2000-02-16_blah.html",
-# "post_2000-02-09_blah.html",
-# "post_2000-02-02_blah.html",
-# "post_2000-01-15_blah.html",
-# "post_2000-01-08_blah.html",
- ],
- m.GetWriteFileData(m._LEAFNAME))
-
- def testGeneratePages_2Cats(self):
- """
- With two categories, we get category pages too
- """
- m = MockSiteDefault(self, self.Log(), False, True,
self.sis).MakeDestDirs()
-
- items = []
- cats = [ "first", "second" ]
- for x in xrange(0, DEFAULT_ITEMS_PER_PAGE + 1):
- # x % 5 => we'll generate 5 month pages
- si = SiteItem(source_item=None,
- date=datetime(2000, 1 + (x % 5), 1 + (x % 28),
x % 24, x % 60, x % 60),
- title="blah",
- permalink="item",
- content_gen=lambda t, x: "content",
- categories=cats)
- items.append(si)
-
- m.GeneratePages(cats, items)
- self.assertListEquals(
-
[ "2000-05.html", "2000-04.html", "2000-03.html", "2000-02.html", "2000-01.html",
- "index.html", "atom.xml",
- os.path.join("cat", "first", "2000-05.html"),
- os.path.join("cat", "first", "2000-04.html"),
- os.path.join("cat", "first", "2000-03.html"),
- os.path.join("cat", "first", "2000-02.html"),
- os.path.join("cat", "first", "2000-01.html"),
- os.path.join("cat", "first", "index.html"),
- os.path.join("cat", "first", "atom.xml"),
- os.path.join("cat", "first", "post_2000-05-20_blah.html"),
- os.path.join("cat", "first", "post_2000-05-15_blah.html"),
- os.path.join("cat", "first", "post_2000-05-10_blah.html"),
- os.path.join("cat", "first", "post_2000-05-05_blah.html"),
- os.path.join("cat", "first", "post_2000-04-19_blah.html"),
- os.path.join("cat", "first", "post_2000-04-14_blah.html"),
- os.path.join("cat", "first", "post_2000-04-09_blah.html"),
- os.path.join("cat", "first", "post_2000-04-04_blah.html"),
- os.path.join("cat", "first", "post_2000-03-18_blah.html"),
- os.path.join("cat", "first", "post_2000-03-13_blah.html"),
- os.path.join("cat", "first", "post_2000-03-08_blah.html"),
- os.path.join("cat", "first", "post_2000-03-03_blah.html"),
- os.path.join("cat", "first", "post_2000-02-17_blah.html"),
- os.path.join("cat", "first", "post_2000-02-12_blah.html"),
- os.path.join("cat", "first", "post_2000-02-07_blah.html"),
- os.path.join("cat", "first", "post_2000-02-02_blah.html"),
- os.path.join("cat", "first", "post_2000-01-21_blah.html"),
- os.path.join("cat", "first", "post_2000-01-16_blah.html"),
- os.path.join("cat", "first", "post_2000-01-11_blah.html"),
- os.path.join("cat", "first", "post_2000-01-06_blah.html"),
- os.path.join("cat", "first", "post_2000-01-01_blah.html"),
- os.path.join("cat", "second", "2000-05.html"),
- os.path.join("cat", "second", "2000-04.html"),
- os.path.join("cat", "second", "2000-03.html"),
- os.path.join("cat", "second", "2000-02.html"),
- os.path.join("cat", "second", "2000-01.html"),
- os.path.join("cat", "second", "index.html"),
- os.path.join("cat", "second", "atom.xml"),
- os.path.join("cat", "second", "post_2000-05-20_blah.html"),
- os.path.join("cat", "second", "post_2000-05-15_blah.html"),
- os.path.join("cat", "second", "post_2000-05-10_blah.html"),
- os.path.join("cat", "second", "post_2000-05-05_blah.html"),
- os.path.join("cat", "second", "post_2000-04-19_blah.html"),
- os.path.join("cat", "second", "post_2000-04-14_blah.html"),
- os.path.join("cat", "second", "post_2000-04-09_blah.html"),
- os.path.join("cat", "second", "post_2000-04-04_blah.html"),
- os.path.join("cat", "second", "post_2000-03-18_blah.html"),
- os.path.join("cat", "second", "post_2000-03-13_blah.html"),
- os.path.join("cat", "second", "post_2000-03-08_blah.html"),
- os.path.join("cat", "second", "post_2000-03-03_blah.html"),
- os.path.join("cat", "second", "post_2000-02-17_blah.html"),
- os.path.join("cat", "second", "post_2000-02-12_blah.html"),
- os.path.join("cat", "second", "post_2000-02-07_blah.html"),
- os.path.join("cat", "second", "post_2000-02-02_blah.html"),
- os.path.join("cat", "second", "post_2000-01-21_blah.html"),
- os.path.join("cat", "second", "post_2000-01-16_blah.html"),
- os.path.join("cat", "second", "post_2000-01-11_blah.html"),
- os.path.join("cat", "second", "post_2000-01-06_blah.html"),
- os.path.join("cat", "second", "post_2000-01-01_blah.html"),
- ],
- m.GetWriteFileData(m._LEAFNAME))
-
- def testGeneratePages_3Cats(self):
- """
- More categories: 4 main pages but each category has only 2 pages
- """
- m = MockSiteDefault(self, self.Log(), False, True,
self.sis).MakeDestDirs()
-
- items = []
- cats = [ "first", "second", "three" ]
- for x in xrange(0, DEFAULT_ITEMS_PER_PAGE * 3 + 3):
- # x % 3 => we'll generate 3 month pages and we have 3
categories
- # so each category ends up in the same month.
- si = SiteItem(source_item=None,
- date=datetime(2000, 1 + (x % 3), 1 + (x % 28),
x % 24, x % 60, x % 60),
- title="blah",
- permalink="item",
- content_gen=lambda t, x: "content",
- categories=[ cats[x % 3] ])
- items.append(si)
-
- m.GeneratePages(cats, items)
- self.assertListEquals(
- [ "2000-03.html", "2000-02.html", "2000-01.html",
- "index.html", "atom.xml",
- os.path.join("cat", "first", "2000-01.html"),
- os.path.join("cat", "first", "index.html"),
- os.path.join("cat", "first", "atom.xml"),
- os.path.join("cat", "first", "post_2000-01-28_blah.html"),
- os.path.join("cat", "first", "post_2000-01-27_blah.html"),
- os.path.join("cat", "first", "post_2000-01-25_blah.html"),
- os.path.join("cat", "first", "post_2000-01-24_blah.html"),
- os.path.join("cat", "first", "post_2000-01-22_blah.html"),
- os.path.join("cat", "first", "post_2000-01-21_blah.html"),
- os.path.join("cat", "first", "post_2000-01-19_blah.html"),
- os.path.join("cat", "first", "post_2000-01-18_blah.html"),
- os.path.join("cat", "first", "post_2000-01-16_blah.html"),
- os.path.join("cat", "first", "post_2000-01-15_blah.html"),
- os.path.join("cat", "first", "post_2000-01-13_blah.html"),
- os.path.join("cat", "first", "post_2000-01-12_blah.html"),
- os.path.join("cat", "first", "post_2000-01-10_blah.html"),
- os.path.join("cat", "first", "post_2000-01-09_blah.html"),
- os.path.join("cat", "first", "post_2000-01-07_blah.html"),
- os.path.join("cat", "first", "post_2000-01-06_blah.html"),
- os.path.join("cat", "first", "post_2000-01-05_blah.html"),
- os.path.join("cat", "first", "post_2000-01-04_blah.html"),
- os.path.join("cat", "first", "post_2000-01-03_blah.html"),
- os.path.join("cat", "first", "post_2000-01-02_blah.html"),
- os.path.join("cat", "first", "post_2000-01-01_blah.html"),
- os.path.join("cat", "second", "2000-02.html"),
- os.path.join("cat", "second", "index.html"),
- os.path.join("cat", "second", "atom.xml"),
- os.path.join("cat", "second", "post_2000-02-28_blah.html"),
- os.path.join("cat", "second", "post_2000-02-26_blah.html"),
- os.path.join("cat", "second", "post_2000-02-25_blah.html"),
- os.path.join("cat", "second", "post_2000-02-23_blah.html"),
- os.path.join("cat", "second", "post_2000-02-22_blah.html"),
- os.path.join("cat", "second", "post_2000-02-20_blah.html"),
- os.path.join("cat", "second", "post_2000-02-19_blah.html"),
- os.path.join("cat", "second", "post_2000-02-17_blah.html"),
- os.path.join("cat", "second", "post_2000-02-16_blah.html"),
- os.path.join("cat", "second", "post_2000-02-14_blah.html"),
- os.path.join("cat", "second", "post_2000-02-13_blah.html"),
- os.path.join("cat", "second", "post_2000-02-11_blah.html"),
- os.path.join("cat", "second", "post_2000-02-10_blah.html"),
- os.path.join("cat", "second", "post_2000-02-08_blah.html"),
- os.path.join("cat", "second", "post_2000-02-07_blah.html"),
- os.path.join("cat", "second", "post_2000-02-06_blah.html"),
- os.path.join("cat", "second", "post_2000-02-05_blah.html"),
- os.path.join("cat", "second", "post_2000-02-04_blah.html"),
- os.path.join("cat", "second", "post_2000-02-03_blah.html"),
- os.path.join("cat", "second", "post_2000-02-02_blah.html"),
- os.path.join("cat", "second", "post_2000-02-01_blah.html"),
- os.path.join("cat", "three", "2000-03.html"),
- os.path.join("cat", "three", "index.html"),
- os.path.join("cat", "three", "atom.xml"),
- os.path.join("cat", "three", "post_2000-03-27_blah.html"),
- os.path.join("cat", "three", "post_2000-03-26_blah.html"),
- os.path.join("cat", "three", "post_2000-03-24_blah.html"),
- os.path.join("cat", "three", "post_2000-03-23_blah.html"),
- os.path.join("cat", "three", "post_2000-03-21_blah.html"),
- os.path.join("cat", "three", "post_2000-03-20_blah.html"),
- os.path.join("cat", "three", "post_2000-03-18_blah.html"),
- os.path.join("cat", "three", "post_2000-03-17_blah.html"),
- os.path.join("cat", "three", "post_2000-03-15_blah.html"),
- os.path.join("cat", "three", "post_2000-03-14_blah.html"),
- os.path.join("cat", "three", "post_2000-03-12_blah.html"),
- os.path.join("cat", "three", "post_2000-03-11_blah.html"),
- os.path.join("cat", "three", "post_2000-03-09_blah.html"),
- os.path.join("cat", "three", "post_2000-03-08_blah.html"),
- os.path.join("cat", "three", "post_2000-03-07_blah.html"),
- os.path.join("cat", "three", "post_2000-03-06_blah.html"),
- os.path.join("cat", "three", "post_2000-03-05_blah.html"),
- os.path.join("cat", "three", "post_2000-03-04_blah.html"),
- os.path.join("cat", "three", "post_2000-03-03_blah.html"),
- os.path.join("cat", "three", "post_2000-03-02_blah.html"),
- os.path.join("cat", "three", "post_2000-03-01_blah.html"),
- ],
- m.GetWriteFileData(m._LEAFNAME))
-
- def testGeneratePages_UseCurrMonth(self):
- """
- Test that index contains all items from the first month when
- use_curr_month_in_index is True, even if it's more than
- num_item_page.
- """
- self.sis.use_curr_month_in_index = True
- self.sis.num_item_page = 2
- m = MockSiteDefault(self, self.Log(), False, True,
self.sis).MakeDestDirs()
-
- items = []
- cats = []
- # generate 2 months with 5 items per month each
- for mo in xrange(0, 2):
- for d in xrange(0, 5):
- si = SiteItem(source_item=None,
- date=datetime(2000, 1 + mo, 1 + d, 0, 0, 0),
- title="blah",
- permalink="item",
- content_gen=lambda t, x: "content",
- categories=cats)
- items.append(si)
-
- m.GeneratePages(cats, items)
-
- self.assertListEquals(
- [ "2000-02.html", "2000-01.html",
- "index.html", "atom.xml",
- "post_2000-02-05_blah.html",
- "post_2000-02-04_blah.html",
- "post_2000-02-03_blah.html",
- "post_2000-02-02_blah.html",
- "post_2000-02-01_blah.html",
- "post_2000-01-05_blah.html",
- "post_2000-01-04_blah.html",
- "post_2000-01-03_blah.html",
- "post_2000-01-02_blah.html",
- "post_2000-01-01_blah.html"
- ],
- m.GetWriteFileData(m._LEAFNAME))
-
- self.assertTrue(SiteDefault._TEMPLATE_HTML_INDEX in
m._fill_template_params)
- self.assertTrue(1,
len(m._fill_template_params[SiteDefault._TEMPLATE_HTML_INDEX]))
- self.assertTrue("entries" in
m._fill_template_params[SiteDefault._TEMPLATE_HTML_INDEX][0])
- self.assertListEquals(
- [ datetime(2000, 2, 5, 0, 0),
- datetime(2000, 2, 4, 0, 0),
- datetime(2000, 2, 3, 0, 0),
- datetime(2000, 2, 2, 0, 0),
- datetime(2000, 2, 1, 0, 0) ],
- [ j.date
- for j in
m._fill_template_params[SiteDefault._TEMPLATE_HTML_INDEX][0]["entries"] ])
-
- # Now if we set num_item_page to 7, we'll get the 5 items of the
last month
- # plus 2 from the next month
-
- self.sis.num_item_page = 7
- m = MockSiteDefault(self, self.Log(), False, True,
self.sis).MakeDestDirs()
-
- m.GeneratePages(cats, items)
-
- self.assertListEquals(
- [ "2000-02.html", "2000-01.html",
- "index.html", "atom.xml",
- "post_2000-02-05_blah.html",
- "post_2000-02-04_blah.html",
- "post_2000-02-03_blah.html",
- "post_2000-02-02_blah.html",
- "post_2000-02-01_blah.html",
- "post_2000-01-05_blah.html",
- "post_2000-01-04_blah.html",
- "post_2000-01-03_blah.html",
- "post_2000-01-02_blah.html",
- "post_2000-01-01_blah.html"
- ],
- m.GetWriteFileData(m._LEAFNAME))
-
- self.assertTrue(SiteDefault._TEMPLATE_HTML_INDEX in
m._fill_template_params)
- self.assertTrue(1,
len(m._fill_template_params[SiteDefault._TEMPLATE_HTML_INDEX]))
- self.assertTrue("entries" in
m._fill_template_params[SiteDefault._TEMPLATE_HTML_INDEX][0])
- self.assertListEquals(
- [ datetime(2000, 2, 5, 0, 0),
- datetime(2000, 2, 4, 0, 0),
- datetime(2000, 2, 3, 0, 0),
- datetime(2000, 2, 2, 0, 0),
- datetime(2000, 2, 1, 0, 0),
- datetime(2000, 1, 5, 0, 0),
- datetime(2000, 1, 4, 0, 0) ],
- [ j.date
- for j in
m._fill_template_params[SiteDefault._TEMPLATE_HTML_INDEX][0]["entries"] ])
-
- def testGeneratePages_DontUseCurrMonth(self):
- """
- Test that index contains N max items independantly of the first
month when
- use_curr_month_in_index is False.
- """
- self.sis.use_curr_month_in_index = False
- self.sis.num_item_page = 2
- m = MockSiteDefault(self, self.Log(), False, True,
self.sis).MakeDestDirs()
-
- items = []
- cats = []
- # generate 2 months with 5 items per month each
- for mo in xrange(0, 2):
- for d in xrange(0, 5):
- si = SiteItem(source_item=None,
- date=datetime(2000, 1 + mo, 1 + d, 0, 0, 0),
- title="blah",
- permalink="item",
- content_gen=lambda t, x: "content",
- categories=cats)
- items.append(si)
-
- m.GeneratePages(cats, items)
-
- self.assertListEquals(
- [ "2000-02.html", "2000-01.html",
- "index.html", "atom.xml",
- "post_2000-02-05_blah.html",
- "post_2000-02-04_blah.html",
- "post_2000-02-03_blah.html",
- "post_2000-02-02_blah.html",
- "post_2000-02-01_blah.html",
- "post_2000-01-05_blah.html",
- "post_2000-01-04_blah.html",
- "post_2000-01-03_blah.html",
- "post_2000-01-02_blah.html",
- "post_2000-01-01_blah.html"
- ],
- m.GetWriteFileData(m._LEAFNAME))
-
- self.assertTrue(SiteDefault._TEMPLATE_HTML_INDEX in
m._fill_template_params)
- self.assertTrue(1,
len(m._fill_template_params[SiteDefault._TEMPLATE_HTML_INDEX]))
- self.assertTrue("entries" in
m._fill_template_params[SiteDefault._TEMPLATE_HTML_INDEX][0])
- self.assertListEquals(
- [ datetime(2000, 2, 5, 0, 0),
- datetime(2000, 2, 4, 0, 0) ],
- [ j.date
- for j in
m._fill_template_params[SiteDefault._TEMPLATE_HTML_INDEX][0]["entries"] ])
-
- # Now if we set num_item_page to 7, we'll get the 5 items of the
last month
- # plus 2 from the next month
-
- self.sis.num_item_page = 7
- m = MockSiteDefault(self, self.Log(), False, True,
self.sis).MakeDestDirs()
-
- m.GeneratePages(cats, items)
-
- self.assertListEquals(
- [ "2000-02.html", "2000-01.html",
- "index.html", "atom.xml",
- "post_2000-02-05_blah.html",
- "post_2000-02-04_blah.html",
- "post_2000-02-03_blah.html",
- "post_2000-02-02_blah.html",
- "post_2000-02-01_blah.html",
- "post_2000-01-05_blah.html",
- "post_2000-01-04_blah.html",
- "post_2000-01-03_blah.html",
- "post_2000-01-02_blah.html",
- "post_2000-01-01_blah.html"
- ],
- m.GetWriteFileData(m._LEAFNAME))
-
- self.assertTrue(SiteDefault._TEMPLATE_HTML_INDEX in
m._fill_template_params)
- self.assertTrue(1,
len(m._fill_template_params[SiteDefault._TEMPLATE_HTML_INDEX]))
- self.assertTrue("entries" in
m._fill_template_params[SiteDefault._TEMPLATE_HTML_INDEX][0])
- self.assertListEquals(
- [ datetime(2000, 2, 5, 0, 0),
- datetime(2000, 2, 4, 0, 0),
- datetime(2000, 2, 3, 0, 0),
- datetime(2000, 2, 2, 0, 0),
- datetime(2000, 2, 1, 0, 0),
- datetime(2000, 1, 5, 0, 0),
- datetime(2000, 1, 4, 0, 0) ],
- [ j.date
- for j in
m._fill_template_params[SiteDefault._TEMPLATE_HTML_INDEX][0]["entries"] ])
-
- def testClearCache(self):
- """
- Tests the ClearCache method which computes a coherency key and only
- clears the cache when settings or templates change.
***The diff for this file has been truncated for email.***
=======================================
--- /trunk/rig3serv/misc/Design.txt Sat Jun 5 15:02:06 2010
+++ /trunk/rig3serv/misc/Design.txt Tue Sep 7 00:27:42 2010
@@ -10,10 +10,20 @@
Summary:
- Input blog posts are either Izumi (text with wiki-like syntax) or HTML.
-- Rig3 has two "expansion" mechanisms. Izumi files are first converted to
- HTML when found. The HTML is then fed to the "template engine",
- which is a macro processor (i.e. like PHP or Django templates).
- (Native HTML posts do not go thru the template engine.)
+
+- Rig3 has two "expansion" mechanisms:
+
+A- Izumi files are text files that contains formatting instructions in
brackets,
+ e.g. "[label|
http://link]". The IzuParser class knows how to convert
these
+ Izu files or strings to parial-HTML, which may contain template tags.
+
+B- The partial-HTML is then fed to the "template engine", which is a macro
processor
+ (i.e. like PHP or Django templates). Here the template is based on tags
+ which are enclosed in double-brackets. There are tags to inject
variables,
+ do some computations or do conditional execution (for, if).
+
+- Pure-HTML posts do not go thru the template engine.
+
- Wrapper templates are then available to generate full HTML or Atom pages
from individual blog posts.
@@ -39,7 +49,7 @@
- for CSS files, transform using the template engine.
- for all sources in the site's setting source list:
- _ProcessSourceItems:
- - source.Parse => a generator of SourceItem (aka SourceFile,
SourceDir)
+ - source.Parse => a generator of SourceItem (aka SourceFile,
SourceDir, SourceContent)
- for all SourceItems:
- remove dups (by hashing on path/settings)
- GenerateItem: transforms SourceItem into SiteItem
@@ -50,9 +60,11 @@
4- GenerateItem:
- Currently implemented only in rig.site.site_default for the photoblog
- Input must be either SourceFile (one izu file = one blog post) or
- SourceDir (one directory with index.izu + pictures = one blog post)
+ SourceDir (one directory with index.izu + pictures = one blog post) or
+ SourceContent (one izu string = one blog post)
- Parse date and title from file name or dir name
- If there's an izu file, pre-render it to HTML
(rig.parser.izu_parser.RenderFileToHtml)
+ If there's an izu content, pre-render it to HTML
(rig.parser.izu_parser.RenderStringToHtml)
- Generates a list of tags:
- Use date, title or categories from parsed izu tags, if any.
- Generates a list of sections:
@@ -126,8 +138,8 @@
- Parents folders are used to provide categories and index.izu files (or
some kind of
specific file) can provide additional tags.
- Generated pages:
- - Page for the Most recent N items
- - Page for all items of category X
+ - Page for the Most recent N items
+ - Page for all items of category X
- Each item should be generated as a bit of HTML, cached as an embeddable
HTML file.
- Each page is a collection of existing items. We can use .shtml on the
server
side (to be enabled in Apache) to link the separate items into a single
page,
@@ -145,24 +157,24 @@
Stages:
- Stage 1:
- - Ignore pictures (i.e. the album view will be a link to an existing
- Rig1) and only deal with folders that contain an index.izu.
- - Requires a new Izu formatter in Python that can embedded the Rig
images.
- - Have global config vs sites configs.
- - Patterns for valid folder names
- - Settings for generating the Rig links
- - Generate .shtml for items and create pages that uses them.
+ - Ignore pictures (i.e. the album view will be a link to an existing
+ Rig1) and only deal with folders that contain an index.izu.
+ - Requires a new Izu formatter in Python that can embedded the Rig
images.
+ - Have global config vs sites configs.
+ - Patterns for valid folder names
+ - Settings for generating the Rig links
+ - Generate .shtml for items and create pages that uses them.
- Stage 2:
- - Remove obsolete destination items/pages
- - Generate embedded album views, with a link onto the full rig version.
- - Settings/patterns for image levels (unwanted/ignored,
low/medium/good/excellent)
- - Experiment with AJAX instead of shtml (or provide it as an option)
- - Tags to be able to remove a given source folder from processing
- - Tags to generate .htaccess into destination
+ - Remove obsolete destination items/pages
+ - Generate embedded album views, with a link onto the full rig version.
+ - Settings/patterns for image levels (unwanted/ignored,
low/medium/good/excellent)
+ - Experiment with AJAX instead of shtml (or provide it as an option)
+ - Tags to be able to remove a given source folder from processing
+ - Tags to generate .htaccess into destination
Expansions:
- Ability to generate on-the-fly obfuscated pages for sharing
- - can be done at first by symlinking the html on the web server
+ - can be done at first by symlinking the html on the web server
----
20070827 Structure Stage 1
@@ -176,11 +188,11 @@
- settings.py: Load() from .rig3.rc f.ex (flat settings dict per site)
- dirparser.py: Parse(dir) => list [ Dir( ... ) ] (recursive)
- generate.py: Generate(site)
- - load source for site
- - compare to dest
- - generate or update items
- - keep links per type: last-n-page or page-cat-X (dict of list or dict of
dict)
- - generate pages
+ - load source for site
+ - compare to dest
+ - generate or update items
+ - keep links per type: last-n-page or page-cat-X (dict of list or dict
of dict)
+ - generate pages
- izumi.py: ConvertToHtml(izu)
- thumbnail.py: UrlForImage(file, quality, size)
- cache.py: Store(type, name, ref), or update. Cleanup()
@@ -335,12 +347,12 @@
The izu index should have the following structure:
- An izu header on the first line (same tags).
- - The date & title are optional.
- - If not present, the defaults extracted from the directory name will be
used.
- - If present, they must override these defaults.
+ - The date & title are optional.
+ - If not present, the defaults extracted from the directory name will be
used.
+ - If present, they must override these defaults.
- Sections: "en" (english), "fr" (french), "images", "notes".
- - Sections are optional. "en" is the default if not specified.
- - Sections are to be used in the template if present.
+ - Sections are optional. "en" is the default if not specified.
+ - Sections are to be used in the template if present.
The purpose of the sections is to further separate layout from content:
even in the current HTML of the "old" wordpress blog, I have quite a bit of
@@ -471,22 +483,22 @@
20071121 Next Steps
- Permalinks
- - Ironically, requires to save each post as a separate HTML file
- - links: prev/next/up. Up goes to the corresponding index with an anchor.
+ - Ironically, requires to save each post as a separate HTML file
+ - links: prev/next/up. Up goes to the corresponding index with an anchor.
- RSS generation
- - discovery links
+ - discovery links
- Site customization/refactor.
- - Ability to have several sources. Each source generates a dated list of
entries.
- - DirParser is just one of them.
- - Adapt DirParser to return single files w/ pattern <date><title>.izu
- - Later I'll want a parser for old izu files that contain multiple
entries.
- - It can be all done by DirParser but we want to make it configurable in
- site prefs.
- - Move prefs to site prefs w/ defaults. Essentially regexps but also Rig
sizes.
- - Extract actual page/items/images generation.
+ - Ability to have several sources. Each source generates a dated list of
entries.
+ - DirParser is just one of them.
+ - Adapt DirParser to return single files w/ pattern <date><title>.izu
+ - Later I'll want a parser for old izu files that contain multiple
entries.
+ - It can be all done by DirParser but we want to make it configurable
in
+ site prefs.
+ - Move prefs to site prefs w/ defaults. Essentially regexps but also Rig
sizes.
+ - Extract actual page/items/images generation.
- IzuParser:
- - add a raw HTML tag, to include HTML inline on the spot, e.g.
[html:-- ... --].
- - [img:] tag that work for current album (or simply [blah.jpg])
+ - add a raw HTML tag, to include HTML inline on the spot, e.g.
[html:-- ... --].
+ - [img:] tag that work for current album (or simply [blah.jpg])
- Documentation
The long term goal is that it should be possible to switch templates *and*
switch the
=======================================
--- /trunk/rig3serv/src/rig/parser/izu_parser.py Mon Aug 30 23:36:44 2010
+++ /trunk/rig3serv/src/rig/parser/izu_parser.py Tue Sep 7 00:27:42 2010
@@ -34,7 +34,7 @@
from StringIO import StringIO
from rig.parser.utf8_accents import UTF8_ACCENTS_TO_HTML
-from rig.parser.dir_parser import RelPath
+from rig.parser.dir_parser import RelPath, RelFile
_DATE_YMD =
re.compile(r"^(?P<year>\d{4})[:/-]?(?P<month>\d{2})[:/-]?(?P<day>\d{2})"
r"(?:[ ,:/-]?(?P<hour>\d{2})[:/.-]?(?P<min>\d{2})(?:[:/.-]?(?P<sec>\d{2}))?)?")
@@ -193,7 +193,7 @@
self._tag_handlers = { "cat" : self._CatHandler,
"date" : self._DateHandler }
- def RenderFileToHtml(self, filestream, encoding):
+ def RenderFileToHtml(self, filestream, encoding=None):
"""
Parses the file 'filename' and returns an HTML snippet for it.
Renders a <div> section, not a full single HTML file.
@@ -214,16 +214,34 @@
- most are HTML content.
- the "images" section must be a list of RIG urls.
"""
+ return self.__RenderContent(filestream, encoding)
+
+ def RenderStringToHtml(self, source, encoding=None, rel_file=None):
+ """
+ Renders an Izu string to HTML.
+ This is an utility wrapper that actually calls RenderFileToHtml.
+
+ Rel_file is the originating file, if any, where the string was
+ extracted from. The file itself is not used, only its parent
+ directory is used for rigimg/riglink image glob patterns and such.
+
+ Encoding must be the desired text file encoding, e.g. "utf-8"
+ or "iso-8859-1", as supported by the codecs.open() method.
+ """
+ f = StringIO(source)
+ return self.__RenderContent(f, encoding, rel_file)
+
+ def __RenderContent(self, filestream, encoding=None, rel_file=None):
f = None
result = None
try:
- rel_file = None
if isinstance(filestream, (str, unicode)):
# open with 1=line buffered, U=universal end-of-lines
f = codecs.open(filestream, mode="rU", buffering=1,
encoding=encoding,
errors="xmlcharrefreplace")
filename = filestream
+ rel_file = RelFile(os.path.dirname(filestream),
os.path.basename(filestream))
elif isinstance(filestream, RelPath):
filename = filestream.abs_path
rel_file = filestream
@@ -244,17 +262,6 @@
self._log.Exception("Read-error for %s" % filestream)
return result
- def RenderStringToHtml(self, source, encoding):
- """
- Renders an Izu string to HTML.
- This is an utility wrapper that actually calls RenderFileToHtml.
-
- Encoding must be the desired text file encoding, e.g. "utf-8"
- or "iso-8859-1", as supported by the codecs.open() method.
- """
- f = StringIO(source)
- return self.RenderFileToHtml(f, encoding)
-
def ParseFirstLine(self, source):
"""
Parses the *first* line of a *string* -- the string is actual
content,
@@ -269,7 +276,7 @@
a = source.find("\r")
if a != -1:
source = source[:a]
- tags, sections = self.RenderStringToHtml(source, encoding=None)
#@UnusedVariable
+ tags, sections = self.RenderStringToHtml(source) #@UnusedVariable
return tags
def ParseFileFirstLine(self, filename, encoding):
@@ -694,7 +701,7 @@
def _FormatYoutube(self, state, line):
"""
- Formats any [[youtube:ID:SXxSY]] tag.
+ Formats any [youtube:ID:SXxSY] tag.
The ":SXxSY" part is optional.
"""
m = True
@@ -840,6 +847,11 @@
# rig image: [name|rigimg:size:image_glob]
line = self._ParseRigImage(state, line, accept_rest=True)
+ # izumi post link: [name|/category#s:date:title] or [name|
#s:date:title]
+ line = self._RE_IZU_POST_LINK.sub(
+ lambda m: self._ReplIzuPostLink(state, m.group(1), m.group(2),
m.group(3), m.group(4)),
+ line)
+
# unformatted link:
http://blah or ftp:// (link cannot contain
quotes)
# and must not be surrounded by quotes
# and must not be surrounded by brackets
@@ -855,6 +867,22 @@
_RE_LINK_UNNAMED_URL = re.compile(r'(?<!\[)\[((?:https?://|ftp://|
#)[^ "<>]+?)\]')
_RE_LINK_UNFORMATTED = re.compile(r'(^|[^\[]\]|[^"\[\]\|
>])((?:https?://|ftp://)[^ "<>]+)($|[^"\]])')
_RE_RIGLINK = re.compile(r'(?<!\[)\[([^\|\[\]]+)\|
riglink:([^ "<>]+?)\]')
+ _RE_IZU_POST_LINK = re.compile(r'(?<!\[)\[([^\|\[\]]+)\|(/[^ #:\[\]\|
]+)?#s:([0-9]{8})(?::([^\|\[\]]+))?\]')
+
+ def _ReplIzuPostLink(self, state, label, category, date, title):
+ """
+ Generates an izumi blog post link, either within the same category
or to
+ another category.
+
+ If category is available, we link to:
+ <album_base_url>/cat/<category>/post_<date>_<title>.html
+ If the category is not available, we need to figure the current
one.
+ """
+ return ("<pre> *** "
+ "curr_category=[[[[raw
locals().get('curr_category', 'NOT-SET2')]] "
+ "permalink_url=[[[[raw
locals().get('permalink_url', 'NOT-SET')]] "
+ "rel_permalink_url=[[[[raw
locals().get('rel_permalink_url', 'NOT-SET')]] "
+ "</pre>")
def _ParseRigImage(self, state, line, accept_rest):
"""
@@ -887,7 +915,12 @@
result = ""
filename = state.Filename()
if filename and image_glob:
- choice = self._GlobGlob(os.path.dirname(filename), image_glob)
+ rel_file = state.RelFile()
+ if rel_file:
+ abs_dir = rel_file.dirname().abs_path
+ else:
+ abs_dir = os.path.dirname(filename)
+ choice = self._GlobGlob(abs_dir, image_glob)
if choice:
subdir = os.path.dirname(choice)
filename = os.path.basename(choice)
@@ -915,10 +948,13 @@
result = ""
filename = state.Filename()
if filename and image_glob:
- abs_dir = os.path.dirname(filename)
+ rel_file = state.RelFile()
+ if rel_file:
+ abs_dir = rel_file.dirname().abs_path
+ else:
+ abs_dir = os.path.dirname(filename)
choice = self._GlobGlob(abs_dir, image_glob)
if choice:
- rel_file = state.RelFile()
if rel_file:
rel_file = rel_file.dirname().join(choice)
subdir = os.path.dirname(choice)
=======================================
--- /trunk/rig3serv/src/rig/site/site_default.py Mon Aug 30 23:36:44 2010
+++ /trunk/rig3serv/src/rig/site/site_default.py Tue Sep 7 00:27:42 2010
@@ -69,9 +69,6 @@
class SiteDefault(SiteBase):
"""
Describes how to generate the content of a site using the "default"
theme.
-
- Right now the "magic" theme is identical to the "default" theme
- so the implementation is empty. This is expected to change later.
"""
EXT_IZU = ".izu"
EXT_HTML = ".html"
@@ -170,7 +167,7 @@
# Do we have to generate anything at all?
hash_key = self._cache.GetKey([ categories, items ])
- if self._hash_store.Contains(hash_key):
+ if self._enable_cache and self._hash_store.Contains(hash_key):
if self._force:
self._log.Info("[%s] No new content found, forcing
generation",
self._site_settings.public_name)
@@ -678,7 +675,7 @@
- source_item: An instance of SourceItem.
"""
may_have_images, all_files, izu_file, html_file, title, rel_dir = \
-
self.__GenItem_GetFiles(source_item)
+
self._GenItem_GetFiles(source_item)
# TODO keep 2 keyword dicts: the main site_settings which does NOT
# need to be hashed for the cache (cache gets cleared on settings)
@@ -696,7 +693,7 @@
sections, tags = self._cache.Compute(
section_args,
- lambda: self.__GenItem_GetSections(*section_args),
+ lambda: self._GenItem_GetSections(*section_args),
stat_prefix="1.1 Izu",
use_cache=self._enable_cache)
@@ -719,7 +716,7 @@
cats,
title)
- def __GenItem_GetFiles(self, source_item):
+ def _GenItem_GetFiles(self, source_item):
may_have_images = False
all_files = None
izu_file = None
@@ -748,16 +745,19 @@
title = title[:-1 * len(self.EXT_HTML)] # remove ext from
title
elif isinstance(source_item, SourceContent):
+ html_file = "@content"
title = source_item.title
+ may_have_images = True
+ all_files = []
izu_file = source_item.rel_file
- html_file = "@content"
+ rel_dir = izu_file.dirname()
else:
raise NotImplementedError("TODO support %s" %
repr(source_item))
return may_have_images, all_files, izu_file, html_file, title,
rel_dir
- def __GenItem_GetSections(self,
+ def _GenItem_GetSections(self,
source_item,
may_have_images,
izu_file,
@@ -782,7 +782,7 @@
keywords["img_gen_script"])
if html_file == "@content":
tags = source_item.tags
- _, sections = p.RenderStringToHtml(source_item.content,
encoding)
+ _, sections = p.RenderStringToHtml(source_item.content,
encoding, source_item.rel_file)
else:
tags = p.ParseFileFirstLine(izu_file, encoding)
if "encoding" in tags:
@@ -811,7 +811,6 @@
keywords["rig_base"],
keywords["img_gen_script"])
tags = izu_parser.ParseFirstLine(sections["html"])
- #DEBUG--self._log.Debug("HTML : %s => '%s'", main_filename,
sections["html"])
else:
self._log.Debug("No content for source %s", source_item)
return None, None
@@ -883,7 +882,7 @@
_keywords["sections"]["images"] = _html_img
if "curr_category" in _keywords:
- # We need to update some keywords depending the current
category
+ # We need to update some keywords depending on the current
category
# being generated.
curr_category = _keywords["curr_category"]
permalink_url = _keywords["permalink_url"]
@@ -1206,7 +1205,8 @@
- If the name is too long, keep a shorter version with a CRC at
the end.
Returns the new file name.
"""
- name = re.sub(r"[ /\\-]+", "-", leafname)
+ name = leafname.lower()
+ name = re.sub(r"[ /\\-]+", "-", name)
name = re.sub(r"[^a-zA-Z0-9-]+", "_", name)
if maxlen <= 0:
maxlen = self._site_settings.mangled_name_len
@@ -1310,7 +1310,7 @@
}
hash_key = self._cache.GetKey(cache_coherency_key)
- f = self._hash_store.Contains(hash_key)
+ f = self._enable_cache and self._hash_store.Contains(hash_key)
if self._debug_cache:
self._log.Debug("Cache Coherency key [site=%s, found=%s,
hash=%s] = %s",
=======================================
--- /trunk/rig3serv/src/rig/source_reader.py Wed Sep 1 00:58:28 2010
+++ /trunk/rig3serv/src/rig/source_reader.py Tue Sep 7 00:27:42 2010
@@ -27,7 +27,7 @@
import codecs
import os
import re
-from binascii import crc32
+import zlib
from datetime import datetime
from rig.source_item import SourceDir, SourceFile, SourceContent
@@ -146,7 +146,7 @@
if valid_files:
self._log.Debug("[%s] Process '%s' to '%s'",
self._site_settings and
self._site_settings.public_name or "[Unnamed Site]",
- source_dir.rel_curr, dest_dir.rel_curr)
+ source_dir.rel_curr, dest_dir.rel_curr)
date =
datetime.fromtimestamp(self._DirTimeStamp(source_dir.abs_path))
item = SourceDir(date, source_dir, all_files,
self._source_settings)
@@ -167,7 +167,9 @@
date =
datetime.fromtimestamp(self._FileTimeStamp(rel_file.abs_path))
item = SourceFile(date, rel_file,
self._source_settings)
items.append(item)
- self._log.Debug("[%s] Append item '%s'", item)
+ self._log.Debug("[%s] Append item '%s'",
+ self._site_settings and
self._site_settings.public_name or "[Unnamed Site]",
+ item)
return items
@@ -233,7 +235,9 @@
tags["date"] = date
item = SourceContent(date, rel_file, title, content,
tags, self._source_settings)
items.append(item)
- self._log.Debug("[%s] Append item '%s'", item)
+ self._log.Debug("[%s] Append item '%s'",
+ self._site_settings and
self._site_settings.public_name or "[Unnamed Site]",
+ item)
content = ""
date = None
@@ -267,7 +271,9 @@
# Flush content
item = SourceContent(date, rel_file, title, content, tags,
self._source_settings)
items.append(item)
- self._log.Debug("[%s] Append item '%s'", item)
+ self._log.Debug("[%s] Append item '%s'",
+ self._site_settings and
self._site_settings.public_name or "[Unnamed Site]",
+ item)
f.close()
@@ -287,7 +293,10 @@
key = date + "_" + key
if len(key) > 32:
# shorten with a crc32
- key = "%s_%x" % (key[0:23], crc32(date + title))
+ # The adler32 CRC is returned as an int and can
thus "seem" negative
+ # convert to its true long 64-bit value, always positive
+ crc = zlib.adler32(date + title) & 0x0FFffFFffL
+ key = "%s_%8x" % (key[0:23], crc)
else:
key = date
=======================================
--- /trunk/rig3serv/src/rig/template/buffer.py Wed Sep 2 21:57:04 2009
+++ /trunk/rig3serv/src/rig/template/buffer.py Tue Sep 7 00:27:42 2010
@@ -126,13 +126,13 @@
def SkipTo(self, word):
"""
- Advances the buffer up to the first occurence of the given word
+ Advances the buffer up to the first occurrence of the given word
(not included) or to the end of the buffer.
Line numbers: The method returns *everything* between the current
position
- and the first occurence of word, including line separators. If
linesep is
+ and the first occurrence of word, including line separators. If
linesep is
defined, these are scanned for when the buffer is consumed and the
- Buffer.lineno is incremeted as necessary.
+ Buffer.lineno is incremented as necessary.
Returns whatever has been read in between or an empty string is
nothing changed (i.e. if the requested word is already at the
current
=======================================
--- /trunk/rig3serv/src/rig/template/tag.py Mon Aug 30 23:36:44 2010
+++ /trunk/rig3serv/src/rig/template/tag.py Tue Sep 7 00:27:42 2010
@@ -273,7 +273,34 @@
#------------------------
-ALL_TAGS = [TagComment, TagFor, TagIf, TagRaw, TagHtml, TagXml, TagUrl,
TagInsert]
+class TagEval(Tag):
+ """
+ Tag that represents a template evulation. The expression must
+ evaluate to a string that is the new template to inject and generate
+ in-place in the container template.
+
+ This is similar to [[insert]] except here we directly have the text
+ of the template rather than the filename of the template.
+
+ Template syntax:
+ [[eval python_expression]]
+ """
+ def __init__(self):
+ super(TagEval, self).__init__(tag="eval", has_content=False)
+
+ def Generate(self, log, tag_node, context):
+ source = eval(tag_node.Parameters(), dict(context))
+
+ if not not source:
+ from rig.template.template import Template
+ template = Template(log, source=source)
+ result = template.Generate(context)
+ return result
+ return ""
+
+
+#------------------------
+ALL_TAGS = [TagComment, TagFor, TagIf, TagRaw, TagHtml, TagXml, TagUrl,
TagInsert, TagEval]
#------------------------
# Local Variables:
=======================================
--- /trunk/rig3serv/src/rig/template/template.py Wed Sep 2 21:57:04 2009
+++ /trunk/rig3serv/src/rig/template/template.py Tue Sep 7 00:27:42 2010
@@ -164,6 +164,19 @@
Returns the next node in the buffer.
"""
if buffer.StartsWith("[[", consume=True):
+
+ # Tags start with [[. However we can use [[[ to escape a tag
+ # that should be ignored, the [[[ is converted to [[ and [[[[
+ # is converted to [[[, etc.
+
+ if buffer.StartsWith("[", consume=False):
+ bracket = "[" # because we consumed 2 [ above
+ while buffer.StartsWith("[", consume=True):
+ bracket += "["
+ literal = buffer.SkipTo("[[")
+ return NodeLiteral(bracket + literal)
+
+ # Process a normal tag opened with [[
keyword = buffer.NextWord().lower()
parameters = buffer.SkipTo("]]")
if not buffer.StartsWith("]]", consume=True):
=======================================
--- /trunk/rig3serv/src/test_rig3.py Mon Aug 30 23:36:44 2010
+++ /trunk/rig3serv/src/test_rig3.py Tue Sep 7 00:27:42 2010
@@ -55,6 +55,7 @@
localdir = os.path.join(os.path.dirname(__file__), "tests")
start = len(localdir.split(os.path.sep)) - 1
modules = []
+ ignored = []
for root, dirs, files in os.walk(localdir):
if "CVS" in dirs:
dirs.remove("CVS")
@@ -73,9 +74,13 @@
m.append(file)
m = m[start:]
name = ".".join(m)
- if (not test_filter) or name in test_filter:
+ if (not test_filter) or (name in test_filter):
modules.append(name)
-
+ else:
+ ignored.append(name)
+
+ if ignored:
+ print >>sys.stderr, "IGNORED Rig Tests:", ", ".join([m for m in
ignored])
print >>sys.stderr, "Rig Tests:", ", ".join([m.split(".")[-1] for m in
modules])
loader = unittest.TestLoader()
=======================================
--- /trunk/rig3serv/src/tests/parser/test_izu_parser.py Sun Aug 29 21:19:47
2010
+++ /trunk/rig3serv/src/tests/parser/test_izu_parser.py Tue Sep 7 00:27:42
2010
@@ -92,11 +92,11 @@
self.m = None
def _Render(self, text, section="en"):
- tags, sections = self.m.RenderStringToHtml(text, encoding=None)
#@UnusedVariable
+ tags, sections = self.m.RenderStringToHtml(text) #@UnusedVariable
return sections.get("en", None)
def _Tags(self, text):
- tags, sections = self.m.RenderStringToHtml(text, encoding=None)
#@UnusedVariable
+ tags, sections = self.m.RenderStringToHtml(text) #@UnusedVariable
return tags
def testEscapes(self):
@@ -327,68 +327,68 @@
self._Render("first
line\nfoo[!html:<blah1>\n<blah2>\n\ntoto</blah2>--]bar\nend"))
def testSection(self):
- tags, sections = self.m.RenderStringToHtml("default section is
en", encoding=None) #@UnusedVariable
+ tags, sections = self.m.RenderStringToHtml("default section is
en") #@UnusedVariable
self.assertEquals('<span class="izu">\ndefault section is
en</span>',
sections.get("en", None))
self.assertEquals(None, sections.get("fr", None))
- tags, sections = self.m.RenderStringToHtml("line 1[s:en]line 2",
encoding=None) #@UnusedVariable
+ tags, sections = self.m.RenderStringToHtml("line 1[s:en]line 2")
#@UnusedVariable
self.assertEquals('<span class="izu">\nline 1\nline 2</span>',
sections.get("en", None))
self.assertEquals(None, sections.get("fr", None))
- tags, sections = self.m.RenderStringToHtml("line 1\n[s:en]line 2",
encoding=None) #@UnusedVariable
+ tags, sections = self.m.RenderStringToHtml("line 1\n[s:en]line 2")
#@UnusedVariable
self.assertEquals('<span class="izu">\nline 1\nline 2</span>',
sections.get("en", None))
self.assertEquals(None, sections.get("fr", None))
- tags, sections = self.m.RenderStringToHtml("section
1\n[s:fr]section 2", encoding=None) #@UnusedVariable
+ tags, sections = self.m.RenderStringToHtml("section
1\n[s:fr]section 2") #@UnusedVariable
self.assertEquals('<span class="izu">\nsection 1</span>',
sections.get("en", None))
self.assertEquals('<span class="izu">\nsection 2</span>',
sections.get("fr", None))
- tags, sections = self.m.RenderStringToHtml("[s:en]section
1\n[s:fr]section 2", encoding=None) #@UnusedVariable
+ tags, sections = self.m.RenderStringToHtml("[s:en]section
1\n[s:fr]section 2") #@UnusedVariable
self.assertEquals('<span class="izu">\nsection 1</span>',
sections.get("en", None))
self.assertEquals('<span class="izu">\nsection 2</span>',
sections.get("fr", None))
- tags, sections = self.m.RenderStringToHtml("[s:fr]section
1\n[s:en]section 2", encoding=None) #@UnusedVariable
+ tags, sections = self.m.RenderStringToHtml("[s:fr]section
1\n[s:en]section 2") #@UnusedVariable
self.assertEquals('<span class="izu">\nsection 1</span>',
sections.get("fr", None))
self.assertEquals('<span class="izu">\nsection 2</span>',
sections.get("en", None))
# Empty sections generate *really* nothing, not even the wrapping
div (since
# there's nothing to wrap)
- tags, sections =
self.m.RenderStringToHtml("\n\n\n\n[s:en]\n\n\n\n\n[s:fr]\n\n\n\n",
encoding=None) #@UnusedVariable
+ tags, sections =
self.m.RenderStringToHtml("\n\n\n\n[s:en]\n\n\n\n\n[s:fr]\n\n\n\n")
#@UnusedVariable
self.assertEquals('', sections.get("en", None))
self.assertEquals('', sections.get("fr", None))
# A section before EOF generates nothing
- tags, sections = self.m.RenderStringToHtml("[s:fr]section
1[s:en]", encoding=None) #@UnusedVariable
+ tags, sections = self.m.RenderStringToHtml("[s:fr]section
1[s:en]") #@UnusedVariable
self.assertEquals('<span class="izu">\nsection 1</span>',
sections.get("fr", None))
self.assertEquals('', sections.get("en", None))
- tags, sections = self.m.RenderStringToHtml("[s:fr]section
1\n[s:en]", encoding=None) #@UnusedVariable
+ tags, sections = self.m.RenderStringToHtml("[s:fr]section
1\n[s:en]") #@UnusedVariable
self.assertEquals('<span class="izu">\nsection 1</span>',
sections.get("fr", None))
self.assertEquals('', sections.get("en", None))
# Sole section tags do not count as a white line that would
generate a <p>
- tags, sections = self.m.RenderStringToHtml("\n[s:en]\nline
1\n\n[s:fr]\nline 2\n\n", encoding=None) #@UnusedVariable
+ tags, sections = self.m.RenderStringToHtml("\n[s:en]\nline
1\n\n[s:fr]\nline 2\n\n") #@UnusedVariable
self.assertEquals('<span class="izu">\nline 1</span>',
sections.get("en", None))
self.assertEquals('<span class="izu">\nline 2</span>',
sections.get("fr", None))
def testIzuTags(self):
- tags, sections = self.m.RenderStringToHtml("[izu:author:ralf]",
encoding=None) #@UnusedVariable
+ tags, sections = self.m.RenderStringToHtml("[izu:author:ralf]")
#@UnusedVariable
self.assertDictEquals({ "author": "ralf" }, tags)
- tags, sections = self.m.RenderStringToHtml("[izu:date:2006-05-28
17:18:05]", encoding=None) #@UnusedVariable
+ tags, sections = self.m.RenderStringToHtml("[izu:date:2006-05-28
17:18:05]") #@UnusedVariable
self.assertDictEquals({ "date": datetime(2006, 5, 28, 17, 18, 5)
}, tags)
- tags, sections = self.m.RenderStringToHtml("[izu:date:2006:05:28
17:18:22]", encoding=None) #@UnusedVariable
+ tags, sections = self.m.RenderStringToHtml("[izu:date:2006:05:28
17:18:22]") #@UnusedVariable
self.assertDictEquals({ "date": datetime(2006, 5, 28, 17, 18, 22)
}, tags)
- tags, sections =
self.m.RenderStringToHtml("[izu:cat:videos,photos]", encoding=None)
#@UnusedVariable
+ tags, sections =
self.m.RenderStringToHtml("[izu:cat:videos,photos]") #@UnusedVariable
self.assertDictEquals({ "cat": { "videos": True, "photos": True }
}, tags)
- tags, sections = self.m.RenderStringToHtml("[izu:title:some random
title with : colon]", encoding=None) #@UnusedVariable
+ tags, sections = self.m.RenderStringToHtml("[izu:title:some random
title with : colon]") #@UnusedVariable
self.assertDictEquals({ "title": "some random title with : colon"
}, tags)
- tags, sections = self.m.RenderStringToHtml("[izu:date:0000-00-00
00:00:00]", encoding=None) #@UnusedVariable
+ tags, sections = self.m.RenderStringToHtml("[izu:date:0000-00-00
00:00:00]") #@UnusedVariable
self.assertDictEquals({}, tags)
def testParseFirstLine(self):
@@ -400,6 +400,11 @@
"cat": { "foo": True, "bar": True, "test":
True } },
tags)
+ def testConvertAccents(self):
+ self.assertEquals(
+ "ça, où est le pré près du
prêt?",
+ self.m._ConvertAccents("ça, où est le pré près du prêt?"))
+
def testAutoLink(self):
self.assertEquals(
'<span class="izu">\n<a
href="
http://www.example.code">
http://www.example.code</a></span>',
@@ -431,11 +436,6 @@
'<span class="izu">\n<img alt="My Image" title="My Image"
src="
http://www.example.code/image.gif"></span>',
self._Render("[My Image|
http://www.example.code/image.gif]"))
- def testConvertAccents(self):
- self.assertEquals(
- "ça, où est le pré près du
prêt?",
- self.m._ConvertAccents("ça, où est le pré près du prêt?"))
-
def testRigLink(self):
self.m = MockIzuParser(self.Log(),
glob={ "A01234*.jpg": "A01234 My Image.jpg",
@@ -568,19 +568,19 @@
glob={ "A01234*.jpg": "A01234 My Image.jpg"
},
rig_base=None,
img_gen_script=None)
- tags, sections = self.m.RenderStringToHtml("[s:images]",
encoding=None) #@UnusedVariable
+ tags, sections = self.m.RenderStringToHtml("[s:images]")
#@UnusedVariable
self.assertEquals(None, sections.get("en", None))
self.assertEquals(None, sections.get("fr", None))
self.assertEquals([], sections.get("images", None))
# Ignore invalid tags
- tags, sections = self.m.RenderStringToHtml("[s:images]line 1\nline
2\n[not a rigimg tag]", encoding=None) #@UnusedVariable
+ tags, sections = self.m.RenderStringToHtml("[s:images]line 1\nline
2\n[not a rigimg tag]") #@UnusedVariable
self.assertEquals(None, sections.get("en", None))
self.assertEquals(None, sections.get("fr", None))
self.assertEquals([], sections.get("images", None))
# full tag with name, size and glob
- tags, sections = self.m.RenderStringToHtml("[s:images][This is &
comment|rigimg:256:A01234*.jpg] ignore the rest", encoding=None)
#@UnusedVariable
+ tags, sections = self.m.RenderStringToHtml("[s:images][This is &
comment|rigimg:256:A01234*.jpg] ignore the rest") #@UnusedVariable
self.assertListEquals(
[ '[[if rig_base]]<img title="This is & comment" '
'src="[[raw rig_thumb_url % '
=======================================
--- /trunk/rig3serv/src/tests/template/test_template.py Wed Sep 2 21:57:04
2009
+++ /trunk/rig3serv/src/tests/template/test_template.py Tue Sep 7 00:27:42
2010
@@ -106,6 +106,24 @@
b = Buffer("file", "[[tag")
self.assertRaises(SyntaxError, m._GetNextNode, b)
+ def testGetNextNode_Escape(self):
+ m = MockParse(self.Log(), source="")
+
+ # [[raw expr]] is escaped with an extra [, so it transformed into a
+ # literal rather than a tag.
+ b = Buffer("file", "[[[raw expr]]")
+ self.assertEquals(NodeLiteral("[[raw expr]]"), m._GetNextNode(b))
+
+ # We can have as many levels of [[[[, only N-1 are generated in
output.
+ # However the [[[... part still generates its own literal.
+ b = Buffer("file", "some [[[[[[blah foo bar]] thing")
+ self.assertEquals(NodeLiteral("some "), m._GetNextNode(b))
+ self.assertEquals(NodeLiteral("[[[[[blah foo bar]] thing"),
m._GetNextNode(b))
+
+ # Since the escaped tag is a literal, it doesn't have to be closed
properly
+ b = Buffer("file", "[[[[tag")
+ self.assertEquals(NodeLiteral("[[[tag"), m._GetNextNode(b))
+
def testGetNextNode_Tags(self):
m = MockParse(self.Log(), source="")
t = m._tags["tag"] = _TagTag()
=======================================
--- /trunk/rig3serv/src/tests/z_last/render_testdata.py Wed Sep 2 21:57:04
2009
+++ /trunk/rig3serv/src/tests/z_last/render_testdata.py Tue Sep 7 00:27:42
2010
@@ -28,7 +28,7 @@
along with this program. If not, see <
http://www.gnu.org/licenses/>.
"""
-__author__ = "ralfoide at gmail com"
+__author__ = "ralfoide gmail com"
import os
=======================================
--- /trunk/rig3serv/src/tests/z_last/test_rig3_live.py Sat Feb 13 23:14:18
2010
+++ /trunk/rig3serv/src/tests/z_last/test_rig3_live.py Tue Sep 7 00:27:42
2010
@@ -85,16 +85,16 @@
self.assertSearch(r'Rig link: <a title="This is a rig link"
href="
http://rig.base.url.alfray.com/photos1/index.php\?album=2007-10-07_Folder%201&img=T12896_tiny_jpeg.jpg">This
is a rig link</a>',
index_izu)
# file items which use the file name as title should loose their
extension
- self.assertHtmlSearch('<td class="title">\s*<a
name="Izu-File-Item" title="Permalink to \'Izu File Item\'"><a
href="cat/bar/post_2007-09-09_Izu-File-Item.html" title="Permalink to \'Izu
File Item\'"><span class="date">2007/09/09</span>Izu File
Item</a></a></td></tr>',
+ self.assertHtmlSearch('<td class="title">\s*<a
name="izu-file-item" title="Permalink to \'Izu File Item\'"><a
href="cat/bar/post_2007-09-09_izu-file-item.html" title="Permalink to \'Izu
File Item\'"><span class="date">2007/09/09</span>Izu File
Item</a></a></td></tr>',
index_izu)
# sub-directories are parsed for file items too
- self.assertHtmlSearch('<td class="title">\s*<a
name="Sub-File-Item" title="Permalink to \'Sub File Item\'"><a
href="cat/bar/post_2008-01-02_Sub-File-Item.html" title="Permalink to \'Sub
File Item\'"><span class="date">2008/01/02</span>Sub File
Item</a></a></td></tr>',
+ self.assertHtmlSearch('<td class="title">\s*<a
name="sub-file-item" title="Permalink to \'Sub File Item\'"><a
href="cat/bar/post_2008-01-02_sub-file-item.html" title="Permalink to \'Sub
File Item\'"><span class="date">2008/01/02</span>Sub File
Item</a></a></td></tr>',
index_izu)
# posts with no tags/categories are accepted
- self.assertHtmlSearch('<td class="title">\s*<a name="No-Tags"
title="Permalink to \'No Tags\'"><a href="post_2007-10-02_No-Tags.html"
title="Permalink to \'No Tags\'"><span class="date">2007/10/02</span>No
Tags</a></a></td></tr>',
+ self.assertHtmlSearch('<td class="title">\s*<a name="no-tags"
title="Permalink to \'No Tags\'"><a href="post_2007-10-02_no-tags.html"
title="Permalink to \'No Tags\'"><span class="date">2007/10/02</span>No
Tags</a></a></td></tr>',
index_izu)
# empty posts are accepted
- self.assertHtmlSearch('<td class="title">\s*<a name="Empty-Post"
title="Permalink to \'Empty Post\'"><a
href="post_2007-10-01_Empty-Post.html" title="Permalink to \'Empty
Post\'"><span class="date">2007/10/01</span>Empty Post</a></a></td></tr>',
+ self.assertHtmlSearch('<td class="title">\s*<a name="empty-post"
title="Permalink to \'Empty Post\'"><a
href="post_2007-10-01_empty-post.html" title="Permalink to \'Empty
Post\'"><span class="date">2007/10/01</span>Empty Post</a></a></td></tr>',
index_izu)
# the live test site has sharing enabled (default is off)
self.assertHtmlSearch('href="
http://www.facebook.com/sharer.php\?u=http://www.example.alfray.com/cat/videos/post_',
=======================================
--- /trunk/rig3serv/testdata/album/blog2/2007-10-07 11.00_Folder
2/index.izu Sun Mar 22 22:15:48 2009
+++ /trunk/rig3serv/testdata/album/blog2/2007-10-07 11.00_Folder
2/index.izu Tue Sep 7 00:27:42 2010
@@ -11,6 +11,11 @@
___underline___ '''single quotes''' ===equals===
+
+Cross-linking:
+* [To folder 1 in same category|#s:20071007:Folder 1]
+* [To folder 1 in another category|/bar#s:20071007:Folder 1]
+
[s:images]
[Image 2 @ 128|rigimg:128:T*tiny2.jpg]
[Image 1 @ 96 |rigimg:96:T*tiny1.jpg]
=======================================
--- /trunk/rig3serv/testdata/templates/default/html_entry.html Sun Jun 22
14:57:24 2008
+++ /trunk/rig3serv/testdata/templates/default/html_entry.html Tue Sep 7
00:27:42 2010
@@ -9,7 +9,7 @@
- title: string, title of the entry
- tags: dict{string tag: string value}, the parsed Izu tags.
- sections: dict{string name: string content}, the HTML for the various
sections.
- - Expected sections names: html (old html), en, fr and images.
+ - Expected sections names: html (old html), en, fr and images.
- rel_base_url: string, Relative url to base of site. May be empty or
like ../../
- permalink: string, the permalink URL relative to the base URL
]]