eis_slide.py 10.5 KB
import os
import uuid
#from ..tools import row2dict, xls_reader
from datetime import datetime
from sqlalchemy import not_, func
from pyramid.view import (view_config,)
from pyramid.httpexceptions import ( HTTPFound, )
import colander
from deform import (Form, ValidationFailure, FileData,)
#from ..views import widget
from deform import widget
from ..models import EisDBSession
from ..models.eis import Slide, Eis
from sqlalchemy.sql.expression import update
from ..views import BaseView, ColumnDT, DataTables
from deform.interfaces import FileUploadTempStore
from pyramid.path import AssetResolver

SESS_ADD_FAILED = 'Tambah eis-slide gagal'
SESS_EDIT_FAILED = 'Edit eis-slide gagal'

@colander.deferred
def deferred_slide_type(node, kw):
    values = kw.get('slide_type', [])
    return widget.SelectWidget(values=values)
    
SLIDE_TYPE = (('','--Pilih--'),
           ('image','Gambar'),
           ('grid','Grid'),
           ('chart-line','Chart Garis'),
           ('chart-bar','Chart-Bar'),
           ('chart-pie', 'Chart-Pie'))

#tmpstore = FileUploadTempStore()
class MemoryTmpStore(dict):
    """ Instances of this class implement the
    :class:`deform.interfaces.FileUploadTempStore` interface"""
    def preview_url(self, uid):
        return None
        
tmpstore = MemoryTmpStore()
        
class UploadSchema(colander.Schema):
    upload = colander.SchemaNode(
                FileData(),
                missing=colander.drop,
                widget=widget.FileUploadWidget(tmpstore),
                title='Unggah',
                oid="upload")
           
class AddSchema(colander.Schema):
    kode  = colander.SchemaNode(
                    colander.String(),
                    validator=colander.Length(max=18),
                    oid='kode')
                    
    nama = colander.SchemaNode(
                    colander.String(),
                    validator=colander.Length(max=128),
                    oid = 'nama')
    source_type = colander.SchemaNode(
                    colander.String(),
                    widget=deferred_slide_type,
                    oid = "source_type")
                                    
    source_id  = colander.SchemaNode(
                    colander.String(),
                    oid = "source_id")
    upload = colander.SchemaNode(
            FileData(),
            missing=colander.drop,
            widget=widget.FileUploadWidget(tmpstore),
            oid = 'upload',
            title='File')
    grid_nm  = colander.SchemaNode(
                    colander.String(),
                    missing = colander.drop,
                    oid = "grid_nm")
    
    pie_nm  = colander.SchemaNode(
                    colander.String(),
                    missing = colander.drop,
                    oid = "pie_nm")
    bar_nm  = colander.SchemaNode(
                    colander.String(),
                    missing = colander.drop,
                    oid = "bar_nm")
    line_nm  = colander.SchemaNode(
                    colander.String(),
                    missing = colander.drop,
                    oid = "line_nm")

                    
    order_id   = colander.SchemaNode(
                    colander.Integer(),
                    default = 0,
                    missing = 0)
                
    aktif   = colander.SchemaNode(
                    colander.Boolean())
    status   = colander.SchemaNode(
                    colander.Boolean())

    #upload = UploadSchema()
    
class EditSchema(AddSchema):
    id = colander.SchemaNode(colander.String(),
            missing=colander.drop,
            widget=widget.HiddenWidget(readonly=True))
            
