log.py 4.46 KB
import os
from datetime import timedelta
from pkg_resources import resource_filename
from sqlalchemy import func
from pyramid.view import view_config
from pyramid.httpexceptions import HTTPFound
from paginate_sqlalchemy import SqlalchemyOrmPage
import colander
from deform import (
    Form,
    widget,
    Button,
    ZPTRendererFactory,
    ValidationFailure,
    )
from ..models import DBSession
from ..models.log import (
    Log,
    Jenis,
    )
from ..tools.waktu import (
    datetime_from_str,
    create_now,
    )
from ..tools.string import dict_to_str


LIMIT = 100

def get_page(request):
    page = request.GET.get('page')
    return page and int(page) or 1


def get_jenis_list():
    q = DBSession.query(Jenis).order_by(Jenis.nama)
    values = []
    for row in q:
        row = (str(row.id), row.nama)
        values.append(row)
    return values


@colander.deferred
def jenis_widget(node, kw):
    return widget.SelectWidget(values=kw['jenis_list'])


class FilterSchema(colander.Schema):
    awal = colander.SchemaNode(colander.String())
    akhir = colander.SchemaNode(colander.String(), missing=colander.drop)
    jenis = colander.SchemaNode(
            colander.String(), missing=colander.drop, widget=jenis_widget)
    keterangan = colander.SchemaNode(colander.String(), missing=colander.drop)


deform_templates = resource_filename('deform', 'templates')
here = os.path.abspath(os.path.dirname(__file__))
my_templates = os.path.join(here, 'templates', 'log')
search_path = [my_templates, deform_templates]
my_renderer = ZPTRendererFactory(search_path)


def get_form():
    schema = FilterSchema()
    schema = schema.bind(jenis_list=get_jenis_list())
    btn_lihat = Button('lihat', 'Lihat')
    btn_terbaru = Button('terbaru', 'Terbaru')
    buttons = (btn_lihat, btn_terbaru)
    return Form(schema, buttons=buttons, renderer=my_renderer)


@view_config(
    route_name='log', renderer='templates/log/list.pt', permission='view')
def view_list(request):
    def url_maker(page):
        d['page'] = page
        d['lihat'] = 1
        return request.route_url('log', _query=d)

    form = get_form()
    resp = dict(title='Log file')
    if request.POST:
        items = request.POST.items()
        try:
            c = form.validate(items)
        except ValidationFailure as e:
            resp['form'] = e.render()
            return resp
        p = dict(c.items())
        if 'terbaru' in request.POST:
            p['awal'] = default_awal(p['jenis'])
        p['lihat'] = 1 
        return route_list(request, p)
    if 'awal' not in request.GET:
        p = default_filter()
        return route_list(request, p)
    p = get_filter(request)
    d = dict_to_str(p)
    resp['form'] = form.render(appstruct=d)
    if 'lihat' not in request.GET:
        return resp
    q = get_query(p)
    resp['count'] = count = q.count()
    q = q.order_by(Log.tgl)
    page = get_page(request)
    resp['rows'] = SqlalchemyOrmPage(
        q, page=page, items_per_page=10, item_count=count,
        url_maker=url_maker)
    return resp
 

def default_filter():
    jenis = get_last_jenis_trx()
    awal = default_awal(jenis)
    p = dict(jenis=jenis, awal=awal)
    return p


def default_awal(jenis):
    q = DBSession.query(Log).filter_by(jenis_id=jenis)
    jml = q.count()
    if jml >= LIMIT:
        offset = jml - LIMIT 
    else:
        offset = 0
    q = DBSession.query(Log.tgl).filter_by(jenis_id=jenis).\
            order_by(Log.tgl).offset(offset).limit(1)
    row = q.first()
    if row:
        return row.tgl
    return create_now()

 
def get_filter(request):
    p = dict(jenis=int(request.params.get('jenis')))
    p['awal'] = datetime_from_str(request.params['awal'])
    akhir = request.params.get('akhir')
    if akhir:
        p['akhir'] = datetime_from_str(akhir)
    keterangan = request.params.get('keterangan') 
    if keterangan:
        p['keterangan'] = keterangan
    return p


def get_query(p):
    q = DBSession.query(Log).filter_by(jenis_id=p['jenis']).\
            filter(Log.tgl >= p['awal'])
    if 'akhir' in p:
        q = q.filter(Log.tgl <= p['akhir'])
    if 'keterangan' in p:
        q = q.filter(Log.line.ilike('%'+p['keterangan']+'%'))
    return q


def get_last_jenis_trx():
    q = DBSession.query(Log).order_by(Log.tgl.desc())
    r = q.first()
    if r:
        return r.jenis_id
    q = DBSession.query(Jenis).order_by(Jenis.id)
    r = q.first()
    return r.id


def route_list(request, p=dict()):
    q = dict_to_str(p)
    return HTTPFound(location=request.route_url('log', _query=q))