wcs/wcs/backoffice/snapshots.py

167 lines
6.4 KiB
Python

# w.c.s. - web application for online forms
# Copyright (C) 2005-2020 Entr'ouvert
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
from quixote import get_publisher, get_response, redirect
from quixote.directory import Directory
from quixote.html import TemplateIO, htmltext
from wcs.qommon import _, errors, misc, template
from wcs.qommon.backoffice.menu import html_top
from wcs.qommon.form import Form, RadiobuttonsWidget, StringWidget
from wcs.qommon.storage import Equal
class SnapshotsDirectory(Directory):
_q_exports = ['', 'save']
do_not_call_in_templates = True
def __init__(self, instance):
self.obj = instance
self.object_type = instance.xml_root_node
self.object_id = instance.id
def _q_traverse(self, path):
get_response().breadcrumb.append(('history/', _('History')))
return super()._q_traverse(path)
def _q_index(self):
html_top('', _('History'))
return template.QommonTemplateResponse(
templates=['wcs/backoffice/snapshots.html'],
context={'view': self})
def save(self):
form = Form(enctype='multipart/form-data')
label = form.add(StringWidget, 'label', title=_('Label'), required=True)
form.add_submit('submit', _('Submit'))
form.add_submit('cancel', _('Cancel'))
if form.get_widget('cancel').parse():
return redirect('../')
if form.is_submitted() and not form.has_errors():
get_publisher().snapshot_class.snap(instance=self.obj, label=label.parse())
return redirect('../')
html_top('', _('History'))
r = TemplateIO(html=True)
r += htmltext('<h2>%s</h2>') % _('Save snapshot')
r += form.render()
return r.getvalue()
def snapshots(self):
current_date = None
snapshots = get_publisher().snapshot_class.select_object_history(self.obj)
day_snapshot = None
for i, snapshot in enumerate(snapshots):
if snapshot.timestamp.date() != current_date:
current_date = snapshot.timestamp.date()
snapshot.new_day = True
snapshot.day_other_count = 0
day_snapshot = snapshot
else:
day_snapshot.day_other_count += 1
return snapshots
def _q_lookup(self, component):
snapshots = get_publisher().snapshot_class.select_object_history(self.obj,
clause=[Equal('id', component)])
if not snapshots:
raise errors.TraversalError()
return SnapshotDirectory(self.obj, snapshots[0])
class SnapshotDirectory(Directory):
_q_exports = ['', 'export', 'restore', 'view']
def __init__(self, instance, snapshot):
self.obj = instance
self.snapshot = snapshot
def _q_traverse(self, path):
get_response().breadcrumb.append((
'%s/' % self.snapshot.id,
misc.localstrftime(self.snapshot.timestamp))
)
return super()._q_traverse(path)
def _q_index(self):
return redirect('view/')
def export(self):
response = get_response()
response.set_content_type('application/x-wcs-snapshot')
response.set_header('content-disposition',
'attachment; filename=snapshot-%s-%s-%s.wcs' % (
self.snapshot.object_type,
self.snapshot.id,
self.snapshot.timestamp.strftime('%Y%m%d-%H%M'),
))
return '<?xml version="1.0"?>\n' + self.snapshot.serialization
def restore(self):
form = Form(enctype='multipart/form-data')
action = form.add(RadiobuttonsWidget, 'action',
options=(
('as-new', _('Restore as a new item'), 'as-new'),
('overwrite', _('Overwrite current content'), 'overwrite')),
value='as-new')
form.add_submit('submit', _('Submit'))
form.add_submit('cancel', _('Cancel'))
if form.get_submit() == 'cancel':
return redirect('..')
if form.get_submit() == 'submit':
self.snapshot.restore(as_new=bool(action.parse() == 'as-new'))
return redirect(self.snapshot.instance.get_admin_url())
get_response().breadcrumb.append(('restore', _('Restore')))
r = TemplateIO(html=True)
r += htmltext('<h2>%s</h2>') % _('Restore snapshot')
r += form.render()
return r.getvalue()
@property
def view(self):
from wcs.blocks import BlockDef
from wcs.carddef import CardDef
from wcs.data_sources import NamedDataSource
from wcs.formdef import FormDef
from wcs.workflows import Workflow
from wcs.wscalls import NamedWsCall
klass = self.snapshot.get_object_class()
if klass is BlockDef:
from wcs.admin.blocks import BlockDirectory
return BlockDirectory(section='forms', objectdef=self.snapshot.instance)
if klass is FormDef:
from wcs.admin.forms import FormDefPage
return FormDefPage(component='view', instance=self.snapshot.instance)
if klass is CardDef:
from wcs.backoffice.cards import CardDefPage
return CardDefPage(component='view', instance=self.snapshot.instance)
if klass is Workflow:
from wcs.admin.workflows import WorkflowPage
return WorkflowPage(component='view',
instance=self.snapshot.instance)
if klass is NamedDataSource:
from wcs.admin.data_sources import NamedDataSourcePage
return NamedDataSourcePage(component='view',
instance=self.snapshot.instance)
if klass is NamedWsCall:
from wcs.admin.wscalls import NamedWsCallPage
return NamedWsCallPage(component='view',
instance=self.snapshot.instance)