From 96f41658e31a7db326daf197be9c3ec89f191140 Mon Sep 17 00:00:00 2001 From: Richard Darst Date: Tue, 22 Sep 2009 18:30:39 +0000 Subject: Add templaning necessary for the soon-to-be genshi templating - This adds .get_template method on the _BaseWriter which gives a big data structure object that can be used with genshi templates to write custom HTML. - Template writer added - place to add the new writer code. - For information on how this works, search for these two names in the code and read the comments in them. darcs-hash:20090922183039-82ea9-c403d1e748e13ee79afc8dbdf7f8ee286000797a.gz --- diff --git a/items.py b/items.py index 187ab58..7463585 100644 --- a/items.py +++ b/items.py @@ -66,17 +66,31 @@ class _BaseItem(object): endtext = '' startmw = '' endmw = '' - def get_replacements(self, escapewith): + def get_replacements(self, M, escapewith): replacements = { } for name in dir(self): if name[0] == "_": continue replacements[name] = getattr(self, name) replacements['nick'] = escapewith(replacements['nick']) + replacements['link'] = self.logURL(M) if 'line' in replacements: replacements['line'] = escapewith(replacements['line']) if 'topic' in replacements: replacements['topic'] = escapewith(replacements['topic']) + if 'url' in replacements: + replacements['url_quoteescaped'] = \ + escapewith(self.url.replace('"', "%22")) + return replacements + def template(self, M, escapewith): + template = { } + for k,v in self.get_replacements(M, escapewith).iteritems(): + if k not in ('itemtype', 'line', 'topic', + 'url', 'url_quoteescaped', + 'nick', 'time', 'link', 'anchor'): + continue + template[k] = v + return template def makeRSTref(self, M): if self.nick[-1] == '_': rstref = rstref_orig = "%s%s"%(self.nick, self.time) @@ -121,7 +135,7 @@ class Topic(_BaseItem): self.nick = nick ; self.topic = line ; self.linenum = linenum self.time = time.strftime("%H:%M:%S", time_) def _htmlrepl(self, M): - repl = self.get_replacements(escapewith=writers.html) + repl = self.get_replacements(M, escapewith=writers.html) repl['link'] = self.logURL(M) return repl def html(self, M): @@ -130,16 +144,16 @@ class Topic(_BaseItem): return self.html2_template%self._htmlrepl(M) def rst(self, M): self.rstref = self.makeRSTref(M) - repl = self.get_replacements(escapewith=writers.rst) + repl = self.get_replacements(M, escapewith=writers.rst) if repl['topic']=='': repl['topic']=' ' repl['link'] = self.logURL(M) return self.rst_template%repl def text(self, M): - repl = self.get_replacements(escapewith=writers.text) + repl = self.get_replacements(M, escapewith=writers.text) repl['link'] = self.logURL(M) return self.text_template%repl def mw(self, M): - repl = self.get_replacements(escapewith=writers.mw) + repl = self.get_replacements(M, escapewith=writers.mw) return self.mw_template%repl class GenericItem(_BaseItem): @@ -163,7 +177,7 @@ class GenericItem(_BaseItem): self.nick = nick ; self.line = line ; self.linenum = linenum self.time = time.strftime("%H:%M:%S", time_) def _htmlrepl(self, M): - repl = self.get_replacements(escapewith=writers.html) + repl = self.get_replacements(M, escapewith=writers.html) repl['link'] = self.logURL(M) return repl def html(self, M): @@ -172,15 +186,15 @@ class GenericItem(_BaseItem): return self.html2_template%self._htmlrepl(M) def rst(self, M): self.rstref = self.makeRSTref(M) - repl = self.get_replacements(escapewith=writers.rst) + repl = self.get_replacements(M, escapewith=writers.rst) repl['link'] = self.logURL(M) return self.rst_template%repl def text(self, M): - repl = self.get_replacements(escapewith=writers.text) + repl = self.get_replacements(M, escapewith=writers.text) repl['link'] = self.logURL(M) return self.text_template%repl def mw(self, M): - repl = self.get_replacements(escapewith=writers.mw) + repl = self.get_replacements(M, escapewith=writers.mw) return self.mw_template%repl @@ -237,7 +251,7 @@ class Link(_BaseItem): self.url = self.url self.line = self.line.strip() def _htmlrepl(self, M): - repl = self.get_replacements(escapewith=writers.html) + repl = self.get_replacements(M, escapewith=writers.html) # special: replace doublequote only for the URL. repl['url'] = writers.html(self.url.replace('"', "%22")) repl['url_readable'] = writers.html(self.url) @@ -249,14 +263,14 @@ class Link(_BaseItem): return self.html2_template%self._htmlrepl(M) def rst(self, M): self.rstref = self.makeRSTref(M) - repl = self.get_replacements(escapewith=writers.rst) + repl = self.get_replacements(M, escapewith=writers.rst) repl['link'] = self.logURL(M) #repl['url'] = writers.rst(self.url) return self.rst_template%repl def text(self, M): - repl = self.get_replacements(escapewith=writers.text) + repl = self.get_replacements(M, escapewith=writers.text) repl['link'] = self.logURL(M) return self.text_template%repl def mw(self, M): - repl = self.get_replacements(escapewith=writers.mw) + repl = self.get_replacements(M, escapewith=writers.mw) return self.mw_template%repl diff --git a/writers.py b/writers.py index 66af538..2423063 100644 --- a/writers.py +++ b/writers.py @@ -132,6 +132,130 @@ class _BaseWriter(object): if getattr(m, 'assigned', False): continue yield m + def get_template(self, escape=lambda s: s): + M = self.M + repl = self.replacements() + + + MeetingItems = [ ] + # We can have initial items with NO initial topic. This + # messes up the templating, so, have this null topic as a + # stopgap measure. + nextTopic = {'topic':{'itemtype':'TOPIC', 'topic':'Prologue', + 'nick':'', + 'time':'', 'link':'', 'anchor':''}, + 'items':[] } + haveTopic = False + for m in M.minutes: + if m.itemtype == "TOPIC": + if nextTopic['topic']['nick'] or nextTopic['items']: + MeetingItems.append(nextTopic) + nextTopic = {'topic':m.template(M, escape), 'items':[] } + haveTopic = True + else: + nextTopic['items'].append(m.template(M, escape)) + MeetingItems.append(nextTopic) + repl['MeetingItems'] = MeetingItems + # Format of MeetingItems: + # [ {'topic': {item_dict}, + # 'items': [item_dict, item_object, item_object, ...] + # }, + # { 'topic':... + # 'items':... + # }, + # .... + # ] + # + # an item_dict has: + # item_dict = {'itemtype': TOPIC, ACTION, IDEA, or so on... + # 'line': the actual line that was said + # 'nick': nick of who said the line + # 'time': 10:53:15, for example, the time + # 'link': ${link}#${anchor} is the URL to link to. + # (page name, and bookmark) + # 'anchor': see above + # 'topic': if itemtype is TOPIC, 'line' is not given, + # instead we have 'topic' + # 'url': if itemtype is LINK, the line should be created + # by "${link} ${line}", where 'link' is the URL + # to link to, and 'line' is the rest of the line + # (that isn't a URL) + # 'url_quoteescaped': 'url' but with " escaped for use in + # + ActionItems = [ ] + for m in M.minutes: + if m.itemtype != "ACTION": continue + ActionItems.append(escape(m.line)) + repl['ActionItems'] = ActionItems + # Format of ActionItems: It's just a very simple list of lines. + # [line, line, line, ...] + # line = (string of what it is) + + + ActionItemsPerson = [ ] + numberAssigned = 0 + for nick, items in self.iterActionItemsNick(): + thisNick = {'nick':escape(nick), 'items':[ ] } + for m in items: + numberAssigned += 1 + thisNick['items'].append(escape(m.line)) + if len(thisNick['items']) > 0: + ActionItemsPerson.append(thisNick) + # Work on the unassigned nicks. + thisNick = {'nick':'UNASSIGNED', 'items':[ ] } + for m in self.iterActionItemsUnassigned(): + thisNick['items'].append(escape(m.line)) + if len(thisNick['items']) > 1: + ActionItemsPerson.append(thisNick) + if numberAssigned == 0: + ActionItemsPerson = None + repl['ActionItemsPerson'] = ActionItemsPerson + # Format of ActionItemsPerson + # ActionItemsPerson = + # [ {'nick':nick_of_person, + # 'items': [item1, item2, item3, ...], + # }, + # ..., + # ..., + # {'nick':'UNASSIGNED', + # 'items': [item1, item2, item3, ...], + # } + # ] + + + PeoplePresent = [] + # sort by number of lines spoken + for nick, count in self.iterNickCounts(): + PeoplePresent.append({'nick':escape(nick), + 'count':count}) + repl['PeoplePresent'] = PeoplePresent + # Format of PeoplePresent + # [{'nick':the_nick, 'count':count_of_lines_said}, + # ..., + # ..., + # ] + + + + +class Template(_BaseWriter): + + def format(self, extension=None): + repl = self.get_template() + + # Uncomment this line to interactively play with the "repl" + # replacements object, for debugging purposes + #from code import interact ; interact(local=locals()) + + + # Add all the genshi code here + + + return '' # This should return the final string to write + + + + class _CSSmanager(object): _css_head = textwrap.dedent('''\