class view_eis_slide(BaseView):
    ########                    
    # List #
    ########    
    @view_config(route_name='eis-slide', renderer='templates/eis-slide/list.pt',
                 permission='read')
    def view_list(self):
        return dict(a={})
        
    ##########                    
    # Action #
    ##########    
    @view_config(route_name='eis-slide-act', renderer='json',
                 permission='read')
    def eis_slide_act(self):
        ses = self.req.session
        req = self.req
        params = req.params
        url_dict = req.matchdict
        
        if url_dict['act']=='grid':
            columns = []
            columns.append(ColumnDT(Slide.id))
            columns.append(ColumnDT(Slide.kode))
            columns.append(ColumnDT(Slide.nama))
            columns.append(ColumnDT(Slide.source_type))
            columns.append(ColumnDT(Slide.source_id))
            columns.append(ColumnDT(Slide.order_id))
            columns.append(ColumnDT(Slide.aktif))
            columns.append(ColumnDT(Slide.status))
            query = EisDBSession.query().select_from(Slide)
            rowTable = DataTables(req.GET, query, columns)
            return rowTable.output_result()
        
    #######    
    # Add #
    #######
    def form_validator(self, form, value):
        if 'id' in form.request.matchdict:
            uid = form.request.matchdict['id']
            q = EisDBSession.query(Slide).filter_by(id=uid)
            row = q.first()
        else:
            row = None
                
    def get_form(self, class_form, row=None):
        schema = class_form(validator=self.form_validator)
        schema = schema.bind(slide_type=SLIDE_TYPE)
        schema.request = self.req
        if row:
          schema.deserialize(row)
        return Form(schema, buttons=('simpan','batal'))
        
    def save_request(self, values, row=None):
        print(values)
        if 'upload' in values and values['upload']:
            filename = self.save_file()
            if filename:
                values['source_id'] = filename
        if 'id' in self.req.matchdict:
            values['id'] = self.req.matchdict['id']
        row = save(values, self.req.user, row)
        self.req.session.flash('Slide sudah disimpan.')
            
    def route_list(self):
        return HTTPFound(location=self.req.route_url('eis-slide'))
        
    def session_failed(self, session_name):
            
        #r = dict(form=self.session[session_name])
        del self.session[session_name]
        #return r
        
    @view_config(route_name='eis-slide-add', renderer='templates/eis-slide/add.pt',
                 permission='add')
    def view_eis_slide_add(self):
        req = self.req
        ses = self.ses
        form = self.get_form(AddSchema)
        if req.POST:
            if 'simpan' in req.POST:
                controls = req.POST.items()
                try:
                    controls = form.validate(controls)
                except ValidationFailure as e:
                    return dict(form=form)
                self.save_request(dict(controls))
            return self.route_list()
        elif SESS_ADD_FAILED in req.session:
            return dict(form=form)
        return dict(form=form)

        
    ########
    # Edit #
    ########
    def query_id(self):
        return EisDBSession.query(Slide).filter_by(id=self.req.matchdict['id'])
        
    def id_not_found(self):    
        msg = 'Slide ID %s Tidak Ditemukan.' % self.req.matchdict['id']
        request.session.flash(msg, 'error')
        return route_list()

    @view_config(route_name='eis-slide-edit', renderer='templates/eis-slide/add.pt',
                 permission='edit')
    def view_eis_slide_edit(self):
        request = self.req
        row = self.query_id().first()
        if not row:
            return id_not_found(request)
        #values = row.to_dict()
        rowd={}
        rowd['id']          = row.id
        rowd['kode']        = row.kode
        rowd['nama']        = row.nama
        rowd['source_type']    = row.source_type
        rowd['source_id']    = row.source_id
        rowd['order_id']    = row.order_id
        rowd['aktif']    = row.aktif
        rowd['status']    = row.status
        
        form = self.get_form(EditSchema)
        form.set_appstruct(rowd)
        if request.POST:
            if 'simpan' in request.POST:
                controls = request.POST.items()
                print(controls)
                try:
                    controls = form.validate(controls)
                except ValidationFailure as e:
                    return dict(form=form)
                self.save_request(dict(controls), row)
            return self.route_list()
        elif SESS_EDIT_FAILED in request.session:
            return self.session_failed(SESS_EDIT_FAILED)
        return dict(form=form)

    ##########
    # Delete #
    ##########    
    @view_config(route_name='eis-slide-delete', renderer='templates/eis-slide/delete.pt',
                 permission='delete')
    def view_eis_slide_delete(self):
        request = self.req
        q = self.query_id()
        row = q.first()
        
        if not row:
            return self.id_not_found(request)
        form = Form(colander.Schema(), buttons=('hapus','batal'))
        if request.POST:
            if 'hapus' in request.POST:
                msg = 'Slide ID %d %s sudah dihapus.' % (row.id, row.nama)
                try:
                  q.delete()
                  EisDBSession.flush()
                except:
                  msg = 'Slide ID %d %s tidak dapat dihapus.' % (row.id, row.nama)
                request.session.flash(msg)
            return self.route_list()
        return dict(row=row,
                     form=form.render())
                     
    def save_file(self):
        request = self.req
        input_file = request.POST['upload'].file
        filename = request.POST['upload'].filename
        resolver = AssetResolver('opensipkd')
        static_path = resolver.resolve('static').abspath()
        fullpath = os.path.join( static_path, 'img/', filename)
        output_file = open(fullpath, 'wb')
        input_file.seek(0)
        while True:
            data = input_file.read(2<<16)
            if not data:
                break
            output_file.write(data)
        return '/static/img/%s' % filename                     
                     
def save(values, user, row=None):
    if not row:
        row = Slide()
        row.created = datetime.now()
        row.create_uid = user.id
    row.from_dict(values)
    row.updated = datetime.now()
    row.update_uid = user.id
    row.aktif = 'aktif' in values and values['aktif'] and 1 or 0
    row.status = 'status' in values and values['status'] and 1 or 0
    EisDBSession.add(row)
    EisDBSession.flush()
    if 'aktif' in values and values['aktif']:
        stmt = update(Slide).where(Slide.id!=row.id).\
               values(aktif=0)
        EisDBSession.execute(stmt)
        EisDBSession.flush()
    return row