Skip to content

Commit

Permalink
Implemented all logging directives.
Browse files Browse the repository at this point in the history
  • Loading branch information
strichter committed Dec 21, 2012
1 parent 902a918 commit 4ee7767
Show file tree
Hide file tree
Showing 9 changed files with 212 additions and 14 deletions.
2 changes: 2 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ CHANGES

- Added ``pageLayout`` and ``pageMode`` to ``docInit`` directive.

- Implemented all logging related directives.

- Don't show "doc" namespace in reference snippets.

- Create a list of RML2PDF and z3c.rml differences.
Expand Down
14 changes: 0 additions & 14 deletions RML-DIFFERENCES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -115,19 +115,5 @@ naming.

- length

- log

- debug

- info

- warning

- error

- critical

- logConfig

- -pdfInclude

4 changes: 4 additions & 0 deletions src/z3c/rml/attr.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,10 @@ def __init__(self, choices=None, doLower=True, *args, **kw):
if isinstance(choices, (tuple, list)):
choices = dict(
[(val.lower() if doLower else val, val) for val in choices])
else:
choices = dict(
[(key.lower() if doLower else key, val)
for key, val in choices.items()])
self.choices = choices
self.doLower = doLower

Expand Down
54 changes: 54 additions & 0 deletions src/z3c/rml/document.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"""
__docformat__ = "reStructuredText"
import cStringIO
import logging
import sys
import zope.interface
import reportlab.pdfgen.canvas
Expand All @@ -28,6 +29,7 @@
from z3c.rml import occurence, pdfinclude, special, storyplace, stylesheet
from z3c.rml import template

LOGGER_NAME = 'z3c.rml.render'

class IRegisterType1Face(interfaces.IRMLDirectiveSignature):
"""Register a new Type 1 font face."""
Expand Down Expand Up @@ -349,6 +351,55 @@ def process(self):
setattr(cmp, name, value)
self.parent.parent.cropMarks = cmp

class ILogConfig(interfaces.IRMLDirectiveSignature):
"""Configure the render logger."""

level = attr.Choice(
title=u'Level',
description=u'The default log level.',
choices=interfaces.LOG_LEVELS,
doLower=False,
required=False)

format = attr.String(
title=u'Format',
description=u'The format of the log messages.',
required=False)

filename = attr.File(
title=u'File Name',
description=u'The path to the file that is being logged.',
doNotOpen=True,
required=True)

filemode = attr.Choice(
title=u'File Mode',
description=u'The mode to open the file in.',
choices={'WRITE': 'w', 'APPEND': 'a'},
default='a',
required=False)

datefmt = attr.String(
title=u'Date Format',
description=u'The format of the log message date.',
required=False)

class LogConfig(directive.RMLDirective):
signature = ILogConfig

def process(self):
args = dict(self.getAttributeValues())
logger = logging.Logger(LOGGER_NAME)
handler = logging.FileHandler(args['filename'], args['filemode'])
formatter = logging.Formatter(
args.get('format'), args.get('datefmt'))
handler.setFormatter(formatter)
logger.addHandler(handler)
if 'level' in args:
logger.setLevel(args['level'])
self.parent.parent.logger = logger


class IDocInit(interfaces.IRMLDirectiveSignature):
occurence.containing(
occurence.ZeroOrMore('color', IColorDefinition),
Expand All @@ -359,6 +410,7 @@ class IDocInit(interfaces.IRMLDirectiveSignature):
occurence.ZeroOrMore('registerTTFont', IRegisterTTFont),
occurence.ZeroOrMore('registerFontFamily', IRegisterFontFamily),
occurence.ZeroOrMore('addMapping', IAddMapping),
occurence.ZeroOrMore('logConfig', ILogConfig),
occurence.ZeroOrMore('cropMarks', ICropMarks),
occurence.ZeroOrMore('startIndex', IStartIndex),
)
Expand Down Expand Up @@ -393,6 +445,7 @@ class DocInit(directive.RMLDirective):
'registerTTFont': RegisterTTFont,
'registerCidFont': RegisterCidFont,
'addMapping': AddMapping,
'logConfig': LogConfig,
'cropMarks': CropMarks,
'startIndex': StartIndex,
}
Expand Down Expand Up @@ -465,6 +518,7 @@ def __init__(self, element):
self.cropMarks = False
self.pageLayout = None
self.pageMode = None
self.logger = None

def _indexAdd(self, canvas, name, label):
self.indexes[name](canvas, name, label)
Expand Down
103 changes: 103 additions & 0 deletions src/z3c/rml/flowable.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"""
__docformat__ = "reStructuredText"
import copy
import logging
import re
import reportlab.lib.styles
import reportlab.platypus
Expand Down Expand Up @@ -1333,6 +1334,95 @@ def process(self):
self.parent.flow.append(index)


class IBaseLogCall(interfaces.IRMLDirectiveSignature):

message = attr.RawXMLContent(
title=u'Message',
description=u'The message to be logged.',
required=True)

class LogCallFlowable(reportlab.platypus.flowables.Flowable):

def __init__(self, logger, level, message):
self.logger = logger
self.level = level
self.message = message

def wrap(self, *args):
return (0, 0)

def draw(self):
self.logger.log(self.level, self.message)

class BaseLogCall(directive.RMLDirective):
signature = IBaseLogCall
level = None

