Commits

Anonymous committed b95ec0f

Added irclog.

Comments (0)

Files changed (43)

irclog/.buildinfo

+# Sphinx build info version 1
+# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
+config: 68fc0b6bd2362839916698c6f5ddcdd7
+tags: fbb0d17656682115ca4d033fb2f83ba1

irclog/_modules/index.html

+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    
+    <title>Overview: module code &mdash; irclog v0.1 documentation</title>
+    <link rel="stylesheet" href="../_static/mezzanine.css" type="text/css" />
+    <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:    '../',
+        VERSION:     '0.1',
+        COLLAPSE_INDEX: false,
+        FILE_SUFFIX: '.html',
+        HAS_SOURCE:  true
+      };
+    </script>
+    <script type="text/javascript" src="../_static/jquery.js"></script>
+    <script type="text/javascript" src="../_static/underscore.js"></script>
+    <script type="text/javascript" src="../_static/doctools.js"></script>
+    <link rel="top" title="irclog v0.1 documentation" href="../index.html" /> 
+  </head>
+  <body>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="../genindex.html" title="General Index"
+             accesskey="I">index</a></li>
+        <li class="right" >
+          <a href="../py-modindex.html" title="Python Module Index"
+             >modules</a> |</li>
+        <li><a href="../index.html">irclog v0.1 documentation</a> &raquo;</li> 
+      </ul>
+    </div>  
+
+    <div class="document">
+      <div class="documentwrapper">
+        <div class="bodywrapper">
+          <div class="body">
+            
+  <h1>All modules for which code is available</h1>
+<ul><li><a href="irclog/archive.html">irclog.archive</a></li>
+<li><a href="irclog/messages.html">irclog.messages</a></li>
+<li><a href="irclog/parser.html">irclog.parser</a></li>
+<li><a href="irclog/tests.html">irclog.tests</a></li>
+<li><a href="irclog/web.html">irclog.web</a></li>
+<ul><li><a href="irclog/web/server.html">irclog.web.server</a></li>
+</ul></ul>
+
+          </div>
+        </div>
+      </div>
+      <div class="sphinxsidebar">
+        <div class="sphinxsidebarwrapper">
+<div id="searchbox" style="display: none">
+  <h3>Quick search</h3>
+    <form class="search" action="../search.html" method="get">
+      <input type="text" name="q" size="18" />
+      <input type="submit" value="Go" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    <p class="searchtip" style="font-size: 90%">
+    Enter search terms or a module, class or function name.
+    </p>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+        </div>
+      </div>
+      <div class="clearer"></div>
+    </div>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="../genindex.html" title="General Index"
+             >index</a></li>
+        <li class="right" >
+          <a href="../py-modindex.html" title="Python Module Index"
+             >modules</a> |</li>
+        <li><a href="../index.html">irclog v0.1 documentation</a> &raquo;</li> 
+      </ul>
+    </div>
+
+    <div class="footer">
+        &copy; Copyright 2010, Hong MinHee.
+      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.3.
+    </div>
+<script type="text/javascript">
+
+  var _gaq = _gaq || [];
+  _gaq.push(['_setAccount', 'UA-52596-12']);
+  _gaq.push(['_trackPageview']);
+
+  (function() {
+    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+  })();
+
+</script>
+
+  </body>
+</html>

irclog/_modules/irclog/archive.html

+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    
+    <title>irclog.archive &mdash; irclog v0.1 documentation</title>
+    <link rel="stylesheet" href="../../_static/mezzanine.css" type="text/css" />
+    <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:    '../../',
+        VERSION:     '0.1',
+        COLLAPSE_INDEX: false,
+        FILE_SUFFIX: '.html',
+        HAS_SOURCE:  true
+      };
+    </script>
+    <script type="text/javascript" src="../../_static/jquery.js"></script>
+    <script type="text/javascript" src="../../_static/underscore.js"></script>
+    <script type="text/javascript" src="../../_static/doctools.js"></script>
+    <link rel="top" title="irclog v0.1 documentation" href="../../index.html" />
+    <link rel="up" title="Module code" href="../index.html" /> 
+  </head>
+  <body>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="../../genindex.html" title="General Index"
+             accesskey="I">index</a></li>
+        <li class="right" >
+          <a href="../../py-modindex.html" title="Python Module Index"
+             >modules</a> |</li>
+        <li><a href="../../index.html">irclog v0.1 documentation</a> &raquo;</li>
+          <li><a href="../index.html" accesskey="U">Module code</a> &raquo;</li> 
+      </ul>
+    </div>  
+
+    <div class="document">
+      <div class="documentwrapper">
+        <div class="bodywrapper">
+          <div class="body">
+            
+  <h1>Source code for irclog.archive</h1><div class="highlight"><pre>
+<span class="sd">&quot;&quot;&quot;:mod:`irclog.archive` --- IRC log archive</span>
+<span class="sd">~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</span>
+
+<span class="sd">&quot;&quot;&quot;</span>
+<span class="kn">import</span> <span class="nn">re</span>
+
+
+<div class="viewcode-block" id="FilenamePattern"><a class="viewcode-back" href="../../irclog/archive.html#irclog.archive.FilenamePattern">[docs]</a><span class="k">class</span> <span class="nc">FilenamePattern</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+    <span class="sd">&quot;&quot;&quot;The glob-like, but specialized to IRC log files, filename pattern</span>
+<span class="sd">    matcher.</span>
+
+<span class="sd">    .. sourcecode:: pycon</span>
+
+<span class="sd">       &gt;&gt;&gt; pattern = FilenamePattern(&quot;/logs/&lt;server&gt;&quot;</span>
+<span class="sd">       ...                           &quot;/&lt;channel&gt;.&lt;date:%Y-%m-%d&gt;.log&quot;)</span>
+<span class="sd">       &gt;&gt;&gt; pattern.glob_pattern()</span>
+<span class="sd">       &#39;/logs/*/*.[0-9][0-9][0-9][0-9]-[01][0-9]-[0-3][0-9].log&#39;</span>
+<span class="sd">       &gt;&gt;&gt; pattern.glob_pattern(server=&quot;Freenode&quot;)</span>
+<span class="sd">       &#39;/logs/Freenode/*.[0-9][0-9][0-9][0-9]-[01][0-9]-[0-3][0-9].log&#39;</span>
+<span class="sd">       &gt;&gt;&gt; pattern.glob_pattern(channel=&quot;#hongminhee&quot;)</span>
+<span class="sd">       &#39;/logs/*/#hongminhee.[0-9][0-9][0-9][0-9]-[01][0-9]-[0-3][0-9].log&#39;</span>
+<span class="sd">       &gt;&gt;&gt; import datetime</span>
+<span class="sd">       &gt;&gt;&gt; pattern.glob_pattern(date=datetime.date(2010, 8, 4))</span>
+<span class="sd">       &#39;/logs/*/*.2010-08-04.log&#39;</span>
+
+<span class="sd">    .. data:: REPLACER_PATTERN</span>
+
+<span class="sd">       The pattern of replacer e.g. ``&lt;date:%Y-%m-%d&gt;``, ``&lt;channel&gt;``.</span>
+
+<span class="sd">       .. productionlist::</span>
+<span class="sd">          replacer: &quot;&lt;&quot; `name` [ &quot;:&quot; `format` ] &quot;&gt;&quot;</span>
+<span class="sd">          name: /[A-Za-z_]+/</span>
+<span class="sd">          format: /[^&gt;]*/</span>
+
+<span class="sd">    &quot;&quot;&quot;</span>
+
+    <span class="n">REPLACER_PATTERN</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="s">r&quot;&lt;(?P&lt;name&gt;[A-Za-z_]+)&quot;</span>
+                                  <span class="s">r&quot;(?::(?P&lt;format&gt;[^&gt;]*))?&gt;&quot;</span><span class="p">)</span>
+
+    <span class="n">__slots__</span> <span class="o">=</span> <span class="s">&quot;pattern&quot;</span><span class="p">,</span>
+
+    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">pattern</span><span class="p">):</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">pattern</span> <span class="o">=</span> <span class="n">pattern</span>
+
+    <span class="nd">@property</span>
+<div class="viewcode-block" id="FilenamePattern.replacers"><a class="viewcode-back" href="../../irclog/archive.html#irclog.archive.FilenamePattern.replacers">[docs]</a>    <span class="k">def</span> <span class="nf">replacers</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot;The list of replacers.</span>
+
+<span class="sd">        .. sourcecode:: pycon</span>
+
+<span class="sd">           &gt;&gt;&gt; pattern = FilenamePattern(&quot;/logs/&lt;server&gt;&quot;</span>
+<span class="sd">           ...                           &quot;/&lt;channel&gt;.&lt;date:%Y-%m-%d&gt;.log&quot;)</span>
+<span class="sd">           &gt;&gt;&gt; list(pattern.replacers)</span>
+<span class="sd">           [&#39;server&#39;, &#39;channel&#39;, &#39;date&#39;]</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">REPLACER_PATTERN</span><span class="o">.</span><span class="n">finditer</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">pattern</span><span class="p">):</span>
+            <span class="k">yield</span> <span class="n">m</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="s">&quot;name&quot;</span><span class="p">)</span>
+</div>
+    <span class="nd">@property</span>
+<div class="viewcode-block" id="FilenamePattern.replacer_pairs"><a class="viewcode-back" href="../../irclog/archive.html#irclog.archive.FilenamePattern.replacer_pairs">[docs]</a>    <span class="k">def</span> <span class="nf">replacer_pairs</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot;The list of replacers&#39; ``(name, format)``. (For replacers have no</span>
+<span class="sd">        format, ``(name, None)``.)</span>
+
+<span class="sd">        .. sourcecode:: pycon</span>
+
+<span class="sd">           &gt;&gt;&gt; pattern = FilenamePattern(&quot;/logs/&lt;server&gt;&quot;</span>
+<span class="sd">           ...                           &quot;/&lt;channel&gt;.&lt;date:%Y-%m-%d&gt;.log&quot;)</span>
+<span class="sd">           &gt;&gt;&gt; list(pattern.replacer_pairs)</span>
+<span class="sd">           [(&#39;server&#39;, None), (&#39;channel&#39;, None), (&#39;date&#39;, &#39;%Y-%m-%d&#39;)]</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">REPLACER_PATTERN</span><span class="o">.</span><span class="n">finditer</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">pattern</span><span class="p">):</span>
+            <span class="k">yield</span> <span class="n">m</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="s">&quot;name&quot;</span><span class="p">),</span> <span class="n">m</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="s">&quot;format&quot;</span><span class="p">)</span> <span class="ow">or</span> <span class="bp">None</span>
+</div>
+<div class="viewcode-block" id="FilenamePattern.fill_replacers"><a class="viewcode-back" href="../../irclog/archive.html#irclog.archive.FilenamePattern.fill_replacers">[docs]</a>    <span class="k">def</span> <span class="nf">fill_replacers</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">replacers</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot;Fills replacers with given values.</span>
+
+<span class="sd">        .. sourcecode:: pycon</span>
+
+<span class="sd">           &gt;&gt;&gt; pattern = FilenamePattern(&quot;/logs/&lt;server&gt;&quot;</span>
+<span class="sd">           ...                           &quot;/&lt;channel&gt;.&lt;date:%Y-%m-%d&gt;.log&quot;)</span>
+<span class="sd">           &gt;&gt;&gt; import datetime</span>
+<span class="sd">           &gt;&gt;&gt; pattern.fill_replacers({&quot;server&quot;: &quot;Freenode&quot;,</span>
+<span class="sd">           ...                         &quot;channel&quot;: &quot;#hongminhee&quot;,</span>
+<span class="sd">           ...                         &quot;date&quot;: datetime.date(2010, 8, 4)})</span>
+<span class="sd">           &#39;/logs/Freenode/#hongminhee.2010-08-04.log&#39;</span>
+
+<span class="sd">        It may raise :exc:`KeyError` when too few replacers has given:</span>
+
+<span class="sd">        .. sourcecode:: pycon</span>
+
+<span class="sd">           &gt;&gt;&gt; pattern = FilenamePattern(&quot;/logs/&lt;server&gt;&quot;</span>
+<span class="sd">           ...                           &quot;/&lt;channel&gt;.&lt;date:%Y-%m-%d&gt;.log&quot;)</span>
+<span class="sd">           &gt;&gt;&gt; pattern.fill_replacers({&quot;server&quot;: &quot;Freenode&quot;})</span>
+<span class="sd">           Traceback (most recent call last):</span>
+<span class="sd">             ...</span>
+<span class="sd">           KeyError: &#39;channel&#39;</span>
+
+<span class="sd">        :param replacers: a mapping object of</span>
+<span class="sd">                          ``(replacer_name, str_to_replace)``</span>
+<span class="sd">        :type replacers: :class:`dict`, mapping object</span>
+<span class="sd">        :returns: a filled filename</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">replacers</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
+            <span class="n">replacers</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span><span class="n">replacers</span><span class="p">)</span>
+        <span class="k">def</span> <span class="nf">repl</span><span class="p">(</span><span class="n">m</span><span class="p">):</span>
+            <span class="n">value</span> <span class="o">=</span> <span class="n">replacers</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="s">&quot;name&quot;</span><span class="p">)]</span>
+            <span class="k">if</span> <span class="n">m</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="s">&quot;format&quot;</span><span class="p">):</span>
+                <span class="n">value</span> <span class="o">=</span> <span class="n">format</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">m</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="s">&quot;format&quot;</span><span class="p">))</span>
+            <span class="k">return</span> <span class="n">value</span>
+        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">REPLACER_PATTERN</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="n">repl</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">pattern</span><span class="p">)</span>
+</div>
+<div class="viewcode-block" id="FilenamePattern.glob_pattern"><a class="viewcode-back" href="../../irclog/archive.html#irclog.archive.FilenamePattern.glob_pattern">[docs]</a>    <span class="k">def</span> <span class="nf">glob_pattern</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
+        <span class="k">return</span> <span class="s">&#39;&#39;</span>
+</div>
+    <span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">pattern</span>
+</pre></div></div>
+
+          </div>
+        </div>
+      </div>
+      <div class="sphinxsidebar">
+        <div class="sphinxsidebarwrapper">
+<div id="searchbox" style="display: none">
+  <h3>Quick search</h3>
+    <form class="search" action="../../search.html" method="get">
+      <input type="text" name="q" size="18" />
+      <input type="submit" value="Go" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    <p class="searchtip" style="font-size: 90%">
+    Enter search terms or a module, class or function name.
+    </p>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+        </div>
+      </div>
+      <div class="clearer"></div>
+    </div>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="../../genindex.html" title="General Index"
+             >index</a></li>
+        <li class="right" >
+          <a href="../../py-modindex.html" title="Python Module Index"
+             >modules</a> |</li>
+        <li><a href="../../index.html">irclog v0.1 documentation</a> &raquo;</li>
+          <li><a href="../index.html" >Module code</a> &raquo;</li> 
+      </ul>
+    </div>
+
+    <div class="footer">
+        &copy; Copyright 2010, Hong MinHee.
+      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.3.
+    </div>
+<script type="text/javascript">
+
+  var _gaq = _gaq || [];
+  _gaq.push(['_setAccount', 'UA-52596-12']);
+  _gaq.push(['_trackPageview']);
+
+  (function() {
+    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+  })();
+
+</script>
+
+  </body>
+</html>

