Skip to content
Toggle navigation
Projects
Groups
Snippets
Help
irul
/
opensipkd-base
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Wiki
Settings
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit 324d8d62
authored
Nov 27, 2024
by
aa.gusti
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
perbaikan template upload
1 parent
8783308f
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
179 additions
and
48 deletions
opensipkd/base/__init__.py
opensipkd/base/views/__init__.py
opensipkd/base/views/base_views.py
opensipkd/base/views/partner.py
opensipkd/base/views/partner_base.py
opensipkd/base/views/widgets/captcha.pt
opensipkd/base/views/widgets/file_upload.pt
opensipkd/base/views/widgets/form.pt
opensipkd/models/partner.py
opensipkd/base/__init__.py
View file @
324d8d6
...
...
@@ -2,13 +2,14 @@ import locale
import
logging
import
re
# from opensipkd.tools.captcha import get_captcha_url
from
.routes
import
routes
try
:
from
urllib
import
(
urlencode
,
quote
,
quote_plus
,
)
except
ImportError
:
from
urllib.parse
import
(
urlencode
,
quote
,
quote_plus
,
)
from
collections
import
OrderedDict
from
pyramid.events
import
NewRequest
from
pyramid.config
import
Configurator
from
pyramid_beaker
import
session_factory_from_settings
...
...
@@ -498,7 +499,7 @@ def get_module_submenus(parent_id):
q
=
DBSession
.
query
(
Route
)
\
.
filter
(
Route
.
parent_id
==
parent_id
)
\
.
order_bY
(
Route
.
order_id
)
return
[
r
.
kode
for
r
in
q
uery
.
all
()]
return
[
r
.
kode
for
r
in
q
.
all
()]
partner_idcard_url
=
'partner/idcard'
...
...
@@ -561,6 +562,7 @@ def main(global_config, **settings):
config
.
add_request_method
(
is_devel
,
'devel'
,
reify
=
True
)
config
.
add_request_method
(
get_host
,
'_host'
,
reify
=
True
)
config
.
add_request_method
(
get_host
,
'home'
,
reify
=
True
)
# config.add_request_method(get_captcha_url, 'captcha', reify=True)
# config.add_request_method(get_urls, 'route_urls', reify=True)
config
.
add_request_method
(
google_signin_client_id
,
'google_signin_client_id'
,
reify
=
True
)
...
...
@@ -592,6 +594,10 @@ def main(global_config, **settings):
os
.
makedirs
(
captcha_files
)
config
.
add_static_view
(
'captcha'
,
captcha_files
)
config
.
add_static_view
(
'partner/files'
,
get_params
(
"partner_files"
,
settings
=
settings
,
alternate
=
"/tmp/partner"
))
config
.
add_renderer
(
'csv'
,
'opensipkd.tools.CSVRenderer'
)
config
.
add_renderer
(
'json'
,
json_renderer
())
config
.
add_renderer
(
'json_rpc'
,
json_rpc
())
...
...
opensipkd/base/views/__init__.py
View file @
324d8d6
...
...
@@ -3,32 +3,25 @@ from datetime import timedelta
import
colander
from
deform
import
(
Form
,
ValidationFailure
,
widget
,
Button
,
)
from
opensipkd.tools.api
import
JsonRpcInvalidLoginError
Form
,
ValidationFailure
,
widget
,
Button
,
FileData
)
from
opensipkd.base
import
get_params
,
get_urls
from
opensipkd.models
import
(
DBSession
,
UserService
,
)
from
opensipkd.tools
import
mem_tmp_store
from
pyramid.httpexceptions
import
(
HTTPFound
,
HTTPForbidden
,
HTTPNotFound
,
HTTPInternalServerError
,
HTTPSeeOther
)
from
pyramid.i18n
import
TranslationStringFactory
from
pyramid.interfaces
import
IRoutesMapper
from
pyramid.renderers
import
render_to_response
from
pyramid.response
import
Response
from
pyramid.security
import
remember
from
pyramid.view
import
view_config
from
opensipkd.base
import
get_params
,
get_urls
from
opensipkd.base.tools.api
import
rpc_auth
from
.base_views
import
BaseView
from
opensipkd.models
import
(
DBSession
,
UserService
,
)
from
.common
import
DataTables
,
ColumnDT
from
pyramid.csrf
import
new_csrf_token
from
.base_views
import
BaseView
,
DataTables
,
ColumnDT
_
=
TranslationStringFactory
(
'login'
)
log
=
logging
.
getLogger
(
__name__
)
@view_config
(
context
=
HTTPNotFound
,
renderer
=
'templates/404.pt'
)
def
not_found
(
request
):
path
=
request
.
path
...
...
@@ -55,6 +48,33 @@ def internal_server_error(request):
# return response
class
Validator
(
object
):
def
__init__
(
self
,
row
):
self
.
row
=
row
class
FileSchema
(
colander
.
Schema
):
file_name
=
colander
.
SchemaNode
(
FileData
(),
widget
=
widget
.
FileUploadWidget
(
mem_tmp_store
,
size
=
104857600
),
missing
=
colander
.
drop
,
title
=
"File"
)
description
=
colander
.
SchemaNode
(
colander
.
String
(),
missing
=
colander
.
drop
,
validator
=
colander
.
Length
(
max
=
256
),
)
class
FilesSchema
(
colander
.
SequenceSchema
):
file_name
=
FileSchema
()
def
after_bin
(
self
,
node
,
kw
):
self
[
"file_name"
]
.
title
=
""
########
# Home #
########
...
...
@@ -152,5 +172,3 @@ two_minutes = timedelta(1.0 / 24 / 60)
def
deferred_jenis
(
node
,
kw
):
values
=
kw
.
get
(
'daftar_jenis'
,
[])
return
widget
.
RadioChoiceWidget
(
values
=
values
)
\ No newline at end of file
opensipkd/base/views/base_views.py
View file @
324d8d6
...
...
@@ -9,7 +9,6 @@ from datatables import ColumnDT
from
dateutil.relativedelta
import
relativedelta
from
deform
import
(
widget
,
Form
,
ValidationFailure
,
FileData
,
)
from
deform.widget
import
SelectWidget
from
opensipkd.base.views.upload
import
tmpstore
from
opensipkd.tools
import
dmy
,
get_settings
,
get_ext
,
\
date_from_str
,
get_random_string
from
opensipkd.tools.buttons
import
btn_save
,
btn_cancel
,
btn_close
,
btn_delete
,
\
...
...
@@ -19,6 +18,7 @@ from opensipkd.tools.captcha import get_captcha
from
opensipkd.tools.report
import
csv_response
,
file_response
from
pyramid.httpexceptions
import
HTTPFound
,
HTTPNotFound
from
opensipkd.base.views.upload
import
tmpstore
from
.common
import
DataTables
from
..
import
DBSession
,
get_params
,
get_urls
from
..scripts.initializedb
import
append_csv
...
...
@@ -149,6 +149,9 @@ class BaseView(object):
self
.
edit_schema
=
""
self
.
add_schema
=
""
self
.
upload_schema
=
UploadSchema
self
.
upload_exts
=
(
".csv"
,
".tsv"
)
self
.
upload_keys
=
[
"kode"
]
self
.
table
=
""
self
.
home
=
self
.
req
.
_host
self
.
buttons
=
None
...
...
@@ -156,7 +159,6 @@ class BaseView(object):
self
.
bindings
=
{}
self
.
autocomplete
=
'on'
self
.
action_suffix
=
"/grid/act"
self
.
upload_keys
=
[
"kode"
]
self
.
report_file
=
""
self
.
new_buttons
=
{}
self
.
is_object
=
False
...
...
@@ -263,7 +265,7 @@ class BaseView(object):
return
arg
def
get_bindings
(
self
,
row
=
None
):
return
{}
return
{
"row"
:
row
}
def
next_view
(
self
,
form
,
**
kwargs
):
return
...
...
@@ -296,11 +298,20 @@ class BaseView(object):
result
=
(
btn_close
,)
return
result
def
before_view
(
self
,
**
kw
):
return
False
def
view_view
(
self
,
**
kwargs
):
# row = query_id(request).first()
request
=
self
.
req
row
=
self
.
query_id
()
.
first
()
if
not
row
:
return
self
.
id_not_found
()
before_view
=
self
.
before_view
(
row
=
row
)
if
before_view
:
return
before_view
bindings
=
self
.
get_bindings
(
row
)
buttons
=
kwargs
.
get
(
"buttons"
,
None
)
if
not
buttons
:
...
...
@@ -339,7 +350,11 @@ class BaseView(object):
buttons
=
(
btn_post
,
btn_close
)
return
self
.
view_view
(
buttons
=
buttons
)
def
view_upload
(
self
,
exts
=
(
'.png'
,
'.ico'
),
**
args
):
def
view_upload
(
self
,
**
kw
):
exts
=
kw
.
get
(
"exts"
)
if
not
exts
:
exts
=
self
.
upload_exts
delimiter
=
args
.
get
(
"delimiter"
)
bindings
=
self
.
get_bindings
()
form
=
self
.
get_form
(
self
.
upload_schema
,
bindings
=
bindings
)
...
...
@@ -516,6 +531,9 @@ class BaseView(object):
else
:
return
self
.
next_act
(
**
kwargs
)
def
get_captcha_url
(
self
):
return
get_urls
(
"/captcha/"
)
+
get_captcha
(
self
.
req
)
def
view_add
(
self
,
**
kwargs
):
# bindings = self.get_bindings()
form
=
self
.
get_form
(
self
.
add_schema
,
**
kwargs
)
...
...
@@ -538,6 +556,8 @@ class BaseView(object):
if
isinstance
(
f
.
typ
,
colander
.
Date
):
e
.
cstruct
[
f
.
name
]
=
date_from_str
(
e
.
cstruct
[
f
.
name
])
if
f
.
name
==
"captcha"
:
e
.
cstruct
[
f
.
name
]
=
self
.
get_captcha_url
()
form
.
set_appstruct
(
e
.
cstruct
)
return
self
.
returned_form
(
form
,
table
,
**
kwargs
)
...
...
@@ -703,6 +723,7 @@ class BaseView(object):
def
query_id
(
self
):
q
=
self
.
db_session
.
query
(
self
.
table
)
.
filter_by
(
id
=
self
.
req
.
matchdict
[
'id'
])
if
self
.
req
.
user
:
if
hasattr
(
self
.
table
,
'company_id'
)
and
self
.
req
.
user
.
company_id
:
q
=
q
.
filter_by
(
company_id
=
self
.
req
.
user
.
company_id
)
return
q
...
...
opensipkd/base/views/partner.py
View file @
324d8d6
...
...
@@ -2,17 +2,17 @@ import colander
from
deform
import
(
widget
,
Button
,
)
from
pyramid.i18n
import
TranslationStringFactory
from
pyramid.view
import
(
view_config
,
)
from
opensipkd.base
import
get_id_card_folder
from
opensipkd.models
import
DBSession
,
Partner
from
opensipkd.models
import
(
ResProvinsi
,
ResDati2
,
ResKecamatan
,
ResDesa
)
from
opensipkd.models.common
import
ResCompany
from
opensipkd.tools
import
Upload
,
img_exts
from
pyramid.i18n
import
TranslationStringFactory
from
pyramid.view
import
(
view_config
,
)
from
.company
import
company_widget
from
.partner_base
import
PartnerSchema
# from .. import partner_idcard_url
...
...
@@ -243,6 +243,7 @@ class ViewPartner(BaseView):
value
[
"status"
]
=
'status'
in
value
and
value
[
'status'
]
and
1
or
0
def
get_bindings
(
self
,
row
=
None
):
result
=
super
()
.
get_bindings
(
row
)
provinsi_list
=
ResProvinsi
.
get_list
()
dati2_list
=
row
and
row
.
provinsi_id
and
ResDati2
.
get_list
(
row
.
provinsi_id
)
or
[]
...
...
@@ -250,17 +251,19 @@ class ViewPartner(BaseView):
row
.
dati2_id
)
or
[]
desa_list
=
row
and
row
.
kecamatan_id
and
ResDesa
.
get_list
(
row
.
kecamatan_id
)
or
[]
re
turn
dict
(
re
sult
.
update
(
dict
(
provinsi_list
=
provinsi_list
,
dati2_list
=
dati2_list
,
kecamatan_list
=
kecamatan_list
,
desa_list
=
desa_list
,
company_list
=
ResCompany
.
get_list
()
)
))
return
result
def
save_request
(
self
,
values
,
row
=
None
):
if
"idcard"
in
values
and
values
[
"idcard"
]:
if
str
(
self
.
req
.
POST
[
'upload'
]
.
decode
(
'utf-8'
)
)
!=
""
:
if
str
(
self
.
req
.
POST
[
'upload'
])
!=
""
:
folder
=
self
.
get_params
(
"idcard_folder"
,
'/tmp/idcard'
)
upload
=
Upload
(
folder
)
file_name
=
upload
.
save
(
self
.
req
,
'upload'
,
img_exts
)
...
...
opensipkd/base/views/partner_base.py
View file @
324d8d6
...
...
@@ -5,15 +5,70 @@ from opensipkd.base.views.dati2 import dati2_widget
from
opensipkd.base.views.desa
import
desa_widget
from
opensipkd.base.views.kecamatan
import
kecamatan_widget
from
opensipkd.base.views.provinsi
import
provinsi_widget
from
opensipkd.models
import
Partner
from
opensipkd.tools
import
mem_tmp_store
from
translationstring
import
TranslationStringFactory
from
..
import
get_urls
from
.
import
Validator
_
=
TranslationStringFactory
(
'partner'
)
class
PartnerEmailValidator
(
colander
.
Email
,
Validator
):
def
__init__
(
self
,
row
):
Validator
.
__init__
(
self
,
row
)
colander
.
Email
.
__init__
(
self
)
def
__call__
(
self
,
node
,
value
):
def
email_found
():
data
=
dict
(
email
=
email
,
rid
=
found
.
id
,
rname
=
found
.
nama
)
ts
=
_
(
'email-already-used'
,
default
=
'Email ${email} already used by Partner ID ${rid}: ${rname}'
,
mapping
=
data
)
raise
colander
.
Invalid
(
node
,
ts
)
if
self
.
match_object
.
match
(
value
)
is
None
:
raise
colander
.
Invalid
(
node
,
_
(
'Invalid email format'
))
email
=
value
.
lower
()
q
=
Partner
.
query
()
.
filter_by
(
email
=
email
)
found
=
q
.
first
()
if
found
and
(
not
self
.
row
or
self
.
row
.
email
!=
found
.
email
):
email_found
()
@colander.deferred
def
partner_email_validator
(
node
,
kw
):
return
PartnerEmailValidator
(
kw
[
'row'
])
class
PartnerKodeValidator
(
Validator
):
def
__init__
(
self
,
row
):
Validator
.
__init__
(
self
,
row
)
def
__call__
(
self
,
node
,
value
):
def
err_found
():
data
=
dict
(
kode
=
val
,
rid
=
found
.
id
,
rnama
=
found
.
nama
)
ts
=
_
(
'kode-already-used'
,
default
=
'Kode ${kode} already used by Partner ID ${rid}: ${rnama}'
,
mapping
=
data
)
raise
colander
.
Invalid
(
node
,
ts
)
val
=
value
q
=
Partner
.
query
()
.
filter_by
(
kode
=
val
)
found
=
q
.
first
()
if
found
and
(
not
self
.
row
or
self
.
row
.
kode
!=
found
.
kode
):
err_found
()
@colander.deferred
def
partner_kode_validator
(
node
,
kw
):
return
PartnerKodeValidator
(
kw
[
'row'
])
class
NamaSchema
(
colander
.
Schema
):
kode
=
colander
.
SchemaNode
(
colander
.
String
(),
validator
=
colander
.
Length
(
max
=
32
)
,
validator
=
partner_kode_validator
,
oid
=
"kode"
,
title
=
"Kode"
,
width
=
"100pt"
)
...
...
@@ -21,7 +76,10 @@ class NamaSchema(colander.Schema):
colander
.
String
(),
validator
=
colander
.
Length
(
max
=
64
),
oid
=
"nama"
)
email
=
colander
.
SchemaNode
(
colander
.
String
(),
validator
=
partner_email_validator
,
oid
=
"email"
)
class
PartnerSchema
(
NamaSchema
):
nip
=
colander
.
SchemaNode
(
...
...
@@ -103,10 +161,7 @@ class PartnerSchema(NamaSchema):
missing
=
colander
.
drop
,
title
=
"Desa/Kelurahan"
,
oid
=
"desa_id"
)
email
=
colander
.
SchemaNode
(
colander
.
String
(),
validator
=
colander
.
Length
(
max
=
128
),
oid
=
"email"
)
phone
=
colander
.
SchemaNode
(
colander
.
String
(),
validator
=
colander
.
Length
(
max
=
16
),
...
...
opensipkd/base/views/widgets/captcha.pt
View file @
324d8d6
opensipkd/base/views/widgets/file_upload.pt
View file @
324d8d6
...
...
@@ -5,12 +5,29 @@
ext str(cstruct.get('filename').split('.')[-1:][0]).lower()|[];
fname str(cstruct.get('filename'))|'';
delete cstruct.get('delete')|'';
maxsize field.widget.size|5242880;">
${field.start_mapping()}
<img id="preview-${oid}" alt="" src="${preview_url}" style="width:100px;height:auto;display:block;"
maxsize field.widget.size|5242880;
img ['jpg', 'jpeg', 'gif', 'png', 'svg', 'eps', 'psd'];
video ['avi', 'mov', 'mpv']
">
${field.start_mapping()}
<img tal:condition="ext in img" id="preview-${oid}" alt="" src="${preview_url}"
style="width:100px;height:auto;display:block;"
onload="window.URL.revokeObjectURL(this.src);"></img>
<video tal:condition="ext in video" width="100%" height="100%" controls
src="${preview_url}" type="video/${ext}">
Your browser does not support the video tag.
</video>
<video tal:condition="ext=='mp4'" width="100%" height="100%" controls
src="${preview_url}" type="video/mp4">
Your browser does not support the video tag.
</video>
<embed tal:condition="ext=='pdf'" src="${preview_url}" width="100%" height="400">
<a id="label-${oid}" tal:condition="preview_url" class="label label-default" href="${preview_url}"
target="_blank"><i class="fa fa-search"></i> View</a>
<input type="file" name="upload" id="${oid}"
tal:attributes="style style;
accept accept|field.widget.accept;
...
...
@@ -24,15 +41,15 @@
deform.addCallback('${oid}', function (oid) {
$('#' + oid).upload();
});
document.getElementById("${oid}").onchange = function
() {
if(this.files[0].size > ${maxsize})
{
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 = '';
}
document.getElementById('preview-'+
this.id).src = window.URL.createObjectURL(this.files[0]);
document.getElementById('labeldelete-'+
this.id).remove();
document.getElementById('label-'+
this.id).remove();
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
opensipkd/base/views/widgets/form.pt
View file @
324d8d6
...
...
@@ -41,6 +41,7 @@
<div tal:repeat="child field"
tal:replace="structure child.render_template(item_template)"/>
</div>
<div class="row">
<div class="form-group deform-form-buttons">
<tal:loop tal:repeat="button buttons">
...
...
opensipkd/models/partner.py
View file @
324d8d6
...
...
@@ -5,11 +5,12 @@ from sqlalchemy import (
SmallInteger
,
DateTime
,
ForeignKey
)
from
sqlalchemy.orm
import
Mapped
,
mapped_column
,
relationship
from
sqlalchemy.orm
import
backref
from
.common
import
NamaModel
from
.wilayah
import
ResProvinsi
,
ResDesa
,
ResKecamatan
,
ResDati2
from
.base
import
NamaModel
,
StandarModel
from
.meta
import
(
Base
)
from
sqlalchemy.orm
import
relationship
,
backref
from
.wilayah
import
ResProvinsi
,
ResDesa
,
ResKecamatan
,
ResDati2
class
PartnerModel
(
NamaModel
):
...
...
@@ -76,6 +77,7 @@ class Partner(Base, PartnerModel):
"ResKecamatan"
,
backref
=
backref
(
'partner'
))
res_desa
=
relationship
(
"ResDesa"
,
backref
=
backref
(
'partner'
))
partner_files
:
Mapped
[
"PartnerFiles"
]
=
relationship
(
back_populates
=
"partner"
)
# npwp = Column(String(16))
# npwpd = Column(String(16))
...
...
@@ -97,6 +99,14 @@ class Partner(Base, PartnerModel):
row
=
cls
.
query
()
.
filter_by
(
mobile
=
ident
)
.
first
()
return
row
class
PartnerFiles
(
Base
,
StandarModel
):
__tablename__
=
'partner_files'
partner_id
:
Mapped
[
int
]
=
mapped_column
(
ForeignKey
(
Partner
.
id
))
file_name
:
Mapped
[
str
]
=
mapped_column
(
String
(
256
))
description
:
Mapped
[
str
]
=
mapped_column
(
String
(
256
),
nullable
=
True
)
partner
:
Mapped
[
"Partner"
]
=
relationship
(
back_populates
=
"partner_files"
)
# class PartnerUserModel(Base, DefaultModel):
# __tablename__ = 'partner_user'
# partner_id = Column(Integer, ForeignKey(Partner.id))
...
...
Write
Preview
Markdown
is supported
Attach a file
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to post a comment