changeset 464:328f45d3937e

macro.DataRevPlot: macro to graph data by svgfig extracted from revisions of the page where it is called from
author Reimar Bauer <rb.proj AT googlemail DOT com>
date Wed, 16 Dec 2009 19:39:54 +0100
parents 959817d46551
children fc9cdf513432
files data/plugin/macro/DataRevPlot.py
diffstat 1 files changed, 133 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/data/plugin/macro/DataRevPlot.py	Wed Dec 16 19:39:54 2009 +0100
@@ -0,0 +1,133 @@
+# -*- coding: iso-8859-1 -*-
+"""
+    MoinMoin - DataRevPlot Macro
+
+    This macro is a used to graph by
+    http://code.google.com/p/svgfig/
+    data of all revisions from a table
+    on the page where it is called from.
+
+    @copyright: 2009 MoinMoin:ReimarBauer
+    @license: GNU GPL, see COPYING for details.
+"""
+import re, svgfig
+from MoinMoin import wikiutil
+from MoinMoin.Page import Page
+from MoinMoin.action import cache
+
+# svg frame sizes
+svgfig._canvas_defaults["width"] = '400px'
+svgfig._canvas_defaults["height"] = '400px'
+
+
+class DictBase(dict):
+    """ Base class for wiki dicts
+
+    To use this class, subclass it and override regex and initFromText.
+
+    @copyright: 2003-2007 MoinMoin:ThomasWaldmann,
+                2003 by Gustavo Niemeyer
+    """
+    def __init__(self, request=None, pagename=None, rev=0):
+        dict.__init__(self)
+        self.name = None
+        if request is not None and pagename is not None:
+            self.loadFromPage(request, pagename, rev=rev)
+
+    # Regular expression used to parse text - subclass must override this
+    regex = None  # re.compile(u'...', re.MULTILINE | re.UNICODE)
+
+    def loadFromPage(self, request, name, rev=0):
+        """ load the dict from wiki page <name>'s content """
+        self.name = name
+        text = Page(request, name, rev=rev).get_raw_body()
+        self.initFromText(text)
+
+    def initFromText(self, text):
+        """ parse the wiki page text and init the dict from it """
+        raise NotImplementedError('subclasses should override this')
+
+class Dict(DictBase):
+    """ Mapping of keys to values from a wiki page.
+
+    = Tue Dec 15 23:30:01 CET 2009 =
+    ||<tableclass="sortable" bgcolor="#cccccc"> order || GB || user || graph||
+    ||<bgcolor="#cccccc"> 1 || 70 || usera || <<SvgWsStats(parameter=usera)>> ||
+    ||<bgcolor="#cccccc"> 2 || 10 || userb || <<SvgWsStats(parameter=userb)>> ||
+
+    @copyright: 2003-2007 MoinMoin:ThomasWaldmann,
+                2003 by Gustavo Niemeyer
+                2009 by MoinMoin:ReimarBauer
+    """
+    # only data from the table line is extracted
+    regex = re.compile(ur'\|\| (?P<value>\w*?) \|\| (?P<key>\w*?)\s|$',
+                       re.MULTILINE | re.UNICODE)
+
+    def initFromText(self, text):
+        for match in self.regex.finditer(text):
+            value, key = match.groups()
+            self[key] = value
+
+    def __repr__(self):
+        return "<Dict name=%r items=%r>" % (self.name, self.items())
+
+Dependencies = ['page']
+
+def macro_DataRevPlot(macro,
+                      width=u'50px',
+                      height=u'50px',
+                      parameter=u'username'
+                     ):
+
+    request = macro.request
+    pagename = request.page.page_name
+    content_type = 'image/svg+xml'
+    current_rev = Page(request, pagename).current_rev()
+    rev_list = range(current_rev)
+    rev_list.reverse()
+
+    # data
+    y = []
+    for rev in rev_list:
+        try:
+            page_dict = Dict(request, pagename, rev=rev)
+            y.append(float(page_dict[parameter].split()[0]))
+        except:
+            pass
+
+    x = range(len(y))
+    if current_rev < 10:
+        xrange = (0, 10)
+    else:
+        xrange = (0, max(x))
+    points1 = svgfig.Dots(zip(x, y),
+              svgfig.make_symbol("data1", stroke="black", fill="red",
+                                 stroke_width="0.25pt"))
+    # define scientific plot 
+    svgfig.Frame.text_ytitle_offset = 16
+    myFrame = svgfig.Frame(xrange[0], xrange[1], 0, max(y) + 0.05 * max(y),
+                           points1, xtitle='days (%d = today)' % len(y),
+                           ytitle=parameter).SVG()
+    # create complete svg xml 
+    data = myFrame.standalone_xml()
+    # create key
+    key = cache.key(request, itemname=pagename, content=data)
+    size_str = "%s_%s" % (svgfig._canvas_defaults["width"].replace('px', ''),
+                          svgfig._canvas_defaults["height"].replace('px', ''))
+    key = '%s_%s_%s' % (wikiutil.escape(content_type.replace('/', '_')),
+                        size_str, key)
+    # check caching status
+    if not cache.exists(request, key):
+        cache.put(request, key, data, content_type=content_type)
+    # create url to cache file
+    url = "%s%s%s" % (request.getQualifiedURL(),
+          Page(request, pagename).url(request), cache.url(request, key))
+    from MoinMoin import macro
+    from MoinMoin.parser.text import Parser
+    macro.request = request
+    macro.formatter = request.html_formatter
+    p = Parser("##\n", request)
+    m = macro.Macro(p)
+    return m.execute('EmbedObject',
+          u'width=%s, height=%s, target=%s, url_mimetype=%s' % (
+          width, height, url, content_type))