def process(self):
message = self.getAttributeValues(
select=('message',), valuesOnly=True)[0]
manager = attr.getManager(self)
self.parent.flow.append(
LogCallFlowable(manager.logger, self.level, message))

class ILog(IBaseLogCall):
"""Log message at DEBUG level."""

level = attr.Choice(
title=u'Level',
description=u'The default log level.',
choices=interfaces.LOG_LEVELS,
doLower=False,
default=logging.INFO,
required=True)

class Log(BaseLogCall):
signature = ILog

@property
def level(self):
return self.getAttributeValues(select=('level',), valuesOnly=True)[0]

class IDebug(IBaseLogCall):
"""Log message at DEBUG level."""

class Debug(BaseLogCall):
signature = IDebug
level = logging.DEBUG


class IInfo(IBaseLogCall):
"""Log message at INFO level."""

class Info(BaseLogCall):
signature = IInfo
level = logging.INFO


class IWarning(IBaseLogCall):
"""Log message at WARNING level."""

class Warning(BaseLogCall):
signature = IWarning
level = logging.WARNING


class IError(IBaseLogCall):
"""Log message at ERROR level."""

class Error(BaseLogCall):
signature = IError
level = logging.ERROR


class ICritical(IBaseLogCall):
"""Log message at CRITICAL level."""

class Critical(BaseLogCall):
signature = ICritical
level = logging.CRITICAL


class IFlow(interfaces.IRMLDirectiveSignature):
"""A list of flowables."""
occurence.containing(
Expand Down Expand Up @@ -1372,6 +1462,12 @@ class IFlow(interfaces.IRMLDirectiveSignature):
occurence.ZeroOrMore('showIndex', IShowIndex),
occurence.ZeroOrMore('name', special.IName),
occurence.ZeroOrMore('namedString', INamedString),
occurence.ZeroOrMore('log', ILog),
occurence.ZeroOrMore('debug', IDebug),
occurence.ZeroOrMore('info', IInfo),
occurence.ZeroOrMore('warning', IWarning),
occurence.ZeroOrMore('error', IError),
occurence.ZeroOrMore('critical', ICritical),
)

class Flow(directive.RMLDirective):
Expand Down Expand Up @@ -1418,6 +1514,13 @@ class Flow(directive.RMLDirective):
# Special Elements
'name': special.Name,
'namedString': NamedString,
# Logging
'log': Log,
'debug': Debug,
'info': Info,
'warning': Warning,
'error': Error,
'critical': Critical,
}

def __init__(self, *args, **kw):
Expand Down
7 changes: 7 additions & 0 deletions src/z3c/rml/interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"""RML to PDF Converter Interfaces
"""
__docformat__ = "reStructuredText"
import logging
import reportlab.lib.enums
import zope.interface
import zope.schema
Expand All @@ -38,6 +39,12 @@
LIST_FORMATS = ('I', 'i', '123', 'ABC', 'abc')
ORDERED_LIST_TYPES = ('I', 'i', '1', 'A', 'a')
UNORDERED_BULLET_VALUES = ('circle', 'square', 'disc', 'diamond', 'rarrowhead')
LOG_LEVELS = {
'DEBUG': logging.DEBUG,
'INFO': logging.INFO,
'WARNING': logging.WARNING,
'ERROR': logging.ERROR,
'CRITICAL': logging.CRITICAL}

class IRML2PDF(zope.interface.Interface):
"""This is the main public API of z3c.rml"""
Expand Down
Binary file added src/z3c/rml/tests/expected/tag-log.pdf
Binary file not shown.
39 changes: 39 additions & 0 deletions src/z3c/rml/tests/input/tag-log.rml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="iso-8859-1" standalone="no"?>
<!DOCTYPE document SYSTEM "rml.dtd">

<document
filename="tag-log.pdf"
xmlns:doc="http://namespaces.zope.org/rml/doc">
<docinit>
<logConfig
level="DEBUG"
format="%(asctime)s %(levelname)s - %(message)s"
datefmt="%Y-%m-%dT%H:%M:%S"
filename="[z3c.rml.tests]/render.log"
filemode="APPEND"
doc:example=""
/>
</docinit>
<template>
<pageTemplate id="main">
<frame id="first" x1="1cm" y1="1cm" width="19cm" height="26cm"/>

<pageGraphics>
<place x="0.5cm" y="0.5cm" width="10cm" height="1cm">
<para>Page <pageNumber /></para>
</place>
</pageGraphics>

</pageTemplate>
</template>
<story>
<title>Logging Example</title>

<log level="WARNING" doc:example="">Log message with level WARNING.</log>
<debug doc:example="">A DEBUG message</debug>
<info doc:example="">A INFO message</info>
<warning doc:example="">A WARNING message</warning>
<error doc:example="">A ERROR message</error>
<critical doc:example="">A CRITICAL message</critical>
</story>
</document>
3 changes: 3 additions & 0 deletions src/z3c/rml/tests/test_rml.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ def tearDown(self):
attr.File.open = self._fileOpen
del sys.modules['module']
del sys.modules['mymodule']
os.remove(
os.path.join(os.path.dirname(__file__), 'render.log'))


def runTest(self):
rml2pdf.go(self._inPath, self._outPath)
Expand Down

0 comments on commit 4ee7767

Please sign in to comment.