Source code for jotting.to
import os
import sys
from copy import deepcopy
from functools import wraps
from .style import Raw
[docs]def outlet(handler):
"""Turn a function into an :class:`Outlet`.
This decorator should wrap functions that send logs wherever they need to go.
Parameters
----------
handler : callable
A function of the form ``(log, *args, **kwargs)``, where ``log`` is a
log generated by a user, and ``*args, **kwargs`` are the parameters that
initialize the outlet (e.g. ``File(path=/path/to/file)``).
"""
method = staticmethod(handler)
cls = type(handler.__name__, (Outlet,), {"_handler": method})
return cls
[docs]class Outlet(object):
"""A base :class:`Outlet` class.
Subclasses should override the :meth:`_handler` method.
Parameters
----------
style : callable
A function that returns a formated log string. This is usually a
:class:`jotting.to.Style` object that returns a string.
*args : any
Positional arguments passed to :meth:`Outlet._handler` - a method
meant to be overriden in subclasses. You can use :func:`outlet` to
turn functions into an :class:`Outlets` whose handler is that function.
**kwargs : any
Keyword arguments passed to :meth:`Outlet._handler` - a method
meant to be overriden in subclasses. You can use :func:`outlet` to
turn functions into an :class:`Outlets` whose handler is that
function.
"""
def __init__(self, style=Raw(), *args, **kwargs):
self._style = style
self._args = args
self._kwargs = kwargs
def __call__(self, log):
if self._style is not None:
log = self._style(log)
if log is not None:
if not isinstance(log, str):
raise TypeError("Expected a string, not %r" % log)
self._handler(log, *self._args, **self._kwargs)
def _handler(self, log, *args, **kwargs):
"""Send logs wherever they need to go.
This should be overriden in a subclasses.
Parameters
----------
log : str
A formated log string.
*args : any
Positional arguments used to initialize the Outlet.
**kwargs : any
Keyword arguments used to initialize the Outlet.
"""
raise NotImplementedError()
@outlet
def File(log, path):
"""Send logs to a file.
Each new log is appended in a new line to the given file.
Parameters
----------
path : string
The place you'd like your logs to reside.
"""
path = os.path.realpath(os.path.expanduser(path))
with open(path, "a+") as f:
f.write(log)
@outlet
def Print(log):
"""Send logs directly to ``sys.stdout``"""
sys.stdout.write(log)
sys.stdout.flush()