remove support for strongbox (#37967)
This commit is contained in:
parent
741fa07466
commit
bfcb1e467d
|
@ -8,7 +8,6 @@ from modules import admin
|
||||||
from modules import backoffice
|
from modules import backoffice
|
||||||
from modules import categories_admin
|
from modules import categories_admin
|
||||||
from modules import payments_ui
|
from modules import payments_ui
|
||||||
from modules import strongbox_ui
|
|
||||||
from modules import formpage
|
from modules import formpage
|
||||||
from modules import template
|
from modules import template
|
||||||
from modules import root
|
from modules import root
|
||||||
|
@ -28,9 +27,6 @@ rdb.items = []
|
||||||
rdb.register_directory('payments', payments_ui.PaymentsDirectory())
|
rdb.register_directory('payments', payments_ui.PaymentsDirectory())
|
||||||
rdb.register_menu_item('payments/', _('Payments'))
|
rdb.register_menu_item('payments/', _('Payments'))
|
||||||
|
|
||||||
rdb.register_directory('strongbox', strongbox_ui.StrongboxDirectory())
|
|
||||||
rdb.register_menu_item('strongbox/', _('Strongbox'))
|
|
||||||
|
|
||||||
rdb.register_directory('settings', admin.SettingsDirectory())
|
rdb.register_directory('settings', admin.SettingsDirectory())
|
||||||
|
|
||||||
import wcs.admin.forms
|
import wcs.admin.forms
|
||||||
|
|
|
@ -22,8 +22,7 @@ from .abelium_domino_ui import AbeliumDominoDirectory
|
||||||
|
|
||||||
|
|
||||||
class PanelDirectory(Directory):
|
class PanelDirectory(Directory):
|
||||||
_q_exports = ['', 'update', 'permissions',
|
_q_exports = ['', 'update', 'permissions', 'domino']
|
||||||
'strongbox', 'domino']
|
|
||||||
label = N_('Control Panel')
|
label = N_('Control Panel')
|
||||||
|
|
||||||
domino = AbeliumDominoDirectory()
|
domino = AbeliumDominoDirectory()
|
||||||
|
@ -47,10 +46,6 @@ class PanelDirectory(Directory):
|
||||||
form.add(SingleSelectWidget, 'payments', title = _('Admin role for payments'),
|
form.add(SingleSelectWidget, 'payments', title = _('Admin role for payments'),
|
||||||
value = permissions_cfg.get('payments', None),
|
value = permissions_cfg.get('payments', None),
|
||||||
options = [(None, _('Nobody'), None)] + get_user_roles())
|
options = [(None, _('Nobody'), None)] + get_user_roles())
|
||||||
if get_publisher().has_site_option('auquotidien-strongbox'):
|
|
||||||
form.add(SingleSelectWidget, 'strongbox', title = _('Admin role for strongbox'),
|
|
||||||
value = permissions_cfg.get('strongbox', None),
|
|
||||||
options = [(None, _('Nobody'), None)] + get_user_roles())
|
|
||||||
form.add_submit('submit', _('Submit'))
|
form.add_submit('submit', _('Submit'))
|
||||||
form.add_submit('cancel', _('Cancel'))
|
form.add_submit('cancel', _('Cancel'))
|
||||||
|
|
||||||
|
@ -66,41 +61,13 @@ class PanelDirectory(Directory):
|
||||||
return r.getvalue()
|
return r.getvalue()
|
||||||
else:
|
else:
|
||||||
from wcs.admin.settings import cfg_submit
|
from wcs.admin.settings import cfg_submit
|
||||||
cfg_submit(form, 'aq-permissions',
|
cfg_submit(form, 'aq-permissions', ('forms', 'payments'))
|
||||||
('forms', 'payments', 'strongbox'))
|
|
||||||
return redirect('..')
|
|
||||||
|
|
||||||
def strongbox(self):
|
|
||||||
if not get_publisher().has_site_option('strongbox'):
|
|
||||||
raise errors.TraversalError()
|
|
||||||
misc_cfg = get_cfg('misc', {})
|
|
||||||
form = Form(enctype='multipart/form-data')
|
|
||||||
form.add(CheckboxWidget, 'aq-strongbox', title=_('Strongbox Support'),
|
|
||||||
value=misc_cfg.get('aq-strongbox'), required=False)
|
|
||||||
|
|
||||||
form.add_submit('submit', _('Submit'))
|
|
||||||
form.add_submit('cancel', _('Cancel'))
|
|
||||||
|
|
||||||
if form.get_widget('cancel').parse():
|
|
||||||
return redirect('..')
|
|
||||||
|
|
||||||
if not form.is_submitted() or form.has_errors():
|
|
||||||
get_response().breadcrumb.append(('aq/strongbox', _('Strongbox Support')))
|
|
||||||
html_top('settings', _('Strongbox Support'))
|
|
||||||
r = TemplateIO(html=True)
|
|
||||||
r += htmltext('<h2>%s</h2>') % _('Strongbox Support')
|
|
||||||
r += form.render()
|
|
||||||
return r.getvalue()
|
|
||||||
else:
|
|
||||||
from wcs.admin.settings import cfg_submit
|
|
||||||
cfg_submit(form, 'misc', ('aq-strongbox',))
|
|
||||||
return redirect('..')
|
return redirect('..')
|
||||||
|
|
||||||
|
|
||||||
class SettingsDirectory(wcs.admin.settings.SettingsDirectory):
|
class SettingsDirectory(wcs.admin.settings.SettingsDirectory):
|
||||||
def _q_index(self):
|
def _q_index(self):
|
||||||
if not (get_publisher().has_site_option('auquotidien-payments') or
|
if not get_publisher().has_site_option('auquotidien-payments'):
|
||||||
get_publisher().has_site_option('auquotidien-strongvox')):
|
|
||||||
return super(SettingsDirectory, self)._q_index()
|
return super(SettingsDirectory, self)._q_index()
|
||||||
r = TemplateIO(html=True)
|
r = TemplateIO(html=True)
|
||||||
r += htmltext(super(SettingsDirectory, self)._q_index())
|
r += htmltext(super(SettingsDirectory, self)._q_index())
|
||||||
|
@ -109,8 +76,6 @@ class SettingsDirectory(wcs.admin.settings.SettingsDirectory):
|
||||||
r += htmltext('<h2>%s</h2>') % _('Extra Options')
|
r += htmltext('<h2>%s</h2>') % _('Extra Options')
|
||||||
r += htmltext('<ul>')
|
r += htmltext('<ul>')
|
||||||
r += htmltext('<li><a href="aq/permissions">%s</a></li>') % _('Permissions')
|
r += htmltext('<li><a href="aq/permissions">%s</a></li>') % _('Permissions')
|
||||||
if get_publisher().has_site_option('strongbox'):
|
|
||||||
r += htmltext('<li><a href="aq/strongbox">%s</a></li>') % _('Strongbox Support')
|
|
||||||
if get_publisher().has_site_option('domino'):
|
if get_publisher().has_site_option('domino'):
|
||||||
r += htmltext('<li><a href="aq/domino">%s</a></li>') % _('Abelium Domino Integration')
|
r += htmltext('<li><a href="aq/domino">%s</a></li>') % _('Abelium Domino Integration')
|
||||||
r += htmltext('</ul>')
|
r += htmltext('</ul>')
|
||||||
|
|
|
@ -28,13 +28,6 @@ def check_visibility(target, user=CURRENT_USER):
|
||||||
target = target.strip('/')
|
target = target.strip('/')
|
||||||
if target == 'management':
|
if target == 'management':
|
||||||
target = 'forms'
|
target = 'forms'
|
||||||
if target == 'strongbox':
|
|
||||||
if not get_publisher().has_site_option(target):
|
|
||||||
# strongbox disabled in site-options.cfg
|
|
||||||
return False
|
|
||||||
if not get_cfg('misc', {}).get('aq-strongbox'):
|
|
||||||
# strongbox disabled in settings panel
|
|
||||||
return False
|
|
||||||
admin_role = get_cfg('aq-permissions', {}).get(target, None)
|
admin_role = get_cfg('aq-permissions', {}).get(target, None)
|
||||||
if not admin_role:
|
if not admin_role:
|
||||||
return False
|
return False
|
||||||
|
|
|
@ -25,7 +25,6 @@ from wcs.qommon.admin.texts import TextsDirectory
|
||||||
from wcs.formdef import FormDef
|
from wcs.formdef import FormDef
|
||||||
import wcs.myspace
|
import wcs.myspace
|
||||||
|
|
||||||
from .strongbox import StrongboxItem, StrongboxType
|
|
||||||
from .payments import Invoice, Regie, is_payment_supported
|
from .payments import Invoice, Regie, is_payment_supported
|
||||||
|
|
||||||
class MyInvoicesDirectory(Directory):
|
class MyInvoicesDirectory(Directory):
|
||||||
|
@ -108,260 +107,6 @@ class MyInvoicesDirectory(Directory):
|
||||||
return r.getvalue()
|
return r.getvalue()
|
||||||
|
|
||||||
|
|
||||||
class StrongboxDirectory(Directory):
|
|
||||||
_q_exports = ['', 'add', 'download', 'remove', 'pick', 'validate']
|
|
||||||
|
|
||||||
def _q_traverse(self, path):
|
|
||||||
if not get_cfg('misc', {}).get('aq-strongbox'):
|
|
||||||
raise errors.TraversalError()
|
|
||||||
get_response().breadcrumb.append(('strongbox/', _('Strongbox')))
|
|
||||||
return Directory._q_traverse(self, path)
|
|
||||||
|
|
||||||
def get_form(self):
|
|
||||||
types = [(x.id, x.label) for x in StrongboxType.select()]
|
|
||||||
form = Form(action='add', enctype='multipart/form-data')
|
|
||||||
form.add(StringWidget, 'description', title=_('Description'), size=60)
|
|
||||||
form.add(FileWidget, 'file', title=_('File'), required=True)
|
|
||||||
form.add(SingleSelectWidget, 'type_id', title=_('Document Type'),
|
|
||||||
options = [(None, _('Not specified'))] + types)
|
|
||||||
form.add(DateWidget, 'date_time', title = _('Document Date'))
|
|
||||||
form.add_submit('submit', _('Upload'))
|
|
||||||
return form
|
|
||||||
|
|
||||||
def _q_index(self):
|
|
||||||
template.html_top(_('Strongbox'))
|
|
||||||
r = TemplateIO(html=True)
|
|
||||||
|
|
||||||
# TODO: a paragraph of explanations here could be useful
|
|
||||||
|
|
||||||
sffiles = list(StrongboxItem.get_with_indexed_value(
|
|
||||||
str('user_id'), str(get_request().user.id)))
|
|
||||||
if sffiles:
|
|
||||||
r += htmltext('<table id="strongbox-items">')
|
|
||||||
r += htmltext('<tr><th></th><th>%s</th><th>%s</th><th></th></tr>') % (
|
|
||||||
_('Type'), _('Expiration'))
|
|
||||||
else:
|
|
||||||
r += htmltext('<p>')
|
|
||||||
r += _('There is currently nothing in your strongbox.')
|
|
||||||
r += htmltext('</p>')
|
|
||||||
has_items_to_validate = False
|
|
||||||
for i, sffile in enumerate(sffiles):
|
|
||||||
expired = False
|
|
||||||
if not sffile.validated_time:
|
|
||||||
has_items_to_validate = True
|
|
||||||
continue
|
|
||||||
if sffile.expiration_time and sffile.expiration_time < time.localtime():
|
|
||||||
expired = True
|
|
||||||
if i%2:
|
|
||||||
classnames = ['odd']
|
|
||||||
else:
|
|
||||||
classnames = ['even']
|
|
||||||
if expired:
|
|
||||||
classnames.append('expired')
|
|
||||||
r += htmltext('<tr class="%s">') % ' '.join(classnames)
|
|
||||||
r += htmltext('<td class="label">')
|
|
||||||
r += sffile.get_display_name()
|
|
||||||
r += htmltext('</td>')
|
|
||||||
if sffile.type_id:
|
|
||||||
r += htmltext('<td class="type">%s</td>') % StrongboxType.get(sffile.type_id).label
|
|
||||||
else:
|
|
||||||
r += htmltext('<td class="type">-</td>')
|
|
||||||
if sffile.expiration_time:
|
|
||||||
r += htmltext('<td class="expiration">%s') % strftime(misc.date_format(), sffile.expiration_time)
|
|
||||||
if expired:
|
|
||||||
r += ' (%s)' % _('expired')
|
|
||||||
r += htmltext('</td>')
|
|
||||||
else:
|
|
||||||
r += htmltext('<td class="expiration">-</td>')
|
|
||||||
r += htmltext('<td class="actions">')
|
|
||||||
r += htmltext(' [<a href="download?id=%s">%s</a>] ') % (sffile.id, _('download'))
|
|
||||||
r += htmltext('[<a rel="popup" href="remove?id=%s">%s</a>] ') % (sffile.id, _('remove'))
|
|
||||||
r += htmltext('</td>')
|
|
||||||
r += htmltext('</tr>')
|
|
||||||
|
|
||||||
if has_items_to_validate:
|
|
||||||
r += htmltext('<tr><td colspan="4"><h3>%s</h3></td></tr>') % _('Proposed Items')
|
|
||||||
for sffile in sffiles:
|
|
||||||
if sffile.validated_time:
|
|
||||||
continue
|
|
||||||
if sffile.expiration_time and sffile.expiration_time < time.localtime():
|
|
||||||
expired = True
|
|
||||||
if i%2:
|
|
||||||
classnames = ['odd']
|
|
||||||
else:
|
|
||||||
classnames = ['even']
|
|
||||||
if expired:
|
|
||||||
classnames.append('expired')
|
|
||||||
r += htmltext('<tr class="%s">') % ' '.join(classnames)
|
|
||||||
|
|
||||||
r += htmltext('<td class="label">')
|
|
||||||
r += sffile.get_display_name()
|
|
||||||
r += htmltext('</td>')
|
|
||||||
if sffile.type_id:
|
|
||||||
r += htmltext('<td class="type">%s</td>') % StrongboxType.get(sffile.type_id).label
|
|
||||||
else:
|
|
||||||
r += htmltext('<td class="type">-</td>')
|
|
||||||
|
|
||||||
if sffile.expiration_time:
|
|
||||||
r += htmltext('<td class="expiration">%s') % strftime(misc.date_format(), sffile.expiration_time)
|
|
||||||
if expired:
|
|
||||||
r += ' (%s)' % _('expired')
|
|
||||||
r += htmltext('</td>')
|
|
||||||
else:
|
|
||||||
r += htmltext('<td class="expiration">-</td>')
|
|
||||||
r += htmltext('<td class="actions">')
|
|
||||||
r += htmltext(' [<a href="download?id=%s">%s</a>] ') % (sffile.id, _('download'))
|
|
||||||
r += htmltext(' [<a href="validate?id=%s">%s</a>] ') % (sffile.id, _('validate'))
|
|
||||||
r += htmltext(' [<a href="remove?id=%s">%s</a>] ') % (sffile.id, _('reject'))
|
|
||||||
r += htmltext('</td>')
|
|
||||||
r += htmltext('</tr>')
|
|
||||||
if sffiles:
|
|
||||||
r += htmltext('</table>')
|
|
||||||
|
|
||||||
r += htmltext('<h3>%s</h3>') % _('Add a file to the strongbox')
|
|
||||||
form = self.get_form()
|
|
||||||
r += form.render()
|
|
||||||
return r.getvalue()
|
|
||||||
|
|
||||||
def add(self):
|
|
||||||
form = self.get_form()
|
|
||||||
if not form.is_submitted():
|
|
||||||
if get_request().form.get('mode') == 'pick':
|
|
||||||
return redirect('pick')
|
|
||||||
else:
|
|
||||||
return redirect('.')
|
|
||||||
|
|
||||||
sffile = StrongboxItem()
|
|
||||||
sffile.user_id = get_request().user.id
|
|
||||||
sffile.description = form.get_widget('description').parse()
|
|
||||||
sffile.validated_time = time.localtime()
|
|
||||||
sffile.type_id = form.get_widget('type_id').parse()
|
|
||||||
v = form.get_widget('date_time').parse()
|
|
||||||
sffile.set_expiration_time_from_date(v)
|
|
||||||
sffile.store()
|
|
||||||
sffile.set_file(form.get_widget('file').parse())
|
|
||||||
sffile.store()
|
|
||||||
if get_request().form.get('mode') == 'pick':
|
|
||||||
return redirect('pick')
|
|
||||||
else:
|
|
||||||
return redirect('.')
|
|
||||||
|
|
||||||
def download(self):
|
|
||||||
id = get_request().form.get('id')
|
|
||||||
if not id:
|
|
||||||
raise errors.TraversalError()
|
|
||||||
try:
|
|
||||||
sffile = StrongboxItem.get(id)
|
|
||||||
except KeyError:
|
|
||||||
raise errors.TraversalError()
|
|
||||||
if str(sffile.user_id) != str(get_request().user.id):
|
|
||||||
raise errors.TraversalError()
|
|
||||||
|
|
||||||
filename = sffile.file.filename
|
|
||||||
fd = file(filename)
|
|
||||||
size = os.path.getsize(filename)
|
|
||||||
response = get_response()
|
|
||||||
response.set_content_type('application/octet-stream')
|
|
||||||
response.set_header('content-disposition', 'attachment; filename="%s"' % sffile.file.base_filename)
|
|
||||||
return FileStream(fd, size)
|
|
||||||
|
|
||||||
def validate(self):
|
|
||||||
id = get_request().form.get('id')
|
|
||||||
if not id:
|
|
||||||
raise errors.TraversalError()
|
|
||||||
try:
|
|
||||||
sffile = StrongboxItem.get(id)
|
|
||||||
except KeyError:
|
|
||||||
raise errors.TraversalError()
|
|
||||||
if str(sffile.user_id) != str(get_request().user.id):
|
|
||||||
raise errors.TraversalError()
|
|
||||||
sffile.validated_time = time.time()
|
|
||||||
sffile.store()
|
|
||||||
return redirect('.')
|
|
||||||
|
|
||||||
def remove(self):
|
|
||||||
id = get_request().form.get('id')
|
|
||||||
if not id:
|
|
||||||
raise errors.TraversalError()
|
|
||||||
try:
|
|
||||||
sffile = StrongboxItem.get(id)
|
|
||||||
except KeyError:
|
|
||||||
raise errors.TraversalError()
|
|
||||||
if str(sffile.user_id) != str(get_request().user.id):
|
|
||||||
raise errors.TraversalError()
|
|
||||||
|
|
||||||
r = TemplateIO(html=True)
|
|
||||||
form = Form(enctype='multipart/form-data')
|
|
||||||
form.add_hidden('id', get_request().form.get('id'))
|
|
||||||
form.widgets.append(HtmlWidget('<p>%s</p>' % _(
|
|
||||||
'You are about to irrevocably delete this item from your strongbox.')))
|
|
||||||
form.add_submit('submit', _('Submit'))
|
|
||||||
form.add_submit('cancel', _('Cancel'))
|
|
||||||
if form.get_submit() == 'cancel':
|
|
||||||
return redirect('.')
|
|
||||||
if not form.is_submitted() or form.has_errors():
|
|
||||||
if sffile.type_id:
|
|
||||||
r += htmltext('<h2>%s</h2>') % _('Deleting %(filetype)s: %(filename)s') % {
|
|
||||||
'filetype': StrongboxType.get(sffile.type_id).label,
|
|
||||||
'filename': sffile.get_display_name()
|
|
||||||
}
|
|
||||||
else:
|
|
||||||
r += htmltext('<h2>%s</h2>') % _('Deleting %(filename)s') % {'filename': sffile.get_display_name()}
|
|
||||||
r += form.render()
|
|
||||||
return r.getvalue()
|
|
||||||
else:
|
|
||||||
sffile.remove_self()
|
|
||||||
sffile.remove_file()
|
|
||||||
return redirect('.')
|
|
||||||
|
|
||||||
def picked_file(self):
|
|
||||||
get_response().set_content_type('application/json')
|
|
||||||
sffile = StrongboxItem.get(get_request().form.get('val'))
|
|
||||||
sffile.file.fp = file(sffile.file.filename)
|
|
||||||
if sffile.user_id != get_request().user.id:
|
|
||||||
raise errors.TraversalError()
|
|
||||||
# XXX: this will copy the file, it would be quite nice if it was
|
|
||||||
# possible to just make it a symlink to the sffile
|
|
||||||
token = get_session().add_tempfile(sffile.file)
|
|
||||||
return json.dumps({'token': token, 'filename': sffile.file.base_filename})
|
|
||||||
|
|
||||||
def pick(self):
|
|
||||||
if get_request().form.get('select') == 'true':
|
|
||||||
return self.picked_file()
|
|
||||||
r = TemplateIO(html=True)
|
|
||||||
root_url = get_publisher().get_root_url()
|
|
||||||
sffiles = list(StrongboxItem.get_with_indexed_value(
|
|
||||||
str('user_id'), str(get_request().user.id)))
|
|
||||||
r += htmltext('<h2>%s</h2>') % _('Pick a file')
|
|
||||||
|
|
||||||
if not sffiles:
|
|
||||||
r += htmltext('<p>')
|
|
||||||
r += _('You do not have any file in your strongbox at the moment.')
|
|
||||||
r += htmltext('</p>')
|
|
||||||
r += htmltext('<div class="buttons">')
|
|
||||||
r += htmltext('<a href="%smyspace/strongbox/" target="_blank">%s</a>') % (root_url,
|
|
||||||
_('Open Strongbox Management'))
|
|
||||||
r += htmltext('</div>')
|
|
||||||
else:
|
|
||||||
r += htmltext('<form id="strongbox-pick">')
|
|
||||||
r += htmltext('<ul>')
|
|
||||||
for sffile in sffiles:
|
|
||||||
r += htmltext('<li><label><input type="radio" name="file" value="%s"/>%s</label>') % (
|
|
||||||
sffile.id, sffile.get_display_name())
|
|
||||||
r += htmltext(' [<a href="%smyspace/strongbox/download?id=%s">%s</a>] ') % (
|
|
||||||
root_url, sffile.id, _('view'))
|
|
||||||
r += htmltext('</li>')
|
|
||||||
r += htmltext('</ul>')
|
|
||||||
|
|
||||||
r += htmltext('<div class="buttons">')
|
|
||||||
r += htmltext('<input name="cancel" type="button" value="%s"/>') % _('Cancel')
|
|
||||||
r += ' '
|
|
||||||
r += htmltext('<input name="pick" type="button" value="%s"/>') % _('Pick')
|
|
||||||
r += htmltext('</div>')
|
|
||||||
r += htmltext('</form>')
|
|
||||||
return r.getvalue()
|
|
||||||
|
|
||||||
|
|
||||||
class JsonDirectory(Directory):
|
class JsonDirectory(Directory):
|
||||||
'''Export of several lists in json, related to the current user or the
|
'''Export of several lists in json, related to the current user or the
|
||||||
SAMLv2 NameID we'd get in the URL'''
|
SAMLv2 NameID we'd get in the URL'''
|
||||||
|
@ -410,9 +155,8 @@ class JsonDirectory(Directory):
|
||||||
|
|
||||||
class MyspaceDirectory(wcs.myspace.MyspaceDirectory):
|
class MyspaceDirectory(wcs.myspace.MyspaceDirectory):
|
||||||
_q_exports = ['', 'profile', 'new', 'password', 'remove', 'drafts', 'forms',
|
_q_exports = ['', 'profile', 'new', 'password', 'remove', 'drafts', 'forms',
|
||||||
'strongbox', 'invoices', 'json']
|
'invoices', 'json']
|
||||||
|
|
||||||
strongbox = StrongboxDirectory()
|
|
||||||
invoices = MyInvoicesDirectory()
|
invoices = MyInvoicesDirectory()
|
||||||
json = JsonDirectory()
|
json = JsonDirectory()
|
||||||
|
|
||||||
|
@ -457,8 +201,6 @@ class MyspaceDirectory(wcs.myspace.MyspaceDirectory):
|
||||||
profile_links.append('<a href="#my-profile">%s</a>' % _('My Profile'))
|
profile_links.append('<a href="#my-profile">%s</a>' % _('My Profile'))
|
||||||
if user_forms:
|
if user_forms:
|
||||||
profile_links.append('<a href="#my-forms">%s</a>' % _('My Forms'))
|
profile_links.append('<a href="#my-forms">%s</a>' % _('My Forms'))
|
||||||
if get_cfg('misc', {}).get('aq-strongbox'):
|
|
||||||
profile_links.append('<a href="strongbox/">%s</a>' % _('My Strongbox'))
|
|
||||||
if is_payment_supported():
|
if is_payment_supported():
|
||||||
profile_links.append('<a href="invoices/">%s</a>' % _('My Invoices'))
|
profile_links.append('<a href="invoices/">%s</a>' % _('My Invoices'))
|
||||||
|
|
||||||
|
|
|
@ -1,98 +0,0 @@
|
||||||
import os
|
|
||||||
import time
|
|
||||||
|
|
||||||
from quixote import get_publisher
|
|
||||||
from wcs.qommon.storage import StorableObject
|
|
||||||
from wcs.qommon import misc
|
|
||||||
|
|
||||||
class StrongboxType(StorableObject):
|
|
||||||
_names = 'strongbox-types'
|
|
||||||
|
|
||||||
id = None
|
|
||||||
label = None
|
|
||||||
validation_months = 0
|
|
||||||
|
|
||||||
|
|
||||||
class StrongboxFile():
|
|
||||||
id = None
|
|
||||||
orig_filename = None
|
|
||||||
base_filename = None
|
|
||||||
content_type = None
|
|
||||||
charset = None
|
|
||||||
|
|
||||||
def __init__(self, id, f):
|
|
||||||
self.id = id
|
|
||||||
self.orig_filename = f.orig_filename
|
|
||||||
self.base_filename = f.base_filename
|
|
||||||
self.content_type = f.content_type
|
|
||||||
self.charset = f.charset
|
|
||||||
self.fp = f.fp
|
|
||||||
|
|
||||||
def __getstate__(self):
|
|
||||||
odict = self.__dict__.copy()
|
|
||||||
if not odict.has_key('fp'):
|
|
||||||
return odict
|
|
||||||
|
|
||||||
# XXX: add some locking
|
|
||||||
del odict['fp']
|
|
||||||
dirname = os.path.join(get_publisher().app_dir, 'strongbox-files')
|
|
||||||
if not os.path.exists(dirname):
|
|
||||||
os.mkdir(dirname)
|
|
||||||
odict['filename'] = os.path.join(dirname, str(self.id))
|
|
||||||
self.fp.seek(0)
|
|
||||||
fd = file(odict['filename'], 'w')
|
|
||||||
fd.write(self.fp.read())
|
|
||||||
fd.close()
|
|
||||||
return odict
|
|
||||||
|
|
||||||
|
|
||||||
class StrongboxItem(StorableObject):
|
|
||||||
_names = 'strongbox-items'
|
|
||||||
_hashed_indexes = ['user_id']
|
|
||||||
|
|
||||||
user_id = None
|
|
||||||
description = None
|
|
||||||
file = None
|
|
||||||
type_id = None
|
|
||||||
expiration_time = None
|
|
||||||
proposed_by = None
|
|
||||||
proposed_time = None
|
|
||||||
validated_time = None
|
|
||||||
|
|
||||||
def get_display_name(self):
|
|
||||||
if self.description:
|
|
||||||
return self.description
|
|
||||||
return self.file.base_filename
|
|
||||||
|
|
||||||
def set_file(self, file):
|
|
||||||
self.file = StrongboxFile(self.id, file)
|
|
||||||
|
|
||||||
def remove_file(self):
|
|
||||||
os.unlink(self.file.filename)
|
|
||||||
|
|
||||||
def set_expiration_time_from_date(self, value):
|
|
||||||
if not value:
|
|
||||||
self.expiration_time = None
|
|
||||||
return
|
|
||||||
if not StrongboxType.has_key(self.type_id):
|
|
||||||
return
|
|
||||||
|
|
||||||
if not StrongboxType.get(self.type_id).validation_months:
|
|
||||||
self.expiration_time = None
|
|
||||||
return
|
|
||||||
|
|
||||||
date = time.strptime(value, misc.date_format())
|
|
||||||
year, month, day = date[:3]
|
|
||||||
month += StrongboxType.get(self.type_id).validation_months
|
|
||||||
while month > 12:
|
|
||||||
year += 1
|
|
||||||
month -= 12
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
self.expiration_time = time.strptime(
|
|
||||||
'%04d-%02d-%02d' % (year, month, day), '%Y-%m-%d')
|
|
||||||
except ValueError:
|
|
||||||
day -= 1
|
|
||||||
continue
|
|
||||||
break
|
|
||||||
|
|
|
@ -1,284 +0,0 @@
|
||||||
import time
|
|
||||||
|
|
||||||
from quixote import get_request, get_response, get_session, redirect
|
|
||||||
from quixote.directory import Directory, AccessControlled
|
|
||||||
from quixote.html import TemplateIO, htmltext
|
|
||||||
|
|
||||||
import wcs
|
|
||||||
import wcs.admin.root
|
|
||||||
|
|
||||||
from wcs.qommon import _
|
|
||||||
from wcs.qommon import errors, misc
|
|
||||||
from wcs.qommon.form import *
|
|
||||||
from wcs.qommon.backoffice.menu import html_top
|
|
||||||
from wcs.qommon import get_cfg
|
|
||||||
|
|
||||||
from .strongbox import StrongboxType, StrongboxItem
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class StrongboxTypeDirectory(Directory):
|
|
||||||
_q_exports = ['', 'edit', 'delete']
|
|
||||||
|
|
||||||
def __init__(self, strongboxtype):
|
|
||||||
self.strongboxtype = strongboxtype
|
|
||||||
|
|
||||||
def _q_index(self):
|
|
||||||
html_top('strongbox', title = _('Item Type: %s') % self.strongboxtype.label)
|
|
||||||
r = TemplateIO(html=True)
|
|
||||||
r += htmltext('<h2>%s</h2>') % _('Item Type: %s') % self.strongboxtype.label
|
|
||||||
get_response().filter['sidebar'] = self.get_sidebar()
|
|
||||||
r += get_session().display_message()
|
|
||||||
|
|
||||||
if self.strongboxtype.validation_months:
|
|
||||||
r += htmltext('<div class="bo-block">')
|
|
||||||
r += htmltext('<ul>')
|
|
||||||
r += htmltext('<li>')
|
|
||||||
r += _('Number of months of validity:')
|
|
||||||
r += ' '
|
|
||||||
r += self.strongboxtype.validation_months
|
|
||||||
r += htmltext('</li>')
|
|
||||||
r += htmltext('</ul>')
|
|
||||||
r += htmltext('</div>')
|
|
||||||
|
|
||||||
return r.getvalue()
|
|
||||||
|
|
||||||
def get_sidebar(self):
|
|
||||||
r = TemplateIO(html=True)
|
|
||||||
r += htmltext('<ul>')
|
|
||||||
r += htmltext('<li><a href="edit">%s</a></li>') % _('Edit')
|
|
||||||
r += htmltext('<li><a href="delete">%s</a></li>') % _('Delete')
|
|
||||||
r += htmltext('</ul>')
|
|
||||||
return r.getvalue()
|
|
||||||
|
|
||||||
def edit(self):
|
|
||||||
form = self.form()
|
|
||||||
if form.get_submit() == 'cancel':
|
|
||||||
return redirect('.')
|
|
||||||
|
|
||||||
if form.is_submitted() and not form.has_errors():
|
|
||||||
self.submit(form)
|
|
||||||
return redirect('..')
|
|
||||||
|
|
||||||
html_top('strongbox', title = _('Edit Item Type: %s') % self.strongboxtype.label)
|
|
||||||
r = TemplateIO(html=True)
|
|
||||||
r += htmltext('<h2>%s</h2>') % _('Edit Item Type: %s') % self.strongboxtype.label
|
|
||||||
r += form.render()
|
|
||||||
return r.getvalue()
|
|
||||||
|
|
||||||
def form(self):
|
|
||||||
form = Form(enctype='multipart/form-data')
|
|
||||||
form.add(StringWidget, 'label', title = _('Label'), required = True,
|
|
||||||
value = self.strongboxtype.label)
|
|
||||||
form.add(IntWidget, 'validation_months', title=_('Number of months of validity'),
|
|
||||||
value=self.strongboxtype.validation_months,
|
|
||||||
hint=_('Use 0 if there is no expiration'))
|
|
||||||
form.add_submit('submit', _('Submit'))
|
|
||||||
form.add_submit('cancel', _('Cancel'))
|
|
||||||
return form
|
|
||||||
|
|
||||||
def submit(self, form):
|
|
||||||
for k in ('label', 'validation_months'):
|
|
||||||
widget = form.get_widget(k)
|
|
||||||
if widget:
|
|
||||||
setattr(self.strongboxtype, k, widget.parse())
|
|
||||||
self.strongboxtype.store()
|
|
||||||
|
|
||||||
def delete(self):
|
|
||||||
form = Form(enctype='multipart/form-data')
|
|
||||||
form.widgets.append(HtmlWidget('<p>%s</p>' % _(
|
|
||||||
'You are about to irrevocably delete this item type.')))
|
|
||||||
form.add_submit('submit', _('Submit'))
|
|
||||||
form.add_submit('cancel', _('Cancel'))
|
|
||||||
if form.get_submit() == 'cancel':
|
|
||||||
return redirect('..')
|
|
||||||
if not form.is_submitted() or form.has_errors():
|
|
||||||
get_response().breadcrumb.append(('delete', _('Delete')))
|
|
||||||
html_top('strongbox', title = _('Delete Item Type'))
|
|
||||||
r = TemplateIO(html=True)
|
|
||||||
r += htmltext('<h2>%s</h2>') % _('Deleting Item Type: %s') % self.strongboxtype.label
|
|
||||||
r += form.render()
|
|
||||||
return r.getvalue()
|
|
||||||
else:
|
|
||||||
self.strongboxtype.remove_self()
|
|
||||||
return redirect('..')
|
|
||||||
|
|
||||||
|
|
||||||
class StrongboxTypesDirectory(Directory):
|
|
||||||
_q_exports = ['', 'new']
|
|
||||||
|
|
||||||
def _q_traverse(self, path):
|
|
||||||
get_response().breadcrumb.append(('types/', _('Item Types')))
|
|
||||||
return Directory._q_traverse(self, path)
|
|
||||||
|
|
||||||
def _q_index(self):
|
|
||||||
return redirect('..')
|
|
||||||
|
|
||||||
def new(self):
|
|
||||||
type_ui = StrongboxTypeDirectory(StrongboxType())
|
|
||||||
|
|
||||||
form = type_ui.form()
|
|
||||||
if form.get_submit() == 'cancel':
|
|
||||||
return redirect('.')
|
|
||||||
|
|
||||||
if form.is_submitted() and not form.has_errors():
|
|
||||||
type_ui.submit(form)
|
|
||||||
return redirect('%s/' % type_ui.strongboxtype.id)
|
|
||||||
|
|
||||||
get_response().breadcrumb.append(('new', _('New Item Type')))
|
|
||||||
html_top('strongbox', title = _('New Item Type'))
|
|
||||||
r = TemplateIO(html=True)
|
|
||||||
r += htmltext('<h2>%s</h2>') % _('New Item Type')
|
|
||||||
r += form.render()
|
|
||||||
return r.getvalue()
|
|
||||||
|
|
||||||
def _q_lookup(self, component):
|
|
||||||
try:
|
|
||||||
strongboxtype = StrongboxType.get(component)
|
|
||||||
except KeyError:
|
|
||||||
raise errors.TraversalError()
|
|
||||||
get_response().breadcrumb.append((str(strongboxtype.id), strongboxtype.label))
|
|
||||||
return StrongboxTypeDirectory(strongboxtype)
|
|
||||||
|
|
||||||
|
|
||||||
class StrongboxDirectory(AccessControlled, Directory):
|
|
||||||
_q_exports = ['', 'types', 'add', 'add_to']
|
|
||||||
label = N_('Strongbox')
|
|
||||||
|
|
||||||
types = StrongboxTypesDirectory()
|
|
||||||
|
|
||||||
def is_accessible(self, user):
|
|
||||||
from .backoffice import check_visibility
|
|
||||||
return check_visibility('strongbox', user)
|
|
||||||
|
|
||||||
def _q_access(self):
|
|
||||||
user = get_request().user
|
|
||||||
if not user:
|
|
||||||
raise errors.AccessUnauthorizedError()
|
|
||||||
|
|
||||||
if not self.is_accessible(user):
|
|
||||||
raise errors.AccessForbiddenError(
|
|
||||||
public_msg = _('You are not allowed to access Strongbox Management'),
|
|
||||||
location_hint = 'backoffice')
|
|
||||||
|
|
||||||
get_response().breadcrumb.append(('strongbox/', _('Strongbox')))
|
|
||||||
|
|
||||||
|
|
||||||
def _q_index(self):
|
|
||||||
html_top('strongbox', _('Strongbox'))
|
|
||||||
r = TemplateIO(html=True)
|
|
||||||
get_response().filter['sidebar'] = self.get_sidebar()
|
|
||||||
|
|
||||||
r += get_session().display_message()
|
|
||||||
|
|
||||||
r += htmltext('<div class="splitcontent-left">')
|
|
||||||
r += htmltext('<div class="bo-block">')
|
|
||||||
r += htmltext('<h2>%s</h2>') % _('Propose a file to a user')
|
|
||||||
form = Form(enctype='multipart/form-data')
|
|
||||||
form.add(StringWidget, 'q', title = _('User'), required=True)
|
|
||||||
form.add_submit('search', _('Search'))
|
|
||||||
r += form.render()
|
|
||||||
if form.is_submitted() and not form.has_errors():
|
|
||||||
q = form.get_widget('q').parse()
|
|
||||||
users = self.search_for_users(q)
|
|
||||||
if users:
|
|
||||||
if len(users) == 1:
|
|
||||||
return redirect('add_to?user_id=%s' % users[0].id)
|
|
||||||
if len(users) < 50:
|
|
||||||
r += _('(first 50 users only)')
|
|
||||||
r += htmltext('<ul>')
|
|
||||||
for u in users:
|
|
||||||
r += htmltext('<li><a href="add_to?user_id=%s">%s</a></li>') % (u.id, u.display_name)
|
|
||||||
r += htmltext('</ul>')
|
|
||||||
else:
|
|
||||||
r += _('No user found.')
|
|
||||||
r += htmltext('</div>')
|
|
||||||
r += htmltext('</div>')
|
|
||||||
|
|
||||||
r += htmltext('<div class="splitcontent-right">')
|
|
||||||
r += htmltext('<div class="bo-block">')
|
|
||||||
types = StrongboxType.select()
|
|
||||||
r += htmltext('<h2>%s</h2>') % _('Item Types')
|
|
||||||
if not types:
|
|
||||||
r += htmltext('<p>')
|
|
||||||
r += _('There is no item types defined at the moment.')
|
|
||||||
r += htmltext('</p>')
|
|
||||||
|
|
||||||
r += htmltext('<ul class="biglist" id="strongbox-list">')
|
|
||||||
for l in types:
|
|
||||||
type_id = l.id
|
|
||||||
r += htmltext('<li class="biglistitem" id="itemId_%s">') % type_id
|
|
||||||
r += htmltext('<strong class="label"><a href="types/%s/">%s</a></strong>') % (type_id, l.label)
|
|
||||||
r += htmltext('</li>')
|
|
||||||
r += htmltext('</ul>')
|
|
||||||
r += htmltext('</div>')
|
|
||||||
r += htmltext('</div>')
|
|
||||||
return r.getvalue()
|
|
||||||
|
|
||||||
def get_sidebar(self):
|
|
||||||
r = TemplateIO(html=True)
|
|
||||||
r += htmltext('<ul id="sidebar-actions">')
|
|
||||||
r += htmltext(' <li><a class="new-item" href="types/new">%s</a></li>') % _('New Item Type')
|
|
||||||
r += htmltext('</ul>')
|
|
||||||
return r.getvalue()
|
|
||||||
|
|
||||||
def search_for_users(self, q):
|
|
||||||
if hasattr(get_publisher().user_class, 'search'):
|
|
||||||
return get_publisher().user_class.search(q)
|
|
||||||
if q:
|
|
||||||
users = [x for x in get_publisher().user_class.select()
|
|
||||||
if q in (x.name or '') or q in (x.email or '')]
|
|
||||||
return users
|
|
||||||
else:
|
|
||||||
return []
|
|
||||||
|
|
||||||
def get_form(self):
|
|
||||||
types = [(x.id, x.label) for x in StrongboxType.select()]
|
|
||||||
form = Form(action='add', enctype='multipart/form-data')
|
|
||||||
form.add(StringWidget, 'description', title=_('Description'), size=60)
|
|
||||||
form.add(FileWidget, 'file', title=_('File'), required=True)
|
|
||||||
form.add(SingleSelectWidget, 'type_id', title=_('Document Type'),
|
|
||||||
options = [(None, _('Not specified'))] + types)
|
|
||||||
form.add(DateWidget, 'date_time', title = _('Document Date'))
|
|
||||||
form.add_submit('submit', _('Upload'))
|
|
||||||
return form
|
|
||||||
|
|
||||||
def add(self):
|
|
||||||
form = self.get_form()
|
|
||||||
form.add(StringWidget, 'user_id', title=_('User'))
|
|
||||||
if not form.is_submitted():
|
|
||||||
return redirect('.')
|
|
||||||
|
|
||||||
sffile = StrongboxItem()
|
|
||||||
sffile.user_id = form.get_widget('user_id').parse()
|
|
||||||
sffile.description = form.get_widget('description').parse()
|
|
||||||
sffile.proposed_time = time.localtime()
|
|
||||||
sffile.proposed_id = get_request().user.id
|
|
||||||
sffile.type_id = form.get_widget('type_id').parse()
|
|
||||||
v = form.get_widget('date_time').parse()
|
|
||||||
sffile.set_expiration_time_from_date(v)
|
|
||||||
sffile.store()
|
|
||||||
sffile.set_file(form.get_widget('file').parse())
|
|
||||||
sffile.store()
|
|
||||||
return redirect('.')
|
|
||||||
|
|
||||||
def add_to(self):
|
|
||||||
form = Form(enctype='multipart/form-data', action='add_to')
|
|
||||||
form.add(StringWidget, 'user_id', title = _('User'), required=True)
|
|
||||||
try:
|
|
||||||
user_id = form.get_widget('user_id').parse()
|
|
||||||
user = get_publisher().user_class.get(user_id)
|
|
||||||
except:
|
|
||||||
return redirect('.')
|
|
||||||
if not user:
|
|
||||||
return redirect('.')
|
|
||||||
get_request().form = {}
|
|
||||||
get_request().environ['REQUEST_METHOD'] = 'GET'
|
|
||||||
|
|
||||||
html_top('strongbox', _('Strongbox'))
|
|
||||||
r = TemplateIO(html=True)
|
|
||||||
r += htmltext('<h2>%s %s</h2>') % (_('Propose a file to:'), user.display_name)
|
|
||||||
form = self.get_form()
|
|
||||||
form.add(HiddenWidget, 'user_id', title=_('User'), value=user.id)
|
|
||||||
r += form.render()
|
|
||||||
return r.getvalue()
|
|
Reference in New Issue