# Path: logviewer/exc.py
# class AuthenticationError(RuntimeError):
#     pass
# 
# Path: logviewer/parser.py
# def parse_log(fp, start=None):
#     def extract_time(match):
#         t = match.group('timestamp')
#         try:
#             # ISO 8601
#             timestamp = t.split('.')[0]
#             return datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%S')
#         except ValueError:
#             # RFC 2822
#             t = email.utils.parsedate(t)
#             if t is not None:
#             	t = time.mktime(t)
#             else:
#             	t = 0 # fail
#             return datetime.fromtimestamp(t)
# 
#     no = 0
#     for line in fp:
#         m = LINE_PATTERN.match(line)
#         if not m:
#             continue
# 
#         if 'PRIVMSG' in m.group('data'):
#             no += 1
# 
#             if start and no < start:
#                 continue
#             pm = PRIVMSG_PATTERN.match(m.group('data'))
#             if not pm:
#                 continue
# 
#             is_bot = not pm.group('nick')
#             pmm = PROXY_MSG_PATTERN.match(pm.group('text'))
#             if is_bot and pmm:
#                 nick = pmm.group('nick')
#                 text = pmm.group('text')
#                 is_bot = False
#             else:
#                 nick = pm.group('nick')
#                 text = pm.group('text')
# 
#             yield dict(type='privmsg', no=no,
#                 time=extract_time(m),
#                 nick=nick, text=text, is_bot=is_bot)
#         elif (m.group('dir') == '>>>' and start is None and
#               m.group('data').startswith('JOIN ') and
#               JOIN_PATTERN.match(m.group('data'))):
#             yield dict(type='join', time=extract_time(m), is_bot=True, no=-1)
# 
# Path: logviewer/routing.py
# class DateConverter(BaseConverter):
#     def to_python(self, value):
#     def to_url(self, value):
# 
# Path: logviewer/util.py
# def irc_channels(config):


import os
import io
import re
import time
import json
import random
import datetime
import itertools
import functools
import sqlite3
import sphinxapi
import flask
from contextlib import closing
from flask import (Flask, request, redirect, session, url_for, render_template,
                   current_app, jsonify)
from logviewer.exc import AuthenticationError
from logviewer.parser import parse_log
from logviewer import routing, util
    if channel not in channel_names:
        flask.abort(404)
    return channel


def login_required(f):
    @functools.wraps(f)
    def _wrapped(*args, **kwargs):
        if 'username' not in session:
            return redirect(url_for('login', next=request.url))
        return f(*args, **kwargs)
    return _wrapped


@app.route('/favicon.ico')
def favicon():
    flask.abort(404)  # it's very annoying.


@app.route('/login', methods=['GET', 'POST'])
def login():
    auth = app.config['AUTH_BACKEND']
    return auth.login(error=None)


@app.route('/login/authenticate', methods=['GET', 'POST'])
def authenticate():
    auth = app.config['AUTH_BACKEND']
    try:
        result = auth.authenticate()

# Path: logviewer/exc.py
# class AuthenticationError(RuntimeError):
#     pass
# 
# Path: logviewer/parser.py
# def parse_log(fp, start=None):
#     def extract_time(match):
#         t = match.group('timestamp')
#         try:
#             # ISO 8601
#             timestamp = t.split('.')[0]
#             return datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%S')
#         except ValueError:
#             # RFC 2822
#             t = email.utils.parsedate(t)
#             if t is not None:
#             	t = time.mktime(t)
#             else:
#             	t = 0 # fail
#             return datetime.fromtimestamp(t)
# 
#     no = 0
#     for line in fp:
#         m = LINE_PATTERN.match(line)
#         if not m:
#             continue
# 
#         if 'PRIVMSG' in m.group('data'):
#             no += 1
# 
#             if start and no < start:
#                 continue
#             pm = PRIVMSG_PATTERN.match(m.group('data'))
#             if not pm:
#                 continue
# 
#             is_bot = not pm.group('nick')
#             pmm = PROXY_MSG_PATTERN.match(pm.group('text'))
#             if is_bot and pmm:
#                 nick = pmm.group('nick')
#                 text = pmm.group('text')
#                 is_bot = False
#             else:
#                 nick = pm.group('nick')
#                 text = pm.group('text')
# 
#             yield dict(type='privmsg', no=no,
#                 time=extract_time(m),
#                 nick=nick, text=text, is_bot=is_bot)
#         elif (m.group('dir') == '>>>' and start is None and
#               m.group('data').startswith('JOIN ') and
#               JOIN_PATTERN.match(m.group('data'))):
#             yield dict(type='join', time=extract_time(m), is_bot=True, no=-1)
# 
# Path: logviewer/routing.py
# class DateConverter(BaseConverter):
#     def to_python(self, value):
#     def to_url(self, value):
# 
# Path: logviewer/util.py
# def irc_channels(config):


# Path: logviewer/app.py
import os
import io
import re
import time
import json
import random
import datetime
import itertools
import functools
import sqlite3
import sphinxapi
import flask
from contextlib import closing
from flask import (Flask, request, redirect, session, url_for, render_template,
                   current_app, jsonify)
from logviewer.exc import AuthenticationError
from logviewer.parser import parse_log
from logviewer import routing, util

    if channel not in channel_names:
        flask.abort(404)
    return channel


def login_required(f):
    @functools.wraps(f)
    def _wrapped(*args, **kwargs):
        if 'username' not in session:
            return redirect(url_for('login', next=request.url))
        return f(*args, **kwargs)
    return _wrapped


@app.route('/favicon.ico')
def favicon():
    flask.abort(404)  # it's very annoying.


@app.route('/login', methods=['GET', 'POST'])
def login():
    auth = app.config['AUTH_BACKEND']
    return auth.login(error=None)


@app.route('/login/authenticate', methods=['GET', 'POST'])
def authenticate():
    auth = app.config['AUTH_BACKEND']
    try:
        result = auth.authenticate()

    except AuthenticationError as e: