20250509

1 parent 166dae29
...@@ -22,6 +22,8 @@ pyramid.includes = ...@@ -22,6 +22,8 @@ pyramid.includes =
pyramid_chameleon pyramid_chameleon
pyramid_rpc.jsonrpc pyramid_rpc.jsonrpc
pyramid_debugtoolbar pyramid_debugtoolbar
opensipkd.pbb.models
opensipkd.pbb.esppt
session.type = ext:database session.type = ext:database
...@@ -41,18 +43,22 @@ partner_doc = C:\\tmp\\docs\\partner\\ ...@@ -41,18 +43,22 @@ partner_doc = C:\\tmp\\docs\\partner\\
# Registrasi User # Registrasi User
allow_register = 1 allow_register = 1
reg_form = reg_form =
reg_idcard = 1 reg_id_card = 1
reg_captcha = 1 reg_captcha = 1
reg_verify = 1 reg_verify = 1
;reg_form = ;reg_form =
login_tpl = login_tpl =
login_captcha = 1 login_captcha = 0
;login_tpl = opensipkd.samsat.jabar.views:templates/login.pt ;login_tpl = opensipkd.samsat.jabar.views:templates/login.pt
;PBB
; pbb.url = postgresql://aagusti:a@localhost:5432/demo2
pbb.url = oracle://PBB:A@10.8.50.62/simpbb
lib_dir = C:\Users\aagus\Project\pbb\instantclient_11_2
pbb_esppt_files = C:\tmp\pbb_esppt_files
;static_files = %(here)s/../files ;static_files = %(here)s/../files
;captcha_files = /tmp/captcha
;company = Opensipkd ;company = Opensipkd
;ibukota = Bekasi ;ibukota = Bekasi
;departement = IT ;departement = IT
...@@ -72,8 +78,7 @@ login_captcha = 1 ...@@ -72,8 +78,7 @@ login_captcha = 1
; ;
;modules = ;modules =
menus = login:Login menus = login:Login
register:PJDL /pbb/esppt:ESPPT
; bphtb:BPHTB
; five:Five ; five:Five
;app_name = GAJI ASN ;app_name = GAJI ASN
......
[Unit]
After=postgresql.service
[Service]
User={user}
ExecStart=/{bin_path}/pserve /{config_path}/production.ini
Restart=on-abort
[Install]
WantedBy=multi-user.target
...@@ -344,7 +344,7 @@ def _add_view_config(config, paket, route): ...@@ -344,7 +344,7 @@ def _add_view_config(config, paket, route):
route["func_name"] = "_".join(["view", func_name]) route["func_name"] = "_".join(["view", func_name])
file_name = f"{paket}.{route.get('file_name')}" file_name = f"{paket}.{route.get('file_name')}"
_logging.debug(f"File Name: {file_name}") # _logging.debug(f"File Name: {file_name}")
attr = f"{route.get('func_name')}" attr = f"{route.get('func_name')}"
try: try:
_views = importlib.import_module(file_name) _views = importlib.import_module(file_name)
...@@ -376,28 +376,29 @@ def _add_view_config(config, paket, route): ...@@ -376,28 +376,29 @@ def _add_view_config(config, paket, route):
config.add_view(views, **params) config.add_view(views, **params)
except Exception as e: except Exception as e:
_logging.error(f"Add View Config :") _logging.error("Add View Config :{code} Kode {error}"\
_logging.error(str(e)) .format(code=route["kode"], error=str(e)))
_logging.error(route) _logging.debug(f"Route: {route.get('kode')} {route.get('path')}")
# raise e
def get_route_file(filename):
base_dir = os.path.split(__file__)[0]
fullpath = os.path.join(base_dir, 'scripts', 'data', filename)
return open(fullpath)
class BaseApp(): class BaseApp():
def __init__(self): def __init__(self):
self.menus = [] self.menus = []
self.partner_doc = "" self.partner_doc = ""
self.temp_files = "" self.temp_files = ""
self.reg_id_card = 0
self.allow_register = 0 self.allow_register = 0
self.reg_form = "" self.reg_form = ""
self.reg_captcha = "" self.reg_id_card = 0
self.reg_captcha = 0
self.captcha_files = "" self.captcha_files = ""
self.login_captcha = 0 self.login_captcha = 0
self.base_dir = os.path.split(__file__)[0]
def get_route_file(self, filename="routes.csv"):
fullpath = os.path.join(self.base_dir, 'scripts', 'data', filename)
return open(fullpath)
def static_view(self, config, settings=None): def static_view(self, config, settings=None):
self.partner_doc = get_params( self.partner_doc = get_params(
...@@ -420,13 +421,14 @@ class BaseApp(): ...@@ -420,13 +421,14 @@ class BaseApp():
self.reg_captcha = get_params( self.reg_captcha = get_params(
"reg_captcha", 0, settings=settings) "reg_captcha", 0, settings=settings)
self.captcha_files = os.path.join(self.temp_files, "captcha")+os.sep self.captcha_files = os.path.join(self.temp_files, "captcha")+os.sep
if not os.path.exists(self.captcha_files): if not os.path.exists(self.captcha_files):
os.makedirs(self.captcha_files) os.makedirs(self.captcha_files)
config.add_static_view( config.add_static_view(
'captcha', self.captcha_files, cache_max_age=0) 'captcha', self.captcha_files, cache_max_age=0)
self.login_tpl = get_params("login_tpl", "", settings=settings) self.login_tpl = get_params("login_tpl", "", settings=settings)
self.login_captcha = get_params("login_captcha", 0, settings=settings) self.login_captcha = int(get_params("login_captcha", 0, settings=settings))
def add_menu(self, config, route_menus, parent=None, paket="opensipkd.base.views"): def add_menu(self, config, route_menus, parent=None, paket="opensipkd.base.views"):
...@@ -493,19 +495,18 @@ class BaseApp(): ...@@ -493,19 +495,18 @@ class BaseApp():
if p["children"]: if p["children"]:
self.route_children(p["children"], row) self.route_children(p["children"], row)
def route_from_csv(self, config, get_file=get_route_file, paket="opensipkd.base.views"): def route_from_csv(self, config, paket="opensipkd.base.views", filename="routes.csv"):
with get_file("routes.csv") as f: with self.get_route_file(filename) as f:
rows = csv.DictReader(f) rows = csv.DictReader(f)
new_routes = [] new_routes = []
for row in rows: for row in rows:
status = row.get("status", 0) status = row.get("status", 0)
if not status: if not row["kode"] or not int(status):
continue continue
status = int(status) status = int(status)
row["children"] = [] row["children"] = []
parent_id = row.get("parent_id") or row.get( parent_id = row.get("parent_id") or row.get("parent_id/routes.kode")
"parent_id/routes.kode")
if parent_id: if parent_id:
self.route_children(new_routes, row) self.route_children(new_routes, row)
else: else:
......
from opensipkd.base import get_params
from opensipkd.base.models import (DBSession, User, GroupPermission, UserDeviceModel)
from opensipkd.tools import (
devel, get_random_string)
from opensipkd.tools.api import *
log = logging.getLogger(__name__)
lima_menit = 300
#
def auth_from(request, field=None):
global lima_menit
env = request.environ
log.info(env)
if not ('HTTP_USERID' in env and 'HTTP_SIGNATURE' in env and
'HTTP_KEY' in env):
raise JsonRpcInvalidLoginError
http_userid = env['HTTP_USERID']
q = DBSession.query(User).filter_by(user_name=http_userid)
user = q.first()
if not user or user.status == 0:
raise JsonRpcInvalidLoginError
# bypass cek authentication for development
if http_userid == 'admin' and request.devel:
return user
time_stamp = validate_time(request)
if field:
header = json_rpc_header(http_userid, user.security_code, time_stamp)
else:
header = json_rpc_header(http_userid, user.api_key, time_stamp)
if header['signature'] != env['HTTP_SIGNATURE']:
raise JsonRpcInvalidLoginError
return user
def auth_from_rpc(request):
return auth_from(request)
def rpc_auth(request):
return auth_from(request)
# def auth_from_token(request):
# return auth_from(request, "security_code")
#
# def renew_token(user_device, logout=False):
# now = datetime.now(tz=get_timezone())
# tte = timedelta(minutes=10)
# if not user_device.expired or not user_device.token or \
# now - user_device.expired > tte:
# user_device.expired = now
# user_device.token = get_random_string(128)
# if logout:
# user_device.token=""
# DBSession.add(user_device)
# DBSession.flush()
# return user_device
# def token_auth(request, logout=False):
# if not request.environ["HTTP_TOKEN"]:
# raise JsonRpcInvalidLoginError
# user_device = UserDeviceModel.query() \
# .filter_by(kode=request.environ["HTTP_USER_AGENT"],
# token=request.environ["HTTP_TOKEN"]).first()
# if not user_device:
# raise JsonRpcInvalidLoginError
#
# return renew_token(user_device, logout=logout)
def get_user_device(request, user_id):
user_device = UserDeviceModel.query() \
.filter_by(user_id=user_id,
kode=request.environ["HTTP_USER_AGENT"]).first()
if not user_device:
user_device = UserDeviceModel()
user_device.user_id = user_id
user_device.kode = request.environ["HTTP_USER_AGENT"]
# user_device = renew_token(user_device)
return user_device
def auth_device(request):
env = request.environ
log.info(env)
if not ('HTTP_USERID' in env and 'HTTP_SIGNATURE' in env and
'HTTP_KEY' in env):
raise JsonRpcInvalidLoginError
http_userid = env['HTTP_USERID']
q = DBSession.query(User).filter_by(user_name=http_userid)
user = q.first()
if not user or user.status == 0:
raise JsonRpcInvalidLoginError
if http_userid == 'admin' and request.devel:
return user
user_device = get_user_device(request, user)
time_stamp = validate_time(request)
header = json_rpc_header(http_userid, user_device.token, time_stamp)
if header['signature'] != env['HTTP_SIGNATURE']:
log.info(f"{http_userid}, {user_device.token}, {time_stamp}")
log.info(f"{header['signature']} != {env['HTTP_SIGNATURE']}")
raise JsonRpcInvalidLoginError
return user
def check_token(token, perm_name=None):
user = User.get_by_token(token).first()
if not user:
raise JsonRpcInvalidLoginError
if not perm_name:
return user
groups = user.get_groups()
perm = DBSession.query(GroupPermission). \
filter(GroupPermission.group_id.in_(groups),
GroupPermission.perm_name == perm_name).first()
if not perm:
return
return user
def check_token_rpc(token, perm_name=None):
result = check_token(token, perm_name)
if not result:
raise JsonRpcPermissionError
return result
def update_token(user):
if not devel():
user.security_code = get_random_string(64)
DBSession.add(user)
DBSession.flush()
return dict(token=user.security_code)
def config_pars_rpc_url(params, method=None):
values = get_params(params)
return pars_rpc_url(values, method)
\ No newline at end of file \ No newline at end of file
from sqlalchemy import func
from opensipkd.base.models import Parameter
def column_concat(cols=None):
if not cols:
return ''
elif len(cols) == 1:
return cols[0]
# saat ini menggunakan recursive spertinya ada syntax pythonic
# func.concat(cols[i], for col in cols)
return func.concat(cols[0], column_concat(cols[1:]))
def column_date(field, dt_format='YYYY-MM-DD HH:MI:SS'):
return func.to_char(field, dt_format)
def get_parameter(kode):
return Parameter.query_kode(kode).first()
def get_parameter_pasar(kode):
return Parameter.query_kode(kode).all()
def get_parameter_kebersihan(kode):
return Parameter.query_kode(kode).all()
...@@ -10,11 +10,11 @@ log.warning("Opensipkd.base.tools.pbb depreciated use opensipkd.tools.pbb") ...@@ -10,11 +10,11 @@ log.warning("Opensipkd.base.tools.pbb depreciated use opensipkd.tools.pbb")
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
db_driver_port = { # db_driver_port = {
"postgresql": ["postgres", "5432", "org.postgresql.Driver", "jdbc:postgresql://localhost:5432/pjdl_ciamis"], # "postgresql": ["postgres", "5432", "org.postgresql.Driver", "jdbc:postgresql://localhost:5432/pjdl_ciamis"],
"oracle": ["oracle", "1512", "oracle.jdbc.driver.OracleDriver"], # "oracle": ["oracle", "1512", "oracle.jdbc.driver.OracleDriver"],
} # }
def jasper_compile(input_file): def jasper_compile(input_file):
......
...@@ -11,9 +11,11 @@ from pyramid.renderers import render_to_response ...@@ -11,9 +11,11 @@ from pyramid.renderers import render_to_response
from .base_views import BaseView from .base_views import BaseView
#, DataTables #, DataTables
from datetime import timedelta from datetime import timedelta
from opensipkd.detable import *
from .common import ColumnDT, DataTables
from opensipkd.tools import mem_tmp_store
from deform import ( from deform import (
Form, ValidationFailure, widget, Button, FileData) Form, ValidationFailure, widget, Button, FileData)
from opensipkd.tools import mem_tmp_store
one_hour = timedelta(1.0 / 24) one_hour = timedelta(1.0 / 24)
two_minutes = timedelta(1.0 / 24 / 60) two_minutes = timedelta(1.0 / 24 / 60)
......
...@@ -23,7 +23,7 @@ from opensipkd.tools.buttons import ( ...@@ -23,7 +23,7 @@ from opensipkd.tools.buttons import (
# from opensipkd.tools.captcha import get_captcha # from opensipkd.tools.captcha import get_captcha
from opensipkd.tools.report import csv_response, file_response from opensipkd.tools.report import csv_response, file_response
from .common import DataTables from .common import DataTables
from ..models import DBSession from ..models import DBSession, Partner
# , get_params, get_urls # , get_params, get_urls
from ..scripts.initializedb import append_csv from ..scripts.initializedb import append_csv
from ...detable import DeTable from ...detable import DeTable
...@@ -1076,7 +1076,8 @@ class BaseView(object): ...@@ -1076,7 +1076,8 @@ class BaseView(object):
# return resp # return resp
# return value["filename"] # return value["filename"]
def get_partner(self):
return Partner.query_email(self.req.user.email).first()
# @colander.deferred # @colander.deferred
# def deferred_status(node, kw): # def deferred_status(node, kw):
...@@ -1117,6 +1118,7 @@ class BaseView(object): ...@@ -1117,6 +1118,7 @@ class BaseView(object):
# return result == '1' or result == "True" or result == "true" or result == True # return result == '1' or result == "True" or result == "true" or result == True
def get_url_captcha(request): # def get_url_captcha(request):
captcha = get_captcha(request) # captcha = get_captcha(request)
return os.path.join(get_urls(request.route_url('home')), 'captcha', captcha) # return os.path.join(get_urls(request.route_url('home')), 'captcha', captcha)
import email
import logging import logging
import colander import colander
from deform import ( from deform import (
...@@ -49,9 +50,16 @@ class AddSchema(PartnerSchema): ...@@ -49,9 +50,16 @@ class AddSchema(PartnerSchema):
def after_bind(self, schema, kwargs): def after_bind(self, schema, kwargs):
super().after_bind(schema, kwargs) super().after_bind(schema, kwargs)
request = kwargs["request"] request = kwargs["request"]
if request.user.company_id: if BASE_CLASS.reg_id_card:
self["company_id"].widget = widget.HiddenWidget() self["kode"].title = "NIK/NIB"
self["company_id"].default = request.user.company_id else:
self["kode"].title = "E-mail"
del self["email"]
del self["idcard"]
# if request.user.company_id:
# self["company_id"].widget = widget.HiddenWidget()
# self["company_id"].default = request.user.company_id
class EditSchema(AddSchema): class EditSchema(AddSchema):
......
...@@ -94,23 +94,18 @@ class NamaSchema(colander.Schema): ...@@ -94,23 +94,18 @@ class NamaSchema(colander.Schema):
class PartnerSchema(NamaSchema): class PartnerSchema(NamaSchema):
nip = colander.SchemaNode( # nip = colander.SchemaNode(
colander.String(), # colander.String(),
missing=colander.drop, # missing=colander.drop,
validator=colander.Length(max=32), # validator=colander.Length(max=32),
oid="nip") # oid="nip")
npwp = colander.SchemaNode( # npwp = colander.SchemaNode(
colander.String(), # colander.String(),
missing=colander.drop, # missing=colander.drop,
validator=colander.Length(max=32), # validator=colander.Length(max=32),
oid="npwp") # oid="npwp")
idcard = colander.SchemaNode(
FileData(),
widget=widget.FileUploadWidget(mem_tmp_store),
missing=colander.drop,
title="ID Card"
)
alamat_1 = colander.SchemaNode( alamat_1 = colander.SchemaNode(
colander.String(), colander.String(),
missing=colander.drop, missing=colander.drop,
...@@ -121,26 +116,26 @@ class PartnerSchema(NamaSchema): ...@@ -121,26 +116,26 @@ class PartnerSchema(NamaSchema):
missing=colander.drop, missing=colander.drop,
validator=colander.Length(max=128), validator=colander.Length(max=128),
oid="alamat_2") oid="alamat_2")
# kelurahan = colander.SchemaNode( kelurahan = colander.SchemaNode(
# colander.String(), colander.String(),
# missing=colander.drop, missing=colander.drop,
# validator=colander.Length(max=64), validator=colander.Length(max=64),
# oid="kelurahan") oid="kelurahan")
# kecamatan = colander.SchemaNode( kecamatan = colander.SchemaNode(
# colander.String(), colander.String(),
# missing=colander.drop, missing=colander.drop,
# validator=colander.Length(max=64), validator=colander.Length(max=64),
# oid="kecamatan") oid="kecamatan")
# kota = colander.SchemaNode( kota = colander.SchemaNode(
# colander.String(), colander.String(),
# validator=colander.Length(max=64), validator=colander.Length(max=64),
# missing=colander.drop, missing=colander.drop,
# oid="kota") oid="kota")
# provinsi = colander.SchemaNode( provinsi = colander.SchemaNode(
# colander.String(), colander.String(),
# validator=colander.Length(max=64), validator=colander.Length(max=64),
# missing=colander.drop, missing=colander.drop,
# oid="provinsi") oid="provinsi")
# provinsi_id = colander.SchemaNode( # provinsi_id = colander.SchemaNode(
# colander.Integer(), # colander.Integer(),
# widget=provinsi_widget, # widget=provinsi_widget,
...@@ -187,13 +182,18 @@ class PartnerSchema(NamaSchema): ...@@ -187,13 +182,18 @@ class PartnerSchema(NamaSchema):
mobile = colander.SchemaNode( mobile = colander.SchemaNode(
colander.String(), colander.String(),
validator=colander.Length(max=16), validator=colander.Length(max=16),
missing=colander.drop,
oid="mobile") oid="mobile")
website = colander.SchemaNode( website = colander.SchemaNode(
colander.String(), colander.String(),
validator=colander.Length(max=128), validator=colander.Length(max=128),
missing=colander.drop, missing=colander.drop,
oid="website") oid="website")
idcard = colander.SchemaNode(
FileData(),
widget=widget.FileUploadWidget(mem_tmp_store),
missing=colander.drop,
title="ID Card"
)
status = colander.SchemaNode( status = colander.SchemaNode(
colander.Integer(), colander.Integer(),
widget=widget.CheckboxWidget(true_val="1", false_val="0"), widget=widget.CheckboxWidget(true_val="1", false_val="0"),
......
...@@ -57,20 +57,40 @@ _logging = logging.getLogger(__name__) ...@@ -57,20 +57,40 @@ _logging = logging.getLogger(__name__)
class AddSchema(colander.Schema): class AddSchema(colander.Schema):
nama = colander.SchemaNode( nama = colander.SchemaNode(
colander.String(), colander.String(),
validator=colander.Length(max=64),
oid="nama", oid="nama",
title=_("Name"), title=_("Name"),
) )
alamat_1 = colander.SchemaNode( alamat_1 = colander.SchemaNode(
colander.String(), colander.String(),
title=_("Address"), title=_("Address"),
validator=colander.Length(max=128),
oid="alamat_1") oid="alamat_1")
alamat_2 = colander.SchemaNode( alamat_2 = colander.SchemaNode(
colander.String(), colander.String(),
title="", title="",
validator=colander.Length(max=128),
missing=colander.drop, missing=colander.drop,
oid="alamat_2") oid="alamat_2")
kelurahan = colander.SchemaNode(
colander.String(),
validator=colander.Length(max=64),
oid="kelurahan")
kecamatan = colander.SchemaNode(
colander.String(),
validator=colander.Length(max=64),
oid="kecamatan")
kota = colander.SchemaNode(
colander.String(),
validator=colander.Length(max=64),
oid="kota")
provinsi = colander.SchemaNode(
colander.String(),
validator=colander.Length(max=64),
oid="provinsi")
mobile = colander.SchemaNode( mobile = colander.SchemaNode(
colander.String(), colander.String(),
validator=colander.Length(max=18, min=8),
oid="no_hp", oid="no_hp",
title=_("Mobile") title=_("Mobile")
) )
...@@ -285,7 +305,7 @@ class Views(BaseView): ...@@ -285,7 +305,7 @@ class Views(BaseView):
if "idcard" in value and value["idcard"]: if "idcard" in value and value["idcard"]:
idcard = value["idcard"] idcard = value["idcard"]
if "fp" in idcard and idcard["fp"] and idcard["fp"] != b'': if "fp" in idcard and idcard["fp"] and idcard["fp"] != b'':
path = BASE_CLASS.reg_id_card path = BASE_CLASS.partner_doc
_logging.debug(idcard["fp"]) _logging.debug(idcard["fp"])
upload = Upload(path) upload = Upload(path)
value["idcard"] = upload.save_fp(idcard) value["idcard"] = upload.save_fp(idcard)
...@@ -391,7 +411,7 @@ class Views(BaseView): ...@@ -391,7 +411,7 @@ class Views(BaseView):
if d["idcard"]: if d["idcard"]:
filename = d["idcard"] filename = d["idcard"]
preview_url = "/".join( preview_url = "/".join(
[self.req.static_url(BASE_CLASS.reg_id_card), [self.req.static_url(BASE_CLASS.partner_doc),
filename]) filename])
d["idcard"] = {"uid": filename.split(".")[0], d["idcard"] = {"uid": filename.split(".")[0],
"filename": filename, "filename": filename,
......
<html tal:define="home request.home;">
<html tal:define="home request._host;">
<body> <body>
<div class="well"> <div class="well">
<h3>Forbidden</h3> <h3>Forbidden</h3>
<!-- Error session flash --> <!-- Error session flash -->
<div tal:condition="request.session.peek_flash()"> <div tal:condition="request.session.peek_flash()">
<div class="alert alert-success" tal:repeat="message request.session.pop_flash()"><i class="fa fa-fw fa-lg fa-check-circle"></i>&nbsp;${message}</div> <div class="alert alert-success" tal:repeat="message request.session.pop_flash()"><i
class="fa fa-fw fa-lg fa-check-circle"></i>&nbsp;${message}</div>
</div> </div>
<div tal:condition="request.session.peek_flash('error')"> <div tal:condition="request.session.peek_flash('error')">
<div class="alert alert-danger" tal:repeat="message request.session.pop_flash('error')"><i class="fa fa-fw fa-lg fa-times-circle"></i>&nbsp;${message}</div> <div class="alert alert-danger" tal:repeat="message request.session.pop_flash('error')"><i
class="fa fa-fw fa-lg fa-times-circle"></i>&nbsp;${message}</div>
</div> </div>
<!-- Error session flash --> <!-- Error session flash -->
<p><img src="${home}/static/img/logo.png" class="img-float img-thumbnail"/></p> <p><img src="${home}/static/img/logo.png" class="img-float img-thumbnail" /></p>
Anda tidak berhak mengakses halaman <span style="color:red;">${url}</span><br> Anda tidak berhak mengakses halaman <span style="color:red;">${url}</span><br>
<b>Silahkan Hubungi Administrator</b><br> <b>Silahkan Hubungi Administrator</b><br>
<a href="${request.referer}" tal:condition=request.referer >Kembali ke Halaman Sebelumnya</a> <a href="${request.referer}" tal:condition=request.referer>Kembali ke Halaman Sebelumnya</a>
<a href="${home}/" tal:condition="not request.referer" >Kembali ke Halaman Utama</a> <a href="${home}/" tal:condition="not request.referer">Kembali ke Halaman Utama</a>
</div> </div>
</body> </body>
</html>
</html>
\ No newline at end of file \ No newline at end of file
...@@ -118,6 +118,11 @@ ...@@ -118,6 +118,11 @@
<!-- end fullscreen button --> <!-- end fullscreen button -->
<!-- User info --> <!-- User info -->
<ul tal:condition="not request.user" class="header-dropdown-list hidden-xs">
<li>
<a href="${home}/login" class="dropdown-toggle"><i class="fa fa-lg fa-fw fa-user"></i>Login</a>
</li>
</ul>
<ul tal:condition="request.user" class="header-dropdown-list hidden-xs"> <ul tal:condition="request.user" class="header-dropdown-list hidden-xs">
<li> <li>
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="fa fa-lg fa-fw fa-user"></i> <a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="fa fa-lg fa-fw fa-user"></i>
...@@ -159,22 +164,25 @@ ...@@ -159,22 +164,25 @@
<ul metal:define-slot="navs"></ul> <ul metal:define-slot="navs"></ul>
<ul style="margin-top: 0; padding-top: 0;"> <ul style="margin-top: 0; padding-top: 0;">
<li tal:repeat="menu get_base_menus()" <li tal:repeat="menu get_base_menus()"
tal:attributes="class route_name in menu['route_name'] and 'active'"> tal:attributes="class route_name in menu['route_name'] and 'active'">
<a tal:condition="python:not menu['children'] and has_permission(request, menu['permission'])" <a tal:condition="python:not menu['children'] and (not menu['permission'] or has_permission(request, menu['permission']))"
href="${home}${menu['path']}"> href="${home}${menu['path']}">
<i tal:condition="menu['icon']" class="fa fa-lg fa-fw ${menu['icon']}"></i> <i tal:condition="menu['icon']" class="fa fa-lg fa-fw ${menu['icon']}"></i>
<span>${menu['nama']}</span> <span>${menu['nama']}</span>
</a> </a>
<a tal:condition="python:menu['children'] and has_permission(request, menu['permission'])" href="#"> <a tal:condition="python:menu['children'] and (not menu['permission'] or has_permission(request, menu['permission']))"
href="#">
<i tal:condition="menu['icon']" class="fa fa-lg fa-fw ${menu['icon']}"></i> <i tal:condition="menu['icon']" class="fa fa-lg fa-fw ${menu['icon']}"></i>
<span class="menu-item-parent">${menu['nama']}</span> <span class="menu-item-parent">${menu['nama']}</span>
</a> </a>
<ul tal:condition="python:menu['children'] and has_permission(request, menu['permission'])"> <ul
tal:condition="python:menu['children'] and (not menu['permission'] or has_permission(request, menu['permission']))">
<li tal:repeat="submenu menu['children']" <li tal:repeat="submenu menu['children']"
tal:attributes="class route_name in submenu['route_name'] and 'active'"> tal:attributes="class route_name in submenu['route_name'] and 'active'">
<a tal:condition="python:not submenu['children'] and has_permission(request, submenu['permission'])" <a tal:condition="python:not submenu['children'] and (not menu['permission'] or has_permission(request, submenu['permission']))"
href="${home}${submenu['path']}"> href="${home}${submenu['path']}">
<i tal:condition="submenu['icon']" class="fa fa-lg fa-fw ${submenu['icon']}"></i> <i tal:condition="submenu['icon']" class="fa fa-lg fa-fw ${submenu['icon']}"></i>
<span>${submenu['nama']}</span> <span>${submenu['nama']}</span>
......
<tal:block tal:define="oid oid|field.oid;
css_class css_class|field.widget.css_class;
style style|field.widget.style;
preview_url cstruct.get('preview_url')|'';
ext str(cstruct.get('filename').split('.')[-1:][0]).lower()|[];
fname str(cstruct.get('filename'))|'';
delete cstruct.get('delete')|'';
maxsize field.widget.size|5242880;
img ['jpg', 'jpeg', 'gif', 'png', 'svg', 'eps', 'psd'];
video ['avi', 'mov', 'mpv']
">
${field.start_mapping()}
<div class="thumbnail">
<img tal:condition="ext in img" id="preview-${oid}" alt="" src="${preview_url}" style="${style}"
onload="window.URL.revokeObjectURL(this.src);"></img>
<video tal:condition="ext in video" style="${style}" controls src="${preview_url}" type="video/${ext}"
id="preview-${oid}">
Your browser does not support the video tag.
</video>
<video tal:condition="ext=='mp4'" controls style="${style}" src="${preview_url}" type="video/mp4"
id="preview-${oid}">
Your browser does not support the video tag.
</video>
<embed tal:condition="ext=='pdf'" src="${preview_url}" style="${style}" id="preview-${oid}">
</div>
<a class="label label-default" href="${preview_url}" target="_blank" id="a-preview-${oid}"><i
class="fa fa-search"></i> View</a>
<input type="file" name="upload" id="${oid}" tal:attributes="style style;
accept accept|field.widget.accept;
data-filename fname;
attributes|field.widget.attributes|{};" />
<input tal:define="uid cstruct.get('uid')" tal:condition="uid" type="hidden" name="uid" value="${uid}" />
${field.end_mapping()}
<script type="text/javascript">
deform.addCallback('${oid}', function (oid) {
$('#' + oid).upload();
});
document.getElementById("${oid}").onchange = function () {
if (this.files[0].size > ${ maxsize }) {
alert("File is too big!");
this.value = "";
document.getElementById('preview-' + this.id).src = '';
}
document.getElementById('preview-' + this.id).src = window.URL.createObjectURL(this.files[0]);
document.getElementById('labeldelete-' + this.id).remove();
document.getElementById('label-' + this.id).remove();
};
</script>
</tal:block>
\ No newline at end of file \ No newline at end of file
<p tal:define="preview_url cstruct.get('preview_url');
css_class css_class|field.widget.css_class;
style style|field.widget.style;
preview_url cstruct.get('preview_url')|'';
ext str(cstruct.get('filename').split('.')[-1:][0]).lower()|[];
fname str(cstruct.get('filename'))|'';
delete cstruct.get('delete')|'';
ext str(cstruct.get('filename').split('.')[-1:][0]).lower()|[];
oid oid|field.oid;
img ['jpg', 'jpeg', 'gif', 'png', 'svg', 'eps', 'psd'];
video ['avi', 'mov', 'mpv'];
">
<div class="thumbnail">
<img tal:condition="ext in img" id="preview-${oid}" alt="" src="${preview_url}" style="${style}"
onload="window.URL.revokeObjectURL(this.src);"></img>
<video tal:condition="ext in video" style="${style}" controls src="${preview_url}" type="video/${ext}"
id="preview-${oid}">
Your browser does not support the video tag.
</video>
<video tal:condition="ext=='mp4'" controls style="${style}" src="${preview_url}" type="video/mp4" id="preview-${oid}">
Your browser does not support the video tag.
</video>
<embed tal:condition="ext=='pdf'" src="${preview_url}" style="${style}" id="preview-${oid}">
<a id="a-preview-${oid}" class="label label-default" href="${structure: preview_url}" target="_blank"><i
class="fa fa-search"></i> View</a>
</div>
</p>
\ No newline at end of file \ No newline at end of file
from opensipkd.base.models import *
\ No newline at end of file \ No newline at end of file
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!