irclog/_modules/irclog/messages.html

+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    
+    <title>irclog.messages &mdash; irclog v0.1 documentation</title>
+    <link rel="stylesheet" href="../../_static/mezzanine.css" type="text/css" />
+    <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:    '../../',
+        VERSION:     '0.1',
+        COLLAPSE_INDEX: false,
+        FILE_SUFFIX: '.html',
+        HAS_SOURCE:  true
+      };
+    </script>
+    <script type="text/javascript" src="../../_static/jquery.js"></script>
+    <script type="text/javascript" src="../../_static/underscore.js"></script>
+    <script type="text/javascript" src="../../_static/doctools.js"></script>
+    <link rel="top" title="irclog v0.1 documentation" href="../../index.html" />
+    <link rel="up" title="Module code" href="../index.html" /> 
+  </head>
+  <body>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="../../genindex.html" title="General Index"
+             accesskey="I">index</a></li>
+        <li class="right" >
+          <a href="../../py-modindex.html" title="Python Module Index"
+             >modules</a> |</li>
+        <li><a href="../../index.html">irclog v0.1 documentation</a> &raquo;</li>
+          <li><a href="../index.html" accesskey="U">Module code</a> &raquo;</li> 
+      </ul>
+    </div>  
+
+    <div class="document">
+      <div class="documentwrapper">
+        <div class="bodywrapper">
+          <div class="body">
+            
+  <h1>Source code for irclog.messages</h1><div class="highlight"><pre>
+<span class="sd">&quot;&quot;&quot;:mod:`irclog.messages` --- Various message types</span>
+<span class="sd">~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</span>
+
+<span class="sd">It provides a hierarchy of IRC log message types.</span>
+
+<span class="sd">- :class:`BaseMessage`</span>
+
+<span class="sd"> - :class:`Message`</span>
+
+<span class="sd">  - :class:`PublicMessage`</span>
+<span class="sd">  - :class:`ActionMessage`</span>
+<span class="sd">  - :class:`NoticeMessage`</span>
+
+<span class="sd"> - :class:`BaseNickMessage`</span>
+
+<span class="sd">  - :class:`NickMessage`</span>
+<span class="sd">  - :class:`SelfNickMessage`</span>
+
+<span class="sd"> - :class:`JoinMessage`</span>
+<span class="sd"> - :class:`ModeMessage`</span>
+<span class="sd"> - :class:`PartMessage`</span>
+<span class="sd"> - :class:`QuitMessage`</span>
+<span class="sd"> - :class:`KickMessage`</span>
+<span class="sd"> - :class:`BaseTopicMessage`</span>
+
+<span class="sd">  - :class:`TopicMessage`</span>
+<span class="sd">  - :class:`NoTopicMessage`</span>
+
+<span class="sd">&quot;&quot;&quot;</span>
+<span class="kn">import</span> <span class="nn">datetime</span>
+
+
+<div class="viewcode-block" id="BaseMessage"><a class="viewcode-back" href="../../irclog/messages.html#irclog.messages.BaseMessage">[docs]</a><span class="k">class</span> <span class="nc">BaseMessage</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+    <span class="sd">&quot;&quot;&quot;Abstract base type for all IRC log messages.</span>
+
+<span class="sd">    :param messaged_at: a :class:`datetime.datetime` logged</span>
+<span class="sd">    :type messaged_at: :class:`datetime.datetime`</span>
+
+
+<span class="sd">    .. attribute:: messaged_at</span>
+
+<span class="sd">       The naive :class:`datetime.datetime` logged.</span>
+
+<span class="sd">    &quot;&quot;&quot;</span>
+
+    <span class="n">__slots__</span> <span class="o">=</span> <span class="s">&quot;messaged_at&quot;</span><span class="p">,</span>
+
+    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">messaged_at</span><span class="p">):</span>
+        <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">messaged_at</span><span class="p">,</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="p">):</span>
+            <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s">&quot;messaged_at must be a datetime.datetime, not &quot;</span> <span class="o">+</span>
+                            <span class="nb">repr</span><span class="p">(</span><span class="n">messaged_at</span><span class="p">))</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">messaged_at</span> <span class="o">=</span> <span class="n">messaged_at</span>
+
+</div>
+<div class="viewcode-block" id="Message"><a class="viewcode-back" href="../../irclog/messages.html#irclog.messages.Message">[docs]</a><span class="k">class</span> <span class="nc">Message</span><span class="p">(</span><span class="n">BaseMessage</span><span class="p">):</span>
+    <span class="sd">&quot;&quot;&quot;Abstract base type for :class:`PublicMessage`, :class:`ActionMessage`</span>
+<span class="sd">    and :class:`NoticeMessage`.</span>
+
+<span class="sd">    :param messaged_at: a :class:`datetime.datetime` logged</span>
+<span class="sd">    :type messaged_at: :class:`datetime.datetime`</span>
+<span class="sd">    :param nick: a nickname</span>
+<span class="sd">    :type nick: :class:`basestring`</span>
+<span class="sd">    :param line: a message body</span>
+<span class="sd">    :type line: :class:`basestring`</span>
+
+
+<span class="sd">    .. attribute:: nick</span>
+
+<span class="sd">       The nickname.</span>
+
+<span class="sd">    .. attribute:: line</span>
+
+<span class="sd">       The message body.</span>
+
+<span class="sd">    &quot;&quot;&quot;</span>
+
+    <span class="n">__slots__</span> <span class="o">=</span> <span class="s">&quot;nick&quot;</span><span class="p">,</span> <span class="s">&quot;line&quot;</span>
+
+    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">messaged_at</span><span class="p">,</span> <span class="n">nick</span><span class="p">,</span> <span class="n">line</span><span class="p">):</span>
+        <span class="n">BaseMessage</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">messaged_at</span><span class="p">)</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">nick</span> <span class="o">=</span> <span class="nb">unicode</span><span class="p">(</span><span class="n">nick</span><span class="p">)</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">line</span> <span class="o">=</span> <span class="nb">unicode</span><span class="p">(</span><span class="n">line</span><span class="p">)</span>
+
+</div>
+<div class="viewcode-block" id="PublicMessage"><a class="viewcode-back" href="../../irclog/messages.html#irclog.messages.PublicMessage">[docs]</a><span class="k">class</span> <span class="nc">PublicMessage</span><span class="p">(</span><span class="n">Message</span><span class="p">):</span>
+    <span class="sd">&quot;&quot;&quot;Most commonly used message type.</span>
+
+<span class="sd">    :param messaged_at: a :class:`datetime.datetime` logged</span>
+<span class="sd">    :type messaged_at: :class:`datetime.datetime`</span>
+<span class="sd">    :param nick: a nickname</span>
+<span class="sd">    :type nick: :class:`basestring`</span>
+<span class="sd">    :param line: a message body</span>
+<span class="sd">    :type line: :class:`basestring`</span>
+
+<span class="sd">    &quot;&quot;&quot;</span>
+
+</div>
+<div class="viewcode-block" id="ActionMessage"><a class="viewcode-back" href="../../irclog/messages.html#irclog.messages.ActionMessage">[docs]</a><span class="k">class</span> <span class="nc">ActionMessage</span><span class="p">(</span><span class="n">Message</span><span class="p">):</span>
+    <span class="sd">&quot;&quot;&quot;``ACTION`` message type.</span>
+
+<span class="sd">    :param messaged_at: a :class:`datetime.datetime` logged</span>
+<span class="sd">    :type messaged_at: :class:`datetime.datetime`</span>
+<span class="sd">    :param nick: a nickname</span>
+<span class="sd">    :type nick: :class:`basestring`</span>
+<span class="sd">    :param line: a message body</span>
+<span class="sd">    :type line: :class:`basestring`</span>
+
+<span class="sd">    &quot;&quot;&quot;</span>
+</div>
+<div class="viewcode-block" id="NoticeMessage"><a class="viewcode-back" href="../../irclog/messages.html#irclog.messages.NoticeMessage">[docs]</a><span class="k">class</span> <span class="nc">NoticeMessage</span><span class="p">(</span><span class="n">Message</span><span class="p">):</span>
+    <span class="sd">&quot;&quot;&quot;Notice message type.</span>
+
+<span class="sd">    :param messaged_at: a :class:`datetime.datetime` logged</span>
+<span class="sd">    :type messaged_at: :class:`datetime.datetime`</span>
+<span class="sd">    :param nick: a nickname</span>
+<span class="sd">    :type nick: :class:`basestring`</span>
+<span class="sd">    :param line: a message body</span>
+<span class="sd">    :type line: :class:`basestring`</span>
+<span class="sd">    :param channel: a channel name</span>
+<span class="sd">    :type channel: :class:`basestring`</span>
+
+
+<span class="sd">    .. attribute:: channel</span>
+
+<span class="sd">       The channel name.</span>
+
+<span class="sd">    &quot;&quot;&quot;</span>
+
+    <span class="n">__slots__</span> <span class="o">=</span> <span class="s">&quot;channel&quot;</span><span class="p">,</span>
+
+    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">messaged_at</span><span class="p">,</span> <span class="n">nick</span><span class="p">,</span> <span class="n">line</span><span class="p">,</span> <span class="n">channel</span><span class="p">):</span>
+        <span class="n">Message</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">messaged_at</span><span class="p">,</span> <span class="n">nick</span><span class="p">,</span> <span class="n">line</span><span class="p">)</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">channel</span> <span class="o">=</span> <span class="nb">unicode</span><span class="p">(</span><span class="n">channel</span><span class="p">)</span>
+
+</div>
+<div class="viewcode-block" id="BaseNickMessage"><a class="viewcode-back" href="../../irclog/messages.html#irclog.messages.BaseNickMessage">[docs]</a><span class="k">class</span> <span class="nc">BaseNickMessage</span><span class="p">(</span><span class="n">BaseMessage</span><span class="p">):</span>
+    <span class="sd">&quot;&quot;&quot;Abstract base type for nickname changing message types.</span>
+
+<span class="sd">    :param messaged_at: a :class:`datetime.datetime` logged</span>
+<span class="sd">    :type messaged_at: :class:`datetime.datetime`</span>
+<span class="sd">    :param to: a new nickname</span>
+<span class="sd">    :type to: :class:`basestring`</span>
+
+
+<span class="sd">    .. attribute:: to</span>
+
+<span class="sd">       The new nickname.</span>
+
+<span class="sd">    &quot;&quot;&quot;</span>
+
+    <span class="n">__slots__</span> <span class="o">=</span> <span class="s">&quot;to&quot;</span><span class="p">,</span>
+
+    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">messaged_at</span><span class="p">,</span> <span class="n">to</span><span class="p">):</span>
+        <span class="n">BaseMessage</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">messaged_at</span><span class="p">)</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">to</span> <span class="o">=</span> <span class="nb">unicode</span><span class="p">(</span><span class="n">to</span><span class="p">)</span>
+
+</div>
+<div class="viewcode-block" id="NickMessage"><a class="viewcode-back" href="../../irclog/messages.html#irclog.messages.NickMessage">[docs]</a><span class="k">class</span> <span class="nc">NickMessage</span><span class="p">(</span><span class="n">BaseNickMessage</span><span class="p">):</span>
+    <span class="sd">&quot;&quot;&quot;Nickname changing message type.</span>
+
+<span class="sd">    :param messaged_at: a :class:`datetime.datetime` logged</span>
+<span class="sd">    :type messaged_at: :class:`datetime.datetime`</span>
+<span class="sd">    :param from_: a old nickname</span>
+<span class="sd">    :type from_: :class:`basestring`</span>
+<span class="sd">    :param to: a new nickname</span>
+<span class="sd">    :type to: :class:`basestring`</span>
+
+<span class="sd">    .. attribute:: from_</span>
+
+<span class="sd">       The old nickname.</span>
+
+<span class="sd">    &quot;&quot;&quot;</span>
+
+    <span class="n">__slots__</span> <span class="o">=</span> <span class="s">&quot;from_&quot;</span><span class="p">,</span>
+
+    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">messaged_at</span><span class="p">,</span> <span class="n">from_</span><span class="p">,</span> <span class="n">to</span><span class="p">):</span>
+        <span class="n">BaseNickMessage</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">messaged_at</span><span class="p">,</span> <span class="n">to</span><span class="p">)</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">from_</span> <span class="o">=</span> <span class="nb">unicode</span><span class="p">(</span><span class="n">from_</span><span class="p">)</span>
+
+</div>
+<div class="viewcode-block" id="SelfNickMessage"><a class="viewcode-back" href="../../irclog/messages.html#irclog.messages.SelfNickMessage">[docs]</a><span class="k">class</span> <span class="nc">SelfNickMessage</span><span class="p">(</span><span class="n">BaseNickMessage</span><span class="p">):</span>
+    <span class="sd">&quot;&quot;&quot;My nickname chaning message type.</span>
+
+<span class="sd">    :param messaged_at: a :class:`datetime.datetime` logged</span>
+<span class="sd">    :type messaged_at: :class:`datetime.datetime`</span>
+<span class="sd">    :param to: a new nickname</span>
+<span class="sd">    :type to: :class:`basestring`</span>
+
+<span class="sd">    &quot;&quot;&quot;</span>
+
+</div>
+<div class="viewcode-block" id="JoinMessage"><a class="viewcode-back" href="../../irclog/messages.html#irclog.messages.JoinMessage">[docs]</a><span class="k">class</span> <span class="nc">JoinMessage</span><span class="p">(</span><span class="n">BaseMessage</span><span class="p">):</span>
+    <span class="sd">&quot;&quot;&quot;Join message type.</span>
+
+<span class="sd">    :param messaged_at: a :class:`datetime.datetime` logged</span>
+<span class="sd">    :type messaged_at: :class:`datetime.datetime`</span>
+<span class="sd">    :param nick: a nickname</span>
+<span class="sd">    :type nick: :class:`basestring`</span>
+<span class="sd">    :param ident: an ident</span>
+<span class="sd">    :type ident: :class:`basestring`</span>
+<span class="sd">    :param channel: a channel name</span>
+<span class="sd">    :type channel: :class:`basestring`</span>
+
+
+<span class="sd">    .. attribute:: nick</span>
+
+<span class="sd">       The nickname.</span>
+
+<span class="sd">    .. attribute:: ident</span>
+
+<span class="sd">       The ident.</span>
+
+<span class="sd">    .. attribute:: channel</span>
+
+<span class="sd">       The channel name.</span>
+
+<span class="sd">    &quot;&quot;&quot;</span>
+
+    <span class="n">__slots__</span> <span class="o">=</span> <span class="s">&quot;nick&quot;</span><span class="p">,</span> <span class="s">&quot;ident&quot;</span><span class="p">,</span> <span class="s">&quot;channel&quot;</span>
+
+    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">messaged_at</span><span class="p">,</span> <span class="n">nick</span><span class="p">,</span> <span class="n">ident</span><span class="p">,</span> <span class="n">channel</span><span class="p">):</span>
+        <span class="n">BaseMessage</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">messaged_at</span><span class="p">)</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">nick</span> <span class="o">=</span> <span class="nb">unicode</span><span class="p">(</span><span class="n">nick</span><span class="p">)</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">ident</span> <span class="o">=</span> <span class="nb">unicode</span><span class="p">(</span><span class="n">ident</span><span class="p">)</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">channel</span> <span class="o">=</span> <span class="nb">unicode</span><span class="p">(</span><span class="n">channel</span><span class="p">)</span>
+
+</div>
+<div class="viewcode-block" id="ModeMessage"><a class="viewcode-back" href="../../irclog/messages.html#irclog.messages.ModeMessage">[docs]</a><span class="k">class</span> <span class="nc">ModeMessage</span><span class="p">(</span><span class="n">BaseMessage</span><span class="p">):</span>
+    <span class="sd">&quot;&quot;&quot;``MODE`` message type.</span>
+
+<span class="sd">    :param messaged_at: a :class:`datetime.datetime` logged</span>
+<span class="sd">    :type messaged_at: :class:`datetime.datetime`</span>
+<span class="sd">    :param server: a server</span>
+<span class="sd">    :type server: :class:`basestring`</span>
+<span class="sd">    :param channel: a channel name</span>
+<span class="sd">    :type channel: :class:`basestring`</span>
+<span class="sd">    :param modelist: a mode list</span>
+<span class="sd">    :param nick: a nickname</span>
+<span class="sd">    :type nick: :class:`basestring`</span>
+
+
+<span class="sd">    .. attribute:: server</span>
+
+<span class="sd">       The server.</span>
+
+<span class="sd">    .. attribute:: channel</span>
+
+<span class="sd">       The channel name.</span>
+
+<span class="sd">    .. attribute:: modelist</span>
+
+<span class="sd">       The mode list.</span>
+
+<span class="sd">    .. attribute:: nick</span>
+
+<span class="sd">       The nickname.</span>
+
+
+<span class="sd">    &quot;&quot;&quot;</span>
+
+    <span class="n">__slots__</span> <span class="o">=</span> <span class="s">&quot;server&quot;</span><span class="p">,</span> <span class="s">&quot;channel&quot;</span><span class="p">,</span> <span class="s">&quot;modelist&quot;</span><span class="p">,</span> <span class="s">&quot;nick&quot;</span>
+
+    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">messaged_at</span><span class="p">,</span> <span class="n">server</span><span class="p">,</span> <span class="n">channel</span><span class="p">,</span> <span class="n">modelist</span><span class="p">,</span> <span class="n">nick</span><span class="p">):</span>
+        <span class="n">BaseMessage</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">messaged_at</span><span class="p">)</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">server</span> <span class="o">=</span> <span class="nb">unicode</span><span class="p">(</span><span class="n">server</span><span class="p">)</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">channel</span> <span class="o">=</span> <span class="nb">unicode</span><span class="p">(</span><span class="n">channel</span><span class="p">)</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">modelist</span> <span class="o">=</span> <span class="nb">unicode</span><span class="p">(</span><span class="n">modelist</span><span class="p">)</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">channel</span> <span class="o">=</span> <span class="nb">unicode</span><span class="p">(</span><span class="n">channel</span><span class="p">)</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">nick</span> <span class="o">=</span> <span class="nb">unicode</span><span class="p">(</span><span class="n">nick</span><span class="p">)</span>
+
+</div>
+<div class="viewcode-block" id="PartMessage"><a class="viewcode-back" href="../../irclog/messages.html#irclog.messages.PartMessage">[docs]</a><span class="k">class</span> <span class="nc">PartMessage</span><span class="p">(</span><span class="n">BaseMessage</span><span class="p">):</span>
+    <span class="sd">&quot;&quot;&quot;``PART`` message type.</span>
+
+<span class="sd">    :param nick: a nickname</span>
+<span class="sd">    :type nick: :class:`basestring`</span>
+<span class="sd">    :param ident: an ident</span>
+<span class="sd">    :type ident: :class:`basestring`</span>
+<span class="sd">    :param channel: a channel name</span>
+<span class="sd">    :type channel: :class:`basestring`</span>
+<span class="sd">    :param reason: a reason</span>
+<span class="sd">    :type reason: :class:`basestring`</span>
+
+
+<span class="sd">    .. attribute:: nick</span>
+
+<span class="sd">       The nickname.</span>
+
+<span class="sd">    .. attribute:: ident</span>
+
+<span class="sd">       The ident.</span>
+
+<span class="sd">    .. attribute:: channel</span>
+
+<span class="sd">       The channel name.</span>
+
+<span class="sd">    .. attribute:: reason</span>
+
+<span class="sd">       The reason.</span>
+
+<span class="sd">    &quot;&quot;&quot;</span>
+
+    <span class="n">__slots__</span> <span class="o">=</span> <span class="s">&quot;nick&quot;</span><span class="p">,</span> <span class="s">&quot;ident&quot;</span><span class="p">,</span> <span class="s">&quot;channel&quot;</span><span class="p">,</span> <span class="s">&quot;reason&quot;</span>
+
+    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">messaged_at</span><span class="p">,</span> <span class="n">nick</span><span class="p">,</span> <span class="n">ident</span><span class="p">,</span> <span class="n">channel</span><span class="p">,</span> <span class="n">reason</span><span class="p">):</span>
+        <span class="n">BaseMessage</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">messaged_at</span><span class="p">)</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">nick</span> <span class="o">=</span> <span class="nb">unicode</span><span class="p">(</span><span class="n">nick</span><span class="p">)</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">ident</span> <span class="o">=</span> <span class="nb">unicode</span><span class="p">(</span><span class="n">ident</span><span class="p">)</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">channel</span> <span class="o">=</span> <span class="nb">unicode</span><span class="p">(</span><span class="n">channel</span><span class="p">)</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">reason</span> <span class="o">=</span> <span class="nb">unicode</span><span class="p">(</span><span class="n">reason</span><span class="p">)</span>
+
+</div>
+<div class="viewcode-block" id="QuitMessage"><a class="viewcode-back" href="../../irclog/messages.html#irclog.messages.QuitMessage">[docs]</a><span class="k">class</span> <span class="nc">QuitMessage</span><span class="p">(</span><span class="n">BaseMessage</span><span class="p">):</span>
+    <span class="sd">&quot;&quot;&quot;Quiting message type.</span>
+
+<span class="sd">    :param nick: a nickname</span>
+<span class="sd">    :type nick: :class:`basestring`</span>
+<span class="sd">    :param ident: an ident</span>
+<span class="sd">    :type ident: :class:`basestring`</span>
+<span class="sd">    :param reason: a reason</span>
+<span class="sd">    :type reason: :class:`basestring`</span>
+
+
+<span class="sd">    .. attribute:: nick</span>
+
+<span class="sd">       The nickname.</span>
+
+<span class="sd">    .. attribute:: ident</span>
+
+<span class="sd">       The ident.</span>
+
+<span class="sd">    .. attribute:: reason</span>
+
+<span class="sd">       The reason.</span>
+
+<span class="sd">    &quot;&quot;&quot;</span>
+
+    <span class="n">__slots__</span> <span class="o">=</span> <span class="s">&quot;nick&quot;</span><span class="p">,</span> <span class="s">&quot;ident&quot;</span><span class="p">,</span> <span class="s">&quot;reason&quot;</span>
+
+    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">messaged_at</span><span class="p">,</span> <span class="n">nick</span><span class="p">,</span> <span class="n">ident</span><span class="p">,</span> <span class="n">reason</span><span class="p">):</span>
+        <span class="n">BaseMessage</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">messaged_at</span><span class="p">)</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">nick</span> <span class="o">=</span> <span class="nb">unicode</span><span class="p">(</span><span class="n">nick</span><span class="p">)</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">ident</span> <span class="o">=</span> <span class="nb">unicode</span><span class="p">(</span><span class="n">ident</span><span class="p">)</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">reason</span> <span class="o">=</span> <span class="nb">unicode</span><span class="p">(</span><span class="n">reason</span><span class="p">)</span>
+
+</div>
+<div class="viewcode-block" id="KickMessage"><a class="viewcode-back" href="../../irclog/messages.html#irclog.messages.KickMessage">[docs]</a><span class="k">class</span> <span class="nc">KickMessage</span><span class="p">(</span><span class="n">BaseMessage</span><span class="p">):</span>
+    <span class="sd">&quot;&quot;&quot;Kick message type.</span>
+
+<span class="sd">    :param nick: a nickname that was kicked</span>
+<span class="sd">    :type nick: :class:`basestring`</span>
+<span class="sd">    :param channel: a channel name</span>
+<span class="sd">    :type channel: :class:`basestring`</span>
+<span class="sd">    :param by: a nickname that kicks</span>
+<span class="sd">    :type by: :class:`basestring`</span>
+<span class="sd">    :param reason: a reason</span>
+<span class="sd">    :type reason: :class:`basestring`</span>
+
+
+<span class="sd">    .. attribute:: nick</span>
+
+<span class="sd">       The nickname that was kicked.</span>
+
+<span class="sd">    .. attribute:: channel</span>
+
+<span class="sd">       The channel name.</span>
+
+<span class="sd">    .. attribute:: by</span>
+
+<span class="sd">       The nickname that kicks.</span>
+
+<span class="sd">    .. attribute:: reason</span>
+
+<span class="sd">       The reason.</span>
+
+<span class="sd">    &quot;&quot;&quot;</span>
+
+    <span class="n">__slots__</span> <span class="o">=</span> <span class="s">&quot;nick&quot;</span><span class="p">,</span> <span class="s">&quot;channel&quot;</span><span class="p">,</span> <span class="s">&quot;by&quot;</span><span class="p">,</span> <span class="s">&quot;reason&quot;</span><span class="p">,</span>
+
+    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">messaged_at</span><span class="p">,</span> <span class="n">nick</span><span class="p">,</span> <span class="n">channel</span><span class="p">,</span> <span class="n">by</span><span class="p">,</span> <span class="n">reason</span><span class="p">):</span>
+        <span class="n">BaseMessage</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">messaged_at</span><span class="p">)</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">nick</span> <span class="o">=</span> <span class="nb">unicode</span><span class="p">(</span><span class="n">nick</span><span class="p">)</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">channel</span> <span class="o">=</span> <span class="nb">unicode</span><span class="p">(</span><span class="n">channel</span><span class="p">)</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">by</span> <span class="o">=</span> <span class="nb">unicode</span><span class="p">(</span><span class="n">by</span><span class="p">)</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">reason</span> <span class="o">=</span> <span class="nb">unicode</span><span class="p">(</span><span class="n">reason</span><span class="p">)</span>
+
+</div>
+<div class="viewcode-block" id="BaseTopicMessage"><a class="viewcode-back" href="../../irclog/messages.html#irclog.messages.BaseTopicMessage">[docs]</a><span class="k">class</span> <span class="nc">BaseTopicMessage</span><span class="p">(</span><span class="n">BaseMessage</span><span class="p">):</span>
+    <span class="sd">&quot;&quot;&quot;Abstract base class for topic changing message types.</span>
+
+<span class="sd">    :param messaged_at: a :class:`datetime.datetime` logged</span>
+<span class="sd">    :type messaged_at: :class:`datetime.datetime`</span>
+<span class="sd">    :param nick: a nickname</span>
+<span class="sd">    :type nick: :class:`basestring`</span>
+<span class="sd">    :param channel: a channel name</span>
+<span class="sd">    :type channel: :class:`basestring`</span>
+
+
+<span class="sd">    .. attribute:: nick</span>
+
+<span class="sd">       The nickname.</span>
+
+<span class="sd">    .. attribute:: channel</span>
+
+<span class="sd">       The channel name.</span>
+
+<span class="sd">    &quot;&quot;&quot;</span>
+
+    <span class="n">__slots__</span> <span class="o">=</span> <span class="s">&quot;nick&quot;</span><span class="p">,</span> <span class="s">&quot;channel&quot;</span>
+
+    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">messaged_at</span><span class="p">,</span> <span class="n">nick</span><span class="p">,</span> <span class="n">channel</span><span class="p">):</span>
+        <span class="n">BaseMessage</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">messaged_at</span><span class="p">)</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">nick</span> <span class="o">=</span> <span class="nb">unicode</span><span class="p">(</span><span class="n">nick</span><span class="p">)</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">channel</span> <span class="o">=</span> <span class="nb">unicode</span><span class="p">(</span><span class="n">channel</span><span class="p">)</span>
+
+</div>
+<div class="viewcode-block" id="TopicMessage"><a class="viewcode-back" href="../../irclog/messages.html#irclog.messages.TopicMessage">[docs]</a><span class="k">class</span> <span class="nc">TopicMessage</span><span class="p">(</span><span class="n">BaseTopicMessage</span><span class="p">):</span>
+    <span class="sd">&quot;&quot;&quot;Topic changing message types.</span>
+
+<span class="sd">    :param messaged_at: a :class:`datetime.datetime` logged</span>
+<span class="sd">    :type messaged_at: :class:`datetime.datetime`</span>
+<span class="sd">    :param nick: a nickname</span>
+<span class="sd">    :type nick: :class:`basestring`</span>
+<span class="sd">    :param channel: a channel name</span>
+<span class="sd">    :type channel: :class:`basestring`</span>
+<span class="sd">    :param topic: a new topic</span>
+<span class="sd">    :type topic: :class:`basestring`</span>
+
+
+<span class="sd">    .. attribute:: topic</span>
+
+<span class="sd">       The new topic</span>
+
+<span class="sd">    &quot;&quot;&quot;</span>
+
+    <span class="n">__slots__</span> <span class="o">=</span> <span class="s">&quot;topic&quot;</span>
+
+    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">messaged_at</span><span class="p">,</span> <span class="n">nick</span><span class="p">,</span> <span class="n">channel</span><span class="p">,</span> <span class="n">topic</span><span class="p">):</span>
+        <span class="n">BaseTopicMessage</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">messaged_at</span><span class="p">,</span> <span class="n">nick</span><span class="p">,</span> <span class="n">channel</span><span class="p">)</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">topic</span> <span class="o">=</span> <span class="nb">unicode</span><span class="p">(</span><span class="n">topic</span><span class="p">)</span>
+
+</div>
+<div class="viewcode-block" id="NoTopicMessage"><a class="viewcode-back" href="../../irclog/messages.html#irclog.messages.NoTopicMessage">[docs]</a><span class="k">class</span> <span class="nc">NoTopicMessage</span><span class="p">(</span><span class="n">BaseTopicMessage</span><span class="p">):</span>
+    <span class="sd">&quot;&quot;&quot;Empty topic message types.</span>
+
+<span class="sd">    :param messaged_at: a :class:`datetime.datetime` logged</span>
+<span class="sd">    :type messaged_at: :class:`datetime.datetime`</span>
+<span class="sd">    :param nick: a nickname</span>
+<span class="sd">    :type nick: :class:`basestring`</span>
+<span class="sd">    :param channel: a channel name</span>
+<span class="sd">    :type channel: :class:`basestring`</span>
+
+<span class="sd">    &quot;&quot;&quot;</span>
+</pre></div></div>
+
+          </div>
+        </div>
+      </div>
+      <div class="sphinxsidebar">
+        <div class="sphinxsidebarwrapper">
+<div id="searchbox" style="display: none">
+  <h3>Quick search</h3>
+    <form class="search" action="../../search.html" method="get">
+      <input type="text" name="q" size="18" />
+      <input type="submit" value="Go" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    <p class="searchtip" style="font-size: 90%">
+    Enter search terms or a module, class or function name.
+    </p>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+        </div>
+      </div>
+      <div class="clearer"></div>
+    </div>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="../../genindex.html" title="General Index"
+             >index</a></li>
+        <li class="right" >
+          <a href="../../py-modindex.html" title="Python Module Index"
+             >modules</a> |</li>
+        <li><a href="../../index.html">irclog v0.1 documentation</a> &raquo;</li>
+          <li><a href="../index.html" >Module code</a> &raquo;</li> 
+      </ul>
+    </div>
+
+    <div class="footer">
+        &copy; Copyright 2010, Hong MinHee.
+      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.3.
+    </div>
+<script type="text/javascript">
+
+  var _gaq = _gaq || [];
+  _gaq.push(['_setAccount', 'UA-52596-12']);
+  _gaq.push(['_trackPageview']);
+
+  (function() {
+    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+  })();
+
+</script>
+
+  </body>
+</html>

irclog/_modules/irclog/parser.html

+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    
+    <title>irclog.parser &mdash; irclog v0.1 documentation</title>
+    <link rel="stylesheet" href="../../_static/mezzanine.css" type="text/css" />
+    <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:    '../../',
+        VERSION:     '0.1',
+        COLLAPSE_INDEX: false,
+        FILE_SUFFIX: '.html',
+        HAS_SOURCE:  true
+      };
+    </script>
+    <script type="text/javascript" src="../../_static/jquery.js"></script>
+    <script type="text/javascript" src="../../_static/underscore.js"></script>
+    <script type="text/javascript" src="../../_static/doctools.js"></script>
+    <link rel="top" title="irclog v0.1 documentation" href="../../index.html" />
+    <link rel="up" title="Module code" href="../index.html" /> 
+  </head>
+  <body>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="../../genindex.html" title="General Index"
+             accesskey="I">index</a></li>
+        <li class="right" >
+          <a href="../../py-modindex.html" title="Python Module Index"
+             >modules</a> |</li>
+        <li><a href="../../index.html">irclog v0.1 documentation</a> &raquo;</li>
+          <li><a href="../index.html" accesskey="U">Module code</a> &raquo;</li> 
+      </ul>
+    </div>  
+
+    <div class="document">
+      <div class="documentwrapper">
+        <div class="bodywrapper">
+          <div class="body">
+            
+  <h1>Source code for irclog.parser</h1><div class="highlight"><pre>
+<span class="sd">&quot;&quot;&quot;:mod:`irclog.parser` --- IRC log parser</span>
+<span class="sd">~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</span>
+
+<span class="sd">This module provides a function which takes lines of log then transforms it</span>
+<span class="sd">to message objects in :mod:`irclog.messages` module.</span>
+
+
+<span class="sd">.. data:: PATTERN</span>
+
+<span class="sd">   The :mod:`re` pattern matches to a line of IRC log message.</span>
+
+<span class="sd">   .. note::</span>
+
+<span class="sd">      This regular expression is originally written by</span>
+<span class="sd">      `Kang Seonghoon`_ aka *lifthrasiir*. This pattern is posted in</span>
+<span class="sd">      `an article of LangDev &lt;http://langdev.net/post/93&gt;`_.</span>
+
+<span class="sd">      .. _Kang Seonghoon: http://mearie.org/</span>
+
+<span class="sd">&quot;&quot;&quot;</span>
+<span class="kn">import</span> <span class="nn">re</span>
+<span class="kn">import</span> <span class="nn">datetime</span>
+<span class="kn">import</span> <span class="nn">irclog.messages</span>
+
+
+<span class="n">PATTERN</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="s">r&quot;&quot;&quot;</span>
+<span class="s">    ^ (?:</span>
+<span class="s">        (?P&lt;ignorable&gt;</span>
+<span class="s">            ---[ ]Day[ ]changed[ ].* |</span>
+<span class="s">            \d\d:\d\d(?::\d\d)?[ ] (?:</span>
+<span class="s">                -!-[ ]Irssi:[ ] |</span>
+<span class="s">                -!-[ ][&lt;;]/Netsplit[ ]   # XXX</span>
+<span class="s">            ) .*</span>
+<span class="s">        ) |</span>
+<span class="s">        (?P&lt;logopenmsg&gt;</span>
+<span class="s">            ---[ ]Log[ ]opened[ ]...[ ](?:[\d ]\d...|...)[ ]\d\d[ ]</span>
+<span class="s">            (?P&lt;logopenwhen&gt;\d\d:\d\d:\d\d)[ ]\d\d\d\d</span>
+<span class="s">        ) |</span>
+<span class="s">        (?P&lt;logclosemsg&gt;</span>
+<span class="s">            ---[ ]Log[ ]closed[ ]...[ ](?:[\d ]\d...|...)[ ]\d\d[ ]</span>
+<span class="s">            (?P&lt;logclosewhen&gt;\d\d:\d\d:\d\d)[ ]\d\d\d\d</span>
+<span class="s">        ) |</span>
+<span class="s">        (?P&lt;when&gt;\d\d:\d\d(?::\d\d)?)[ ](?:</span>
+<span class="s">            -!- [ ](?:</span>
+<span class="s">                (?P&lt;nickmsg&gt;</span>
+<span class="s">                    (?P&lt;nickfrom&gt;.*?)[ ]is[ ]now[ ]known[ ]as[ ](?P&lt;nickto&gt;.*?)</span>
+<span class="s">                ) |</span>
+<span class="s">                (?P&lt;selfnickmsg&gt;</span>
+<span class="s">                    You&#39;re[ ]now[ ]known[ ]as[ ](?P&lt;selfnickto&gt;.*?)</span>
+<span class="s">                ) |</span>
+<span class="s">                (?P&lt;joinmsg&gt;</span>
+<span class="s">                    (?P&lt;joinnick&gt;.*?)[ ]\[(?P&lt;joinident&gt;.*?)\][ ]</span>
+<span class="s">                    has[ ]joined[ ](?P&lt;joinchan&gt;.*?)</span>
+<span class="s">                ) |</span>
+<span class="s">                (?P&lt;modemsg&gt;</span>
+<span class="s">                    (?:mode|(?P&lt;modeserver&gt;&lt;/ServerMode))</span>
+<span class="s">                    (?P&lt;modechan&gt;.*?)[ ]\[(?P&lt;modelist&gt;.*?)\][ ]</span>
+<span class="s">                    by[ ](?P&lt;modenick&gt;.*?)</span>
+<span class="s">                ) |</span>
+<span class="s">                (?P&lt;partmsg&gt;</span>
+<span class="s">                    (?P&lt;partnick&gt;.*?)[ ]</span>
+<span class="s">                    \[(?P&lt;partident&gt;.*?)\][ ]</span>
+<span class="s">                    has[ ]left[ ](?P&lt;partchan&gt;.*?)[ ]</span>
+<span class="s">                    \[(?P&lt;partreason&gt;.*?)/\]</span>
+<span class="s">                ) |</span>
+<span class="s">                (?P&lt;quitmsg&gt;</span>
+<span class="s">                    (?P&lt;quitnick&gt;.*?)[ ] \[(?P&lt;quitident&gt;.*?)\][ ]</span>
+<span class="s">                    has[ ]quit[ ]\[(?P&lt;quitreason&gt;.*?)\]</span>
+<span class="s">                ) |</span>
+<span class="s">                (?P&lt;kickmsg&gt;</span>
+<span class="s">                    (?P&lt;kicknick&gt;.*?)[ ]</span>
+<span class="s">                    was[ ]kicked[ ]from[ ](?P&lt;kickchan&gt;.*?)[ ]</span>
+<span class="s">                    by[ ](?P&lt;kickby&gt;.*?)[ ] \[(?P&lt;kickreason&gt;.*?)\]</span>
+<span class="s">                ) |</span>
+<span class="s">                (?P&lt;topicmsg&gt;</span>
+<span class="s">                    (?P&lt;topicnick&gt;.*?)[ ]changed[ ]</span>
+<span class="s">                    the[ ]topic[ ]of[ ](?P&lt;topicchan&gt;.*?)</span>
+<span class="s">                    [ ]to:[ ](?P&lt;topicline&gt;.*?)</span>
+<span class="s">                ) |</span>
+<span class="s">                (?P&lt;notopicmsg&gt;</span>
+<span class="s">                    Topic[ ]unset[ ]by[ ](?P&lt;notopicnick&gt;.*?)</span>
+<span class="s">                    [ ]on[ ](?P&lt;notopicchan&gt;.*?)</span>
+<span class="s">                ) |</span>
+<span class="s">            ) |</span>
+<span class="s">            (?P&lt;pubmsg&gt;</span>
+<span class="s">                &lt;[ +@](?P&lt;pubnick&gt;.*?)&gt;[ ](?P&lt;publine&gt;.*?)</span>
+<span class="s">            ) |</span>
+<span class="s">            (?P&lt;actmsg&gt;</span>
+<span class="s">                [ ]\*[ ](?P&lt;actnick&gt;.*?)[ ](?P&lt;actline&gt;.*?)</span>
+<span class="s">            ) |</span>
+<span class="s">            (?P&lt;noticemsg&gt;</span>
+<span class="s">                -(?P&lt;noticenick&gt;.*?):</span>
+<span class="s">                (?:[@+ ])?(?P&lt;noticechan&gt;.*?)</span>
+<span class="s">                -[ ](?P&lt;noticeline&gt;.*?)</span>
+<span class="s">            )</span>
+<span class="s">        )</span>
+<span class="s">    ) $</span>
+<span class="s">&quot;&quot;&quot;</span><span class="p">,</span> <span class="n">re</span><span class="o">.</span><span class="n">VERBOSE</span> <span class="o">|</span> <span class="n">re</span><span class="o">.</span><span class="n">IGNORECASE</span><span class="p">)</span>
+
+<span class="n">RULES</span> <span class="o">=</span> <span class="p">{}</span>
+
+
+<div class="viewcode-block" id="parse"><a class="viewcode-back" href="../../irclog/parser.html#irclog.parser.parse">[docs]</a><span class="k">def</span> <span class="nf">parse</span><span class="p">(</span><span class="n">lines</span><span class="p">,</span> <span class="n">date</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
+    <span class="sd">&quot;&quot;&quot;Transforms lines of log to message objects in :mod:`irclog.messages`</span>
+<span class="sd">    module.</span>
+
+<span class="sd">    :param lines: lines of code</span>
+<span class="sd">    :type lines: iterable object, file object</span>
+<span class="sd">    :param date: a date of the log. default is today</span>
+<span class="sd">    :type date: :class:`datetime.date`</span>
+<span class="sd">    :returns: a list of :class:`irclog.messages.BaseMessage` instances</span>
+
+<span class="sd">    .. note:: This is exactly a generator function.</span>
+
+<span class="sd">    &quot;&quot;&quot;</span>
+    <span class="n">date</span> <span class="o">=</span> <span class="n">date</span> <span class="ow">or</span> <span class="n">datetime</span><span class="o">.</span><span class="n">date</span><span class="o">.</span><span class="n">today</span><span class="p">()</span>
+    <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">lines</span><span class="p">:</span>
+        <span class="k">try</span><span class="p">:</span>
+            <span class="n">line</span> <span class="o">=</span> <span class="n">line</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s">&quot;utf-8&quot;</span><span class="p">)</span>
+        <span class="k">except</span> <span class="ne">UnicodeDecodeError</span><span class="p">:</span>
+            <span class="k">pass</span>
+        <span class="n">match</span> <span class="o">=</span> <span class="n">PATTERN</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">line</span><span class="p">)</span>
+        <span class="k">if</span> <span class="ow">not</span> <span class="n">match</span><span class="p">:</span>
+            <span class="k">continue</span>
+        <span class="k">for</span> <span class="n">group_name</span><span class="p">,</span> <span class="n">function</span> <span class="ow">in</span> <span class="n">RULES</span><span class="o">.</span><span class="n">iteritems</span><span class="p">():</span>
+            <span class="k">if</span> <span class="n">match</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="n">group_name</span><span class="p">):</span>
+                <span class="n">groups</span> <span class="o">=</span> <span class="n">match</span><span class="o">.</span><span class="n">groupdict</span><span class="p">()</span>
+                <span class="n">time</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">time</span><span class="p">(</span><span class="o">*</span><span class="nb">map</span><span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="n">groups</span><span class="p">[</span><span class="s">&quot;when&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&quot;:&quot;</span><span class="p">)))</span>
+                <span class="n">groups</span><span class="p">[</span><span class="s">&quot;when&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">combine</span><span class="p">(</span><span class="n">date</span><span class="p">,</span> <span class="n">time</span><span class="p">)</span>
+                <span class="k">yield</span> <span class="n">function</span><span class="p">(</span><span class="o">**</span><span class="n">groups</span><span class="p">)</span>
+                <span class="k">break</span>
+
+</div>
+<div class="viewcode-block" id="parser"><a class="viewcode-back" href="../../irclog/parser.html#irclog.parser.parser">[docs]</a><span class="k">def</span> <span class="nf">parser</span><span class="p">(</span><span class="n">function</span><span class="p">):</span>
+    <span class="sd">&quot;&quot;&quot;Registers a parser function.</span>
+<span class="sd">    </span>
+<span class="sd">    :param function: a function parses to register</span>
+<span class="sd">    :type function: callable object</span>
+<span class="sd">    :returns: passed ``function``</span>
+
+<span class="sd">    &quot;&quot;&quot;</span>
+    <span class="k">if</span> <span class="ow">not</span> <span class="nb">callable</span><span class="p">(</span><span class="n">function</span><span class="p">):</span>
+        <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s">&quot;function must be callable&quot;</span><span class="p">)</span>
+    <span class="n">RULES</span><span class="p">[</span><span class="n">function</span><span class="o">.</span><span class="n">__name__</span><span class="p">]</span> <span class="o">=</span> <span class="n">function</span>
+    <span class="k">return</span> <span class="n">function</span>
+
+</div>
+<span class="nd">@parser</span>
+<div class="viewcode-block" id="nickmsg"><a class="viewcode-back" href="../../irclog/parser.html#irclog.parser.nickmsg">[docs]</a><span class="k">def</span> <span class="nf">nickmsg</span><span class="p">(</span><span class="n">when</span><span class="p">,</span> <span class="n">nickfrom</span><span class="p">,</span> <span class="n">nickto</span><span class="p">,</span> <span class="o">**</span><span class="n">_</span><span class="p">):</span>
+    <span class="sd">&quot;&quot;&quot;Parses :class:`irclog.messages.NickMessage`.&quot;&quot;&quot;</span>
+    <span class="k">return</span> <span class="n">irclog</span><span class="o">.</span><span class="n">messages</span><span class="o">.</span><span class="n">NickMessage</span><span class="p">(</span><span class="n">when</span><span class="p">,</span> <span class="n">nickfrom</span><span class="p">,</span> <span class="n">nickto</span><span class="p">)</span>
+
+</div>
+<span class="nd">@parser</span>
+<div class="viewcode-block" id="selfnickmsg"><a class="viewcode-back" href="../../irclog/parser.html#irclog.parser.selfnickmsg">[docs]</a><span class="k">def</span> <span class="nf">selfnickmsg</span><span class="p">(</span><span class="n">when</span><span class="p">,</span> <span class="n">selfnickto</span><span class="p">,</span> <span class="o">**</span><span class="n">_</span><span class="p">):</span>
+    <span class="sd">&quot;&quot;&quot;Parses :class:`irclog.messages.SelfNickMessage`.&quot;&quot;&quot;</span>
+    <span class="k">return</span> <span class="n">irclog</span><span class="o">.</span><span class="n">messages</span><span class="o">.</span><span class="n">SelfNickMessage</span><span class="p">(</span><span class="n">when</span><span class="p">,</span> <span class="n">selfnickto</span><span class="p">)</span>
+
+</div>
+<span class="nd">@parser</span>
+<div class="viewcode-block" id="joinmsg"><a class="viewcode-back" href="../../irclog/parser.html#irclog.parser.joinmsg">[docs]</a><span class="k">def</span> <span class="nf">joinmsg</span><span class="p">(</span><span class="n">when</span><span class="p">,</span> <span class="n">joinnick</span><span class="p">,</span> <span class="n">joinident</span><span class="p">,</span> <span class="n">joinchan</span><span class="p">,</span> <span class="o">**</span><span class="n">_</span><span class="p">):</span>
+    <span class="sd">&quot;&quot;&quot;Parses :class:`irclog.messages.JoinMessage`.&quot;&quot;&quot;</span>
+    <span class="k">return</span> <span class="n">irclog</span><span class="o">.</span><span class="n">messages</span><span class="o">.</span><span class="n">JoinMessage</span><span class="p">(</span><span class="n">when</span><span class="p">,</span> <span class="n">joinnick</span><span class="p">,</span> <span class="n">joinident</span><span class="p">,</span> <span class="n">joinchan</span><span class="p">)</span>
+
+</div>
+<span class="nd">@parser</span>
+<div class="viewcode-block" id="modemsg"><a class="viewcode-back" href="../../irclog/parser.html#irclog.parser.modemsg">[docs]</a><span class="k">def</span> <span class="nf">modemsg</span><span class="p">(</span><span class="n">when</span><span class="p">,</span> <span class="n">modeserver</span><span class="p">,</span> <span class="n">modechan</span><span class="p">,</span> <span class="n">modelist</span><span class="p">,</span> <span class="n">modenick</span><span class="p">,</span> <span class="o">**</span><span class="n">_</span><span class="p">):</span>
+    <span class="sd">&quot;&quot;&quot;Parses :class:`irclog.messages.ModeMessage`.&quot;&quot;&quot;</span>
+    <span class="k">return</span> <span class="n">irclog</span><span class="o">.</span><span class="n">messages</span><span class="o">.</span><span class="n">ModeMessage</span><span class="p">(</span><span class="n">when</span><span class="p">,</span> <span class="n">modeserver</span><span class="p">,</span> <span class="n">modechan</span><span class="p">,</span>
+                                       <span class="n">modelist</span><span class="p">,</span> <span class="n">modenick</span><span class="p">)</span>
+
+</div>
+<span class="nd">@parser</span>
+<div class="viewcode-block" id="partmsg"><a class="viewcode-back" href="../../irclog/parser.html#irclog.parser.partmsg">[docs]</a><span class="k">def</span> <span class="nf">partmsg</span><span class="p">(</span><span class="n">when</span><span class="p">,</span> <span class="n">partnick</span><span class="p">,</span> <span class="n">partident</span><span class="p">,</span> <span class="n">partchan</span><span class="p">,</span> <span class="n">partreason</span><span class="p">,</span> <span class="o">**</span><span class="n">_</span><span class="p">):</span>
+    <span class="sd">&quot;&quot;&quot;Parses :class:`irclog.messages.PartMessage`.&quot;&quot;&quot;</span>
+    <span class="k">return</span> <span class="n">irclog</span><span class="o">.</span><span class="n">messages</span><span class="o">.</span><span class="n">PartMessage</span><span class="p">(</span><span class="n">partnick</span><span class="p">,</span> <span class="n">partident</span><span class="p">,</span>
+                                       <span class="n">partchan</span><span class="p">,</span> <span class="n">partreason</span><span class="p">)</span>
+
+</div>
+<span class="nd">@parser</span>
+<div class="viewcode-block" id="quitmsg"><a class="viewcode-back" href="../../irclog/parser.html#irclog.parser.quitmsg">[docs]</a><span class="k">def</span> <span class="nf">quitmsg</span><span class="p">(</span><span class="n">when</span><span class="p">,</span> <span class="n">quitnick</span><span class="p">,</span> <span class="n">quitident</span><span class="p">,</span> <span class="n">quitreason</span><span class="p">,</span> <span class="o">**</span><span class="n">_</span><span class="p">):</span>
+    <span class="sd">&quot;&quot;&quot;Parses :class:`irclog.messages.QuitMessage`.&quot;&quot;&quot;</span>
+    <span class="k">return</span> <span class="n">irclog</span><span class="o">.</span><span class="n">messages</span><span class="o">.</span><span class="n">QuitMessage</span><span class="p">(</span><span class="n">when</span><span class="p">,</span> <span class="n">quitnick</span><span class="p">,</span> <span class="n">quitident</span><span class="p">,</span> <span class="n">quitreason</span><span class="p">)</span>
+
+</div>
+<span class="nd">@parser</span>
+<div class="viewcode-block" id="kickmsg"><a class="viewcode-back" href="../../irclog/parser.html#irclog.parser.kickmsg">[docs]</a><span class="k">def</span> <span class="nf">kickmsg</span><span class="p">(</span><span class="n">when</span><span class="p">,</span> <span class="n">kicknick</span><span class="p">,</span> <span class="n">kickchan</span><span class="p">,</span> <span class="n">kickby</span><span class="p">,</span> <span class="n">kickreason</span><span class="p">,</span> <span class="o">**</span><span class="n">_</span><span class="p">):</span>
+    <span class="sd">&quot;&quot;&quot;Parses :class:`irclog.messages.KickMessage`.&quot;&quot;&quot;</span>
+    <span class="k">return</span> <span class="n">irclog</span><span class="o">.</span><span class="n">messages</span><span class="o">.</span><span class="n">QuitMessage</span><span class="p">(</span><span class="n">when</span><span class="p">,</span> <span class="n">kicknick</span><span class="p">,</span> <span class="n">kickchan</span><span class="p">,</span>
+                                       <span class="n">kickby</span><span class="p">,</span> <span class="n">kickreason</span><span class="p">)</span>
+
+</div>
+<span class="nd">@parser</span>
+<div class="viewcode-block" id="topicmsg"><a class="viewcode-back" href="../../irclog/parser.html#irclog.parser.topicmsg">[docs]</a><span class="k">def</span> <span class="nf">topicmsg</span><span class="p">(</span><span class="n">when</span><span class="p">,</span> <span class="n">topicnick</span><span class="p">,</span> <span class="n">topicchan</span><span class="p">,</span> <span class="n">topicline</span><span class="p">,</span> <span class="o">**</span><span class="n">_</span><span class="p">):</span>
+    <span class="sd">&quot;&quot;&quot;Parses :class:`irclog.messages.TopicMessage`.&quot;&quot;&quot;</span>
+    <span class="k">return</span> <span class="n">irclog</span><span class="o">.</span><span class="n">messages</span><span class="o">.</span><span class="n">TopicMessage</span><span class="p">(</span><span class="n">when</span><span class="p">,</span> <span class="n">topicnick</span><span class="p">,</span> <span class="n">topicchan</span><span class="p">,</span> <span class="n">topicline</span><span class="p">)</span>
+
+</div>
+<span class="nd">@parser</span>
+<div class="viewcode-block" id="notopicmsg"><a class="viewcode-back" href="../../irclog/parser.html#irclog.parser.notopicmsg">[docs]</a><span class="k">def</span> <span class="nf">notopicmsg</span><span class="p">(</span><span class="n">when</span><span class="p">,</span> <span class="n">notopicnick</span><span class="p">,</span> <span class="n">notopicchan</span><span class="p">,</span> <span class="o">**</span><span class="n">_</span><span class="p">):</span>
+    <span class="sd">&quot;&quot;&quot;Parses :class:`irclog.messages.NoTopicMessage`.&quot;&quot;&quot;</span>
+    <span class="k">return</span> <span class="n">irclog</span><span class="o">.</span><span class="n">messages</span><span class="o">.</span><span class="n">TopicMessage</span><span class="p">(</span><span class="n">when</span><span class="p">,</span> <span class="n">notopicnick</span><span class="p">,</span> <span class="n">notopicchan</span><span class="p">)</span>
+
+</div>
+<span class="nd">@parser</span>
+<div class="viewcode-block" id="pubmsg"><a class="viewcode-back" href="../../irclog/parser.html#irclog.parser.pubmsg">[docs]</a><span class="k">def</span> <span class="nf">pubmsg</span><span class="p">(</span><span class="n">when</span><span class="p">,</span> <span class="n">pubnick</span><span class="p">,</span> <span class="n">publine</span><span class="p">,</span> <span class="o">**</span><span class="n">_</span><span class="p">):</span>
+    <span class="sd">&quot;&quot;&quot;Parses :class:`irclog.messages.PublicMessage`.&quot;&quot;&quot;</span>
+    <span class="k">return</span> <span class="n">irclog</span><span class="o">.</span><span class="n">messages</span><span class="o">.</span><span class="n">PublicMessage</span><span class="p">(</span><span class="n">when</span><span class="p">,</span> <span class="n">pubnick</span><span class="p">,</span> <span class="n">publine</span><span class="p">)</span>
+
+</div>
+<span class="nd">@parser</span>
+<div class="viewcode-block" id="actmsg"><a class="viewcode-back" href="../../irclog/parser.html#irclog.parser.actmsg">[docs]</a><span class="k">def</span> <span class="nf">actmsg</span><span class="p">(</span><span class="n">when</span><span class="p">,</span> <span class="n">actnick</span><span class="p">,</span> <span class="n">actline</span><span class="p">,</span> <span class="o">**</span><span class="n">_</span><span class="p">):</span>
+    <span class="sd">&quot;&quot;&quot;Parses :class:`irclog.messages.ActionMessage`.&quot;&quot;&quot;</span>
+    <span class="k">return</span> <span class="n">irclog</span><span class="o">.</span><span class="n">messages</span><span class="o">.</span><span class="n">ActionMessage</span><span class="p">(</span><span class="n">when</span><span class="p">,</span> <span class="n">pubnick</span><span class="p">,</span> <span class="n">publine</span><span class="p">)</span>
+
+</div>
+<span class="nd">@parser</span>
+<div class="viewcode-block" id="noticemsg"><a class="viewcode-back" href="../../irclog/parser.html#irclog.parser.noticemsg">[docs]</a><span class="k">def</span> <span class="nf">noticemsg</span><span class="p">(</span><span class="n">when</span><span class="p">,</span> <span class="n">noticenick</span><span class="p">,</span> <span class="n">noticechan</span><span class="p">,</span> <span class="n">noticeline</span><span class="p">,</span> <span class="o">**</span><span class="n">_</span><span class="p">):</span>
+    <span class="sd">&quot;&quot;&quot;Parses :class:`irclog.messages.ActionMessage`.&quot;&quot;&quot;</span>
+    <span class="k">return</span> <span class="n">irclog</span><span class="o">.</span><span class="n">messages</span><span class="o">.</span><span class="n">NoticeMessage</span><span class="p">(</span><span class="n">when</span><span class="p">,</span> <span class="n">noticenick</span><span class="p">,</span>
+                                         <span class="n">noticechan</span><span class="p">,</span> <span class="n">noticeline</span><span class="p">)</span>
+</pre></div></div>
+
+          </div>
+        </div>
+      </div>
+      <div class="sphinxsidebar">
+        <div class="sphinxsidebarwrapper">
+<div id="searchbox" style="display: none">
+  <h3>Quick search</h3>
+    <form class="search" action="../../search.html" method="get">
+      <input type="text" name="q" size="18" />
+      <input type="submit" value="Go" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    <p class="searchtip" style="font-size: 90%">
+    Enter search terms or a module, class or function name.
+    </p>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+        </div>
+      </div>
+      <div class="clearer"></div>
+    </div>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="../../genindex.html" title="General Index"
+             >index</a></li>
+        <li class="right" >
+          <a href="../../py-modindex.html" title="Python Module Index"
+             >modules</a> |</li>
+        <li><a href="../../index.html">irclog v0.1 documentation</a> &raquo;</li>
+          <li><a href="../index.html" >Module code</a> &raquo;</li> 
+      </ul>
+    </div>
+
+    <div class="footer">
+        &copy; Copyright 2010, Hong MinHee.
+      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.3.
+    </div>
+<script type="text/javascript">
+
+  var _gaq = _gaq || [];
+  _gaq.push(['_setAccount', 'UA-52596-12']);
+  _gaq.push(['_trackPageview']);
+
+  (function() {
+    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+  })();
+
+</script>
+
+  </body>
+</html>

irclog/_modules/irclog/tests.html

+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    
+    <title>irclog.tests &mdash; irclog v0.1 documentation</title>
+    <link rel="stylesheet" href="../../_static/mezzanine.css" type="text/css" />
+    <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:    '../../',
+        VERSION:     '0.1',
+        COLLAPSE_INDEX: false,
+        FILE_SUFFIX: '.html',
+        HAS_SOURCE:  true
+      };
+    </script>
+    <script type="text/javascript" src="../../_static/jquery.js"></script>
+    <script type="text/javascript" src="../../_static/underscore.js"></script>
+    <script type="text/javascript" src="../../_static/doctools.js"></script>
+    <link rel="top" title="irclog v0.1 documentation" href="../../index.html" />
+    <link rel="up" title="Module code" href="../index.html" /> 
+  </head>
+  <body>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="../../genindex.html" title="General Index"
+             accesskey="I">index</a></li>
+        <li class="right" >
+          <a href="../../py-modindex.html" title="Python Module Index"
+             >modules</a> |</li>
+        <li><a href="../../index.html">irclog v0.1 documentation</a> &raquo;</li>
+          <li><a href="../index.html" accesskey="U">Module code</a> &raquo;</li> 
+      </ul>
+    </div>  
+
+    <div class="document">
+      <div class="documentwrapper">
+        <div class="bodywrapper">
+          <div class="body">
+            
+  <h1>Source code for irclog.tests</h1><div class="highlight"><pre>
+<span class="sd">&quot;&quot;&quot;:mod:`irclog.tests` --- Unit tests</span>
+<span class="sd">~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</span>
+
+<span class="sd">.. data:: MODULES</span>
+
+<span class="sd">   The modules to test.</span>
+
+<span class="sd">&quot;&quot;&quot;</span>
+<span class="kn">import</span> <span class="nn">doctest</span>
+<span class="kn">import</span> <span class="nn">unittest</span>
+<span class="kn">import</span> <span class="nn">irclog.archive</span>
+
+
+<span class="n">MODULES</span> <span class="o">=</span> <span class="n">irclog</span><span class="o">.</span><span class="n">archive</span><span class="p">,</span>
+
+
+<div class="viewcode-block" id="suite"><a class="viewcode-back" href="../../irclog/tests.html#irclog.tests.suite">[docs]</a><span class="k">def</span> <span class="nf">suite</span><span class="p">():</span>
+    <span class="sd">&quot;&quot;&quot;Adapts doctests to :mod:`unittest` interface.</span>
+
+<span class="sd">    :returns: an adopted :class:`unittest.TestSuite` object</span>
+
+<span class="sd">    &quot;&quot;&quot;</span>
+    <span class="n">suite</span> <span class="o">=</span> <span class="n">unittest</span><span class="o">.</span><span class="n">TestSuite</span><span class="p">()</span>
+    <span class="k">for</span> <span class="n">mod</span> <span class="ow">in</span> <span class="n">MODULES</span><span class="p">:</span>
+        <span class="n">suite</span><span class="o">.</span><span class="n">addTest</span><span class="p">(</span><span class="n">doctest</span><span class="o">.</span><span class="n">DocTestSuite</span><span class="p">(</span><span class="n">mod</span><span class="p">))</span>
+    <span class="k">return</span> <span class="n">suite</span>
+</pre></div></div>
+
+          </div>
+        </div>
+      </div>
+      <div class="sphinxsidebar">
+        <div class="sphinxsidebarwrapper">
+<div id="searchbox" style="display: none">
+  <h3>Quick search</h3>
+    <form class="search" action="../../search.html" method="get">
+      <input type="text" name="q" size="18" />
+      <input type="submit" value="Go" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    <p class="searchtip" style="font-size: 90%">
+    Enter search terms or a module, class or function name.
+    </p>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+        </div>
+      </div>
+      <div class="clearer"></div>
+    </div>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="../../genindex.html" title="General Index"
+             >index</a></li>
+        <li class="right" >
+          <a href="../../py-modindex.html" title="Python Module Index"
+             >modules</a> |</li>
+        <li><a href="../../index.html">irclog v0.1 documentation</a> &raquo;</li>
+          <li><a href="../index.html" >Module code</a> &raquo;</li> 
+      </ul>
+    </div>
+
+    <div class="footer">
+        &copy; Copyright 2010, Hong MinHee.
+      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.3.
+    </div>
+<script type="text/javascript">
+
+  var _gaq = _gaq || [];
+  _gaq.push(['_setAccount', 'UA-52596-12']);
+  _gaq.push(['_trackPageview']);
+
+  (function() {
+    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+  })();
+
+</script>
+
+  </body>
+</html>

irclog/_modules/irclog/web.html

+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    
+    <title>irclog.web &mdash; irclog v0.1 documentation</title>
+    <link rel="stylesheet" href="../../_static/mezzanine.css" type="text/css" />
+    <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:    '../../',
+        VERSION:     '0.1',
+        COLLAPSE_INDEX: false,
+        FILE_SUFFIX: '.html',
+        HAS_SOURCE:  true
+      };
+    </script>
+    <script type="text/javascript" src="../../_static/jquery.js"></script>
+    <script type="text/javascript" src="../../_static/underscore.js"></script>
+    <script type="text/javascript" src="../../_static/doctools.js"></script>
+    <link rel="top" title="irclog v0.1 documentation" href="../../index.html" />
+    <link rel="up" title="Module code" href="../index.html" /> 
+  </head>
+  <body>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="../../genindex.html" title="General Index"
+             accesskey="I">index</a></li>
+        <li class="right" >
+          <a href="../../py-modindex.html" title="Python Module Index"
+             >modules</a> |</li>
+        <li><a href="../../index.html">irclog v0.1 documentation</a> &raquo;</li>
+          <li><a href="../index.html" accesskey="U">Module code</a> &raquo;</li> 
+      </ul>
+    </div>  
+
+    <div class="document">
+      <div class="documentwrapper">
+        <div class="bodywrapper">
+          <div class="body">
+            
+  <h1>Source code for irclog.web</h1><div class="highlight"><pre>
+<span class="sd">&quot;&quot;&quot;:mod:`irclog.web` --- Web IRC log view</span>
+<span class="sd">~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</span>
+
+<span class="sd">&quot;&quot;&quot;</span>
+<span class="kn">import</span> <span class="nn">re</span>
+<span class="kn">import</span> <span class="nn">datetime</span>
+<span class="kn">import</span> <span class="nn">functools</span>
+<span class="kn">import</span> <span class="nn">urllib</span>
+<span class="kn">import</span> <span class="nn">os.path</span>
+<span class="kn">import</span> <span class="nn">sys</span>
+<span class="kn">import</span> <span class="nn">traceback</span>
+<span class="kn">import</span> <span class="nn">json</span>
+<span class="kn">import</span> <span class="nn">jinja2</span>
+<span class="kn">import</span> <span class="nn">irclog.archive</span>
+<span class="kn">import</span> <span class="nn">irclog.messages</span>
+
+
+<span class="n">MIMETYPES</span> <span class="o">=</span> <span class="p">{</span><span class="s">&quot;jpg&quot;</span><span class="p">:</span> <span class="s">&quot;image/jpeg&quot;</span><span class="p">,</span> <span class="s">&quot;jpeg&quot;</span><span class="p">:</span> <span class="s">&quot;image/jpeg&quot;</span><span class="p">,</span> <span class="s">&quot;png&quot;</span><span class="p">:</span> <span class="s">&quot;image/png&quot;</span><span class="p">,</span>
+             <span class="s">&quot;gif&quot;</span><span class="p">:</span> <span class="s">&quot;image/gif&quot;</span><span class="p">,</span> <span class="s">&quot;ico&quot;</span><span class="p">:</span> <span class="s">&quot;image/vnd.microsoft.icon&quot;</span><span class="p">,</span>
+             <span class="s">&quot;css&quot;</span><span class="p">:</span> <span class="s">&quot;text/css&quot;</span><span class="p">,</span> <span class="s">&quot;html&quot;</span><span class="p">:</span> <span class="s">&quot;text/html&quot;</span><span class="p">,</span>
+             <span class="s">&quot;js&quot;</span><span class="p">:</span> <span class="s">&quot;text/javascript&quot;</span><span class="p">}</span>
+<span class="n">REDIR_STATUS_CODES</span> <span class="o">=</span> <span class="p">{</span><span class="mi">301</span><span class="p">:</span> <span class="s">&quot;301 Moved Permanently&quot;</span><span class="p">,</span>
+                      <span class="mi">302</span><span class="p">:</span> <span class="s">&quot;302 Found&quot;</span><span class="p">,</span>
+                      <span class="mi">303</span><span class="p">:</span> <span class="s">&quot;303 See Other&quot;</span><span class="p">,</span>
+                      <span class="mi">304</span><span class="p">:</span> <span class="s">&quot;304 Not Modified&quot;</span><span class="p">,</span>
+                      <span class="mi">305</span><span class="p">:</span> <span class="s">&quot;305 Use Proxy&quot;</span><span class="p">,</span>
+                      <span class="mi">307</span><span class="p">:</span> <span class="s">&quot;307 Temporary Redirect&quot;</span><span class="p">}</span>
+<span class="n">JINJA2_EXTENSIONS</span> <span class="o">=</span> <span class="p">[</span><span class="s">&quot;jinja2.ext.autoescape&quot;</span><span class="p">,</span> <span class="s">&quot;jinja2.ext.do&quot;</span><span class="p">]</span>
+
+
+<div class="viewcode-block" id="Application"><a class="viewcode-back" href="../../irclog/web.html#irclog.web.Application">[docs]</a><span class="k">class</span> <span class="nc">Application</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+    <span class="sd">&quot;&quot;&quot;WSGI application.</span>
+
+<span class="sd">    :param archive: an archive object or path</span>
+<span class="sd">    :type archive: :class:`Archive &lt;irclog.archive.Archive&gt;`,</span>
+<span class="sd">                   :class:`FilenamePattern &lt;irclog.archive.FilenamePattern&gt;`,</span>
+<span class="sd">                   :class:`basestring`</span>
+<span class="sd">    :param template_path: a path of template files</span>
+<span class="sd">    :type template_path: :class:`basestring`</span>
+<span class="sd">    :param path_prefix: a prefix for the path. default is an empty string</span>
+<span class="sd">    :type path_prefix: :class:`basestring`</span>
+<span class="sd">    :param encoding: an encoding of response text. default is ``&quot;utf-8&quot;``</span>
+<span class="sd">    :type encoding: :class:`basestring`</span>
+<span class="sd">    :param debug: a debug flag. default is ``False``</span>
+<span class="sd">    :type debug: :class:`bool`</span>
+
+
+<span class="sd">    .. data:: STATIC_PATH_PATTERN</span>
+
+<span class="sd">    .. data:: PATH_MAP</span>
+
+<span class="sd">       The :class:`list`: of :class:`tuple` contains template name, routing</span>
+<span class="sd">       pattern and object getting function.</span>
+
+<span class="sd">       Form is like following::</span>
+
+<span class="sd">           [(&quot;template.html&quot;, re.compile(&quot;url regex&quot;), lambda app, ...: ...)]</span>
+
+<span class="sd">    .. attribute:: archive</span>
+<span class="sd">    </span>
+<span class="sd">       The :class:`Archive &lt;irclog.archive.Archive&gt;` object.</span>
+
+<span class="sd">    .. attribute:: template_path</span>
+
+<span class="sd">       The path of template files.</span>
+
+<span class="sd">    .. attribute:: template_environment</span>
+
+<span class="sd">       The Jinja2 template environment. A :class:`jinja2.Environment` instance.</span>
+
+<span class="sd">    .. attribute:: path_prefix</span>
+
+<span class="sd">       The prefix of the path.</span>
+
+<span class="sd">    .. attribute:: encoding</span>
+
+<span class="sd">       The encoding of response text.</span>
+
+<span class="sd">    .. attribute:: debug</span>
+
+<span class="sd">       The debug flag.</span>
+
+<span class="sd">    &quot;&quot;&quot;</span>
+
+    <span class="n">STATIC_PATH_PATTERN</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="s">r&quot;^/_/static/_/(?P&lt;file&gt;.+)$&quot;</span><span class="p">)</span>
+    <span class="n">PATH_MAP</span> <span class="o">=</span> <span class="p">[]</span>
+
+    <span class="n">__slots__</span> <span class="o">=</span> <span class="s">&quot;archive&quot;</span><span class="p">,</span> <span class="s">&quot;template_path&quot;</span><span class="p">,</span> <span class="s">&quot;template_environment&quot;</span><span class="p">,</span> \
+                <span class="s">&quot;path_prefix&quot;</span><span class="p">,</span> <span class="s">&quot;encoding&quot;</span><span class="p">,</span> <span class="s">&quot;debug&quot;</span>
+
+    <span class="nd">@classmethod</span>
+<div class="viewcode-block" id="Application.route"><a class="viewcode-back" href="../../irclog/web.html#irclog.web.Application.route">[docs]</a>    <span class="k">def</span> <span class="nf">route</span><span class="p">(</span><span class="n">cls</span><span class="p">,</span> <span class="n">template_name</span><span class="p">,</span> <span class="n">pattern_string</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot;Registers a function as request handler.</span>
+
+<span class="sd">        .. sourcecode:: pycon</span>
+
+<span class="sd">           &gt;&gt;&gt; __tmp__ = Application.PATH_MAP</span>
+<span class="sd">           &gt;&gt;&gt; Application.PATH_MAP = []</span>
+<span class="sd">           &gt;&gt;&gt; Application.PATH_MAP</span>
+<span class="sd">           []</span>
+<span class="sd">           &gt;&gt;&gt; @Application.route(&quot;myhandler.html&quot;, r&quot;^/(?P&lt;a&gt;.)/(?P&lt;b&gt;.)/?$&quot;)</span>
+<span class="sd">           ... def myhandler(app, a, b):</span>
+<span class="sd">           ...     return {&quot;a&quot;: a, &quot;b&quot;: b}</span>
+<span class="sd">           ...</span>
+<span class="sd">           &gt;&gt;&gt; Application.PATH_MAP  # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS</span>
+<span class="sd">           [(&#39;myhandler.html&#39;, &lt;_sre.SRE_Pattern object at ...&gt;,</span>
+<span class="sd">             &lt;function myhandler at ...&gt;)]</span>
+<span class="sd">           &gt;&gt;&gt; Application.PATH_MAP = __tmp__</span>
+
+<span class="sd">        :param template_name: a template filename</span>
+<span class="sd">        :type template_name: :class:`basestring`</span>
+<span class="sd">        :param pattern_string: a pattern of URL to route</span>
+<span class="sd">        :type pattern_string: :class:`basestring`</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="k">def</span> <span class="nf">decorate</span><span class="p">(</span><span class="n">function</span><span class="p">):</span>
+            <span class="n">pattern</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="n">pattern_string</span><span class="p">)</span>
+            <span class="n">cls</span><span class="o">.</span><span class="n">PATH_MAP</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">template_name</span><span class="p">,</span> <span class="n">pattern</span><span class="p">,</span> <span class="n">function</span><span class="p">))</span>
+            <span class="k">return</span> <span class="n">function</span>
+        <span class="k">return</span> <span class="n">decorate</span>
+</div>
+    <span class="nd">@classmethod</span>
+<div class="viewcode-block" id="Application.redirect"><a class="viewcode-back" href="../../irclog/web.html#irclog.web.Application.redirect">[docs]</a>    <span class="k">def</span> <span class="nf">redirect</span><span class="p">(</span><span class="n">cls</span><span class="p">,</span> <span class="n">pattern_string</span><span class="p">,</span> <span class="n">status_code</span><span class="o">=</span><span class="mi">307</span><span class="p">):</span>
+        <span class="sd">&quot;&quot;&quot;Registers a redirection handler.</span>
+
+<span class="sd">        .. sourcecode:: pycon</span>
+
+<span class="sd">           &gt;&gt;&gt; __tmp__ = Application.PATH_MAP</span>
+<span class="sd">           &gt;&gt;&gt; Application.PATH_MAP = []</span>
+<span class="sd">           &gt;&gt;&gt; Application.PATH_MAP</span>
+<span class="sd">           []</span>
+<span class="sd">           &gt;&gt;&gt; @Application.redirect(r&quot;^/(?P&lt;a&gt;.)/(?P&lt;b&gt;.)/?$&quot;, 301)</span>
+<span class="sd">           ... def redirect(app, a, b):</span>
+<span class="sd">           ...     return &quot;/url/{0}/{1}&quot;.format(a, b)</span>
+<span class="sd">           ...</span>
+<span class="sd">           &gt;&gt;&gt; Application.PATH_MAP  # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS</span>
+<span class="sd">           [(301, &lt;_sre.SRE_Pattern object at ...&gt;,</span>
+<span class="sd">             &lt;function redirect at ...&gt;)]</span>
+<span class="sd">           &gt;&gt;&gt; Application.PATH_MAP = __tmp__</span>
+
+<span class="sd">        :param pattern_string: a pattern of URL to route</span>
+<span class="sd">        :type pattern_string: :class:`basestring`</span>
+
+<span class="sd">        &quot;&quot;&quot;</span>
+        <span class="k">def</span> <span class="nf">decorate</span><span class="p">(</span><span class="n">function</span><span class="p">):</span>
+            <span class="n">pattern</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="n">pattern_string</span><span class="p">)</span>
+            <span class="n">cls</span><span class="o">.</span><span class="n">PATH_MAP</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">status_code</span><span class="p">,</span> <span class="n">pattern</span><span class="p">,</span> <span class="n">function</span><span class="p">))</span>
+            <span class="k">return</span> <span class="n">function</span>
+        <span class="k">return</span> <span class="n">decorate</span>
+</div>
+    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">archive</span><span class="p">,</span> <span class="n">template_path</span><span class="p">,</span>
+                 <span class="n">path_prefix</span><span class="o">=</span><span class="s">&quot;&quot;</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s">&quot;utf-8&quot;</span><span class="p">,</span> <span class="n">debug</span><span class="o">=</span><span class="bp">False</span><span class="p">):</span>
+        <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">archive</span><span class="p">,</span> <span class="n">irclog</span><span class="o">.</span><span class="n">archive</span><span class="o">.</span><span class="n">Archive</span><span class="p">):</span>
+            <span class="n">archive</span> <span class="o">=</span> <span class="n">irclog</span><span class="o">.</span><span class="n">archive</span><span class="o">.</span><span class="n">Archive</span><span class="p">(</span><span class="n">archive</span><span class="p">)</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">archive</span> <span class="o">=</span> <span class="n">archive</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">template_path</span> <span class="o">=</span> <span class="n">template_path</span>
+        <span class="n">loader</span> <span class="o">=</span> <span class="n">jinja2</span><span class="o">.</span><span class="n">FileSystemLoader</span><span class="p">(</span><span class="n">template_path</span><span class="p">)</span>
+        <span class="n">environ</span> <span class="o">=</span> <span class="n">jinja2</span><span class="o">.</span><span class="n">Environment</span><span class="p">(</span><span class="n">loader</span><span class="o">=</span><span class="n">loader</span><span class="p">,</span>
+                                     <span class="n">autoescape</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span>
+                                     <span class="n">extensions</span><span class="o">=</span><span class="n">JINJA2_EXTENSIONS</span><span class="p">)</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">template_environment</span> <span class="o">=</span> <span class="n">environ</span>
+        <span class="n">setup_template_environment</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">template_environment</span><span class="p">)</span>
+        <span class="k">if</span> <span class="n">path_prefix</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s">&quot;/&quot;</span><span class="p">):</span>
+            <span class="n">path_prefix</span> <span class="o">=</span> <span class="n">path_prefix</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">path_prefix</span> <span class="o">=</span> <span class="n">path_prefix</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">encoding</span> <span class="o">=</span> <span class="n">encoding</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">debug</span> <span class="o">=</span> <span class="n">debug</span>
+
+    <span class="k">def</span> <span class="nf">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">environ</span><span class="p">,</span> <span class="n">start_response</span><span class="p">):</span>
+        <span class="k">try</span><span class="p">:</span>
+            <span class="k">if</span> <span class="n">environ</span><span class="p">[</span><span class="s">&quot;PATH_INFO&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">path_prefix</span><span class="p">):</span>
+                <span class="n">prefix_len</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">path_prefix</span><span class="p">)</span>
+                <span class="n">environ</span><span class="p">[</span><span class="s">&quot;PATH_INFO&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">environ</span><span class="p">[</span><span class="s">&quot;PATH_INFO&quot;</span><span class="p">][</span><span class="n">prefix_len</span><span class="p">:]</span>
+                <span class="k">if</span> <span class="s">&quot;RAW_URI&quot;</span> <span class="ow">in</span> <span class="n">environ</span><span class="p">:</span>
+                    <span class="n">environ</span><span class="p">[</span><span class="s">&quot;RAW_URI&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">environ</span><span class="p">[</span><span class="s">&quot;RAW_URI&quot;</span><span class="p">][</span><span class="n">prefix_len</span><span class="p">:]</span>
+            <span class="k">else</span><span class="p">:</span>
+                <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">error_404</span><span class="p">(</span><span class="n">environ</span><span class="p">,</span> <span class="n">start_response</span><span class="p">)</span>
+            <span class="n">match</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">STATIC_PATH_PATTERN</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">environ</span><span class="p">[</span><span class="s">&quot;PATH_INFO&quot;</span><span class="p">])</span>
+            <span class="k">if</span> <span class="n">match</span><span class="p">:</span>
+                <span class="n">r</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">serve_static_resources</span><span class="p">(</span><span class="n">environ</span><span class="p">,</span> <span class="n">start_response</span><span class="p">,</span> <span class="n">match</span><span class="p">)</span>
+                <span class="k">return</span> <span class="n">r</span>
+            <span class="k">else</span><span class="p">:</span>
+                <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">serve_application</span><span class="p">(</span><span class="n">environ</span><span class="p">,</span> <span class="n">start_response</span><span class="p">)</span>
+        <span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
+            <span class="n">exc_info</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()</span>
+            <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">error_500</span><span class="p">(</span><span class="n">environ</span><span class="p">,</span> <span class="n">start_response</span><span class="p">,</span> <span class="n">exc_info</span><span class="p">)</span>
+
+    <span class="k">def</span> <span class="nf">serve_application</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">environ</span><span class="p">,</span> <span class="n">start_response</span><span class="p">):</span>
+        <span class="k">for</span> <span class="n">template_name</span><span class="p">,</span> <span class="n">pattern</span><span class="p">,</span> <span class="n">handle</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">PATH_MAP</span><span class="p">:</span>
+            <span class="n">match</span> <span class="o">=</span> <span class="n">pattern</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">environ</span><span class="p">[</span><span class="s">&quot;PATH_INFO&quot;</span><span class="p">])</span>
+            <span class="k">if</span> <span class="n">match</span><span class="p">:</span>
+                <span class="k">try</span><span class="p">:</span>
+                    <span class="n">context</span> <span class="o">=</span> <span class="n">handle</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">match</span><span class="o">.</span><span class="n">groupdict</span><span class="p">())</span>
+                <span class="k">except</span> <span class="ne">LookupError</span><span class="p">:</span>
+                    <span class="k">continue</span>
+                <span class="k">if</span> <span class="n">template_name</span> <span class="ow">in</span> <span class="n">REDIR_STATUS_CODES</span><span class="p">:</span>
+                    <span class="n">start_response</span><span class="p">(</span>
+                        <span class="n">REDIR_STATUS_CODES</span><span class="p">[</span><span class="n">template_name</span><span class="p">],</span>
+                        <span class="p">[(</span><span class="s">&quot;Location&quot;</span><span class="p">,</span> <span class="n">context</span><span class="p">),</span> <span class="p">(</span><span class="s">&quot;Content-Type&quot;</span><span class="p">,</span> <span class="s">&quot;text/plain&quot;</span><span class="p">)]</span>
+                    <span class="p">)</span>
+                    <span class="k">return</span> <span class="s">&quot;Go {0}&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">context</span><span class="p">)</span>
+                <span class="k">if</span> <span class="s">&quot;__app__&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">context</span><span class="p">:</span>
+                    <span class="n">context</span><span class="p">[</span><span class="s">&quot;__app__&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span>
+                <span class="n">tpl</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">template_environment</span><span class="o">.</span><span class="n">get_template</span><span class="p">(</span><span class="n">template_name</span><span class="p">)</span>
+                <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">debug</span><span class="p">:</span>
+                    <span class="n">result</span> <span class="o">=</span> <span class="n">tpl</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">context</span><span class="p">)</span>
+                <span class="k">else</span><span class="p">:</span>
+                    <span class="n">result</span> <span class="o">=</span> <span class="n">tpl</span><span class="o">.</span><span class="n">generate</span><span class="p">(</span><span class="n">context</span><span class="p">)</span>
+                <span class="n">content_type</span> <span class="o">=</span> <span class="s">&quot;text/html; charset=&quot;</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">encoding</span>
+                <span class="n">start_response</span><span class="p">(</span><span class="s">&quot;200 OK&quot;</span><span class="p">,</span> <span class="p">[(</span><span class="s">&quot;Content-Type&quot;</span><span class="p">,</span> <span class="n">content_type</span><span class="p">)])</span>
+                <span class="k">return</span> <span class="p">(</span><span class="nb">buffer</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">encoding</span><span class="p">)</span> <span class="k">for</span> <span class="nb">buffer</span> <span class="ow">in</span> <span class="n">result</span><span class="p">)</span>
+        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">error_404</span><span class="p">(</span><span class="n">environ</span><span class="p">,</span> <span class="n">start_response</span><span class="p">)</span>
+
+    <span class="k">def</span> <span class="nf">serve_static_resources</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">environ</span><span class="p">,</span> <span class="n">start_response</span><span class="p">,</span> <span class="n">match</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
+        <span class="n">match</span> <span class="o">=</span> <span class="n">match</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">STATIC_PATH_PATTERN</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
+        <span class="n">path</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">template_path</span><span class="p">,</span>
+                            <span class="o">*</span><span class="n">match</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="s">&quot;file&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&quot;/&quot;</span><span class="p">))</span>
+        <span class="n">_</span><span class="p">,</span> <span class="n">suffix</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">rsplit</span><span class="p">(</span><span class="s">&quot;.&quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
+        <span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isfile</span><span class="p">(</span><span class="n">path</span><span class="p">):</span>
+            <span class="n">content_type</span> <span class="o">=</span> <span class="n">MIMETYPES</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">suffix</span><span class="p">,</span> <span class="s">&quot;application/octet-stream&quot;</span><span class="p">)</span>
+            <span class="n">start_response</span><span class="p">(</span><span class="s">&quot;200 OK&quot;</span><span class="p">,</span> <span class="p">[(</span><span class="s">&quot;Content-Type&quot;</span><span class="p">,</span> <span class="n">content_type</span><span class="p">)])</span>
+            <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">path</span><span class="p">)</span> <span class="k">as</span> <span class="nb">file</span><span class="p">:</span>
+                <span class="k">for</span> <span class="nb">buffer</span> <span class="ow">in</span> <span class="nb">file</span><span class="p">:</span>
+                    <span class="k">yield</span> <span class="nb">buffer</span>
+        <span class="k">else</span><span class="p">:</span>
+            <span class="k">for</span> <span class="nb">buffer</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">error_404</span><span class="p">(</span><span class="n">environ</span><span class="p">,</span> <span class="n">start_response</span><span class="p">):</span>
+                <span class="k">yield</span> <span class="nb">buffer</span>
+
+    <span class="k">def</span> <span class="nf">error_404</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">environ</span><span class="p">,</span> <span class="n">start_response</span><span class="p">):</span>
+        <span class="n">start_response</span><span class="p">(</span><span class="s">&quot;404 Not Found&quot;</span><span class="p">,</span> <span class="p">[(</span><span class="s">&quot;Content-Type&quot;</span><span class="p">,</span> <span class="s">&quot;text/plain&quot;</span><span class="p">)])</span>
+        <span class="k">return</span> <span class="s">&quot;page not found&quot;</span><span class="p">,</span>
+
+    <span class="k">def</span> <span class="nf">error_500</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">environ</span><span class="p">,</span> <span class="n">start_response</span><span class="p">,</span> <span class="n">exc_info</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
+        <span class="n">start_response</span><span class="p">(</span><span class="s">&quot;500 Internal Server Error&quot;</span><span class="p">,</span>
+                       <span class="p">[(</span><span class="s">&quot;Content-Type&quot;</span><span class="p">,</span> <span class="s">&quot;text/plain&quot;</span><span class="p">)])</span>
+        <span class="k">yield</span> <span class="s">&quot;internal server error&quot;</span>
+        <span class="k">if</span> <span class="n">exc_info</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">debug</span><span class="p">:</span>
+            <span class="k">yield</span> <span class="s">&quot;</span><span class="se">\n\n</span><span class="s">&quot;</span>
+            <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">traceback</span><span class="o">.</span><span class="n">format_exception</span><span class="p">(</span><span class="o">*</span><span class="n">exc_info</span><span class="p">):</span>
+                <span class="k">yield</span> <span class="n">line</span>
+
+</div>
+<span class="nd">@Application.route</span><span class="p">(</span><span class="s">&quot;archive.html&quot;</span><span class="p">,</span> <span class="s">r&quot;^/?$&quot;</span><span class="p">)</span>
+<span class="k">def</span> <span class="nf">handle_archive</span><span class="p">(</span><span class="n">app</span><span class="p">):</span>
+    <span class="k">return</span> <span class="p">{</span><span class="s">&quot;archive&quot;</span><span class="p">:</span> <span class="n">app</span><span class="o">.</span><span class="n">archive</span><span class="p">}</span>
+
+
+<span class="nd">@Application.route</span><span class="p">(</span><span class="s">&quot;server.html&quot;</span><span class="p">,</span> <span class="s">r&quot;^/(?P&lt;server&gt;.+?)/?$&quot;</span><span class="p">)</span>
+<span class="k">def</span> <span class="nf">handle_server</span><span class="p">(</span><span class="n">app</span><span class="p">,</span> <span class="n">server</span><span class="p">):</span>
+    <span class="n">context</span> <span class="o">=</span> <span class="n">handle_archive</span><span class="p">(</span><span class="n">app</span><span class="p">)</span>
+    <span class="n">context</span><span class="p">[</span><span class="s">&quot;server&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">app</span><span class="o">.</span><span class="n">archive</span><span class="p">[</span><span class="n">server</span><span class="p">]</span>
+    <span class="k">return</span> <span class="n">context</span>
+
+
+<span class="nd">@Application.route</span><span class="p">(</span><span class="s">&quot;channel.html&quot;</span><span class="p">,</span> <span class="s">r&quot;^/(?P&lt;server&gt;.+?)/(?P&lt;channel&gt;.*?)/?$&quot;</span><span class="p">)</span>
+<span class="k">def</span> <span class="nf">handle_channel</span><span class="p">(</span><span class="n">app</span><span class="p">,</span> <span class="n">server</span><span class="p">,</span> <span class="n">channel</span><span class="p">):</span>
+    <span class="n">context</span> <span class="o">=</span> <span class="n">handle_server</span><span class="p">(</span><span class="n">app</span><span class="p">,</span> <span class="n">server</span><span class="p">)</span>
+    <span class="n">context</span><span class="p">[</span><span class="s">&quot;channel&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">context</span><span class="p">[</span><span class="s">&quot;server&quot;</span><span class="p">][</span><span class="n">channel</span><span class="p">]</span>
+    <span class="k">return</span> <span class="n">context</span>
+
+
+<span class="nd">@Application.redirect</span><span class="p">(</span><span class="s">r&quot;^/(?P&lt;server&gt;.+?)/(?P&lt;channel&gt;.*?)/today$&quot;</span><span class="p">)</span>
+<span class="k">def</span> <span class="nf">redirect_today_log</span><span class="p">(</span><span class="n">app</span><span class="p">,</span> <span class="n">server</span><span class="p">,</span> <span class="n">channel</span><span class="p">):</span>
+    <span class="n">date</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">date</span><span class="o">.</span><span class="n">today</span><span class="p">()</span>
+    <span class="k">return</span> <span class="n">date</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="s">&quot;%Y-%m-</span><span class="si">%d</span><span class="s">&quot;</span><span class="p">)</span>
+
+
+<span class="nd">@Application.route</span><span class="p">(</span><span class="s">&quot;log.html&quot;</span><span class="p">,</span> <span class="s">r&quot;^/(?P&lt;server&gt;.+?)/(?P&lt;channel&gt;.*?)&quot;</span>
+                               <span class="s">r&quot;/(?P&lt;date&gt;\d{4}-\d\d-\d\d)$&quot;</span><span class="p">)</span>
+<span class="k">def</span> <span class="nf">handle_log</span><span class="p">(</span><span class="n">app</span><span class="p">,</span> <span class="n">server</span><span class="p">,</span> <span class="n">channel</span><span class="p">,</span> <span class="n">date</span><span class="p">):</span>
+    <span class="n">date</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">date</span><span class="p">(</span><span class="o">*</span><span class="nb">map</span><span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="n">date</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&quot;-&quot;</span><span class="p">)))</span>
+    <span class="n">context</span> <span class="o">=</span> <span class="n">handle_channel</span><span class="p">(</span><span class="n">app</span><span class="p">,</span> <span class="n">server</span><span class="p">,</span> <span class="n">channel</span><span class="p">)</span>
+    <span class="n">context</span><span class="p">[</span><span class="s">&quot;log&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">context</span><span class="p">[</span><span class="s">&quot;channel&quot;</span><span class="p">][</span><span class="n">date</span><span class="p">]</span>
+    <span class="k">return</span> <span class="n">context</span>
+
+
+<div class="viewcode-block" id="setup_template_environment"><a class="viewcode-back" href="../../irclog/web.html#irclog.web.setup_template_environment">[docs]</a><span class="k">def</span> <span class="nf">setup_template_environment</span><span class="p">(</span><span class="n">environment</span><span class="p">):</span>
+    <span class="sd">&quot;&quot;&quot;Sets up the Jinja2 environment.</span>
+
+<span class="sd">    :param environment: a Jinja2 environment</span>
+<span class="sd">    :type environment: :class:`jinja2.Environment`</span>
+
+<span class="sd">    &quot;&quot;&quot;</span>
+    <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">environment</span><span class="p">,</span> <span class="n">jinja2</span><span class="o">.</span><span class="n">Environment</span><span class="p">):</span>
+        <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s">&quot;expected a jinja2.environment.Environment instance,&quot;</span>
+                        <span class="s">&quot;not &quot;</span> <span class="o">+</span> <span class="nb">repr</span><span class="p">(</span><span class="n">environment</span><span class="p">))</span>
+    <span class="k">def</span> <span class="nf">require</span><span class="p">(</span><span class="n">module</span><span class="p">):</span>
+        <span class="k">if</span> <span class="s">&quot;:&quot;</span> <span class="ow">in</span> <span class="n">module</span><span class="p">:</span>
+            <span class="n">module</span><span class="p">,</span> <span class="n">var</span> <span class="o">=</span> <span class="n">module</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&quot;:&quot;</span><span class="p">)</span>
+        <span class="k">else</span><span class="p">:</span>
+            <span class="n">var</span> <span class="o">=</span> <span class="bp">None</span>
+        <span class="n">mod</span> <span class="o">=</span> <span class="nb">__import__</span><span class="p">(</span><span class="n">module</span><span class="p">)</span>
+        <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">module</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&quot;.&quot;</span><span class="p">)[</span><span class="mi">1</span><span class="p">:]:</span>
+            <span class="n">mod</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">mod</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span>
+        <span class="k">if</span> <span class="n">var</span><span class="p">:</span>
+            <span class="k">return</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">mod</span><span class="p">,</span> <span class="n">var</span><span class="p">)</span>