206 |
206 |
|
207 |
207 |
class FormDefPage(Directory):
|
208 |
208 |
_q_exports = ['', 'fields', 'delete', 'duplicate', 'export',
|
209 |
|
'archive', 'invite', 'enable', 'workflow', 'category',
|
|
209 |
'invite', 'enable', 'workflow', 'category',
|
210 |
210 |
'role', ('workflow-options', 'workflow_options'),
|
211 |
211 |
('workflow-status-remapping', 'workflow_status_remapping'),
|
212 |
212 |
'roles', 'title', 'options', ('acl-read', 'acl_read')]
|
... | ... | |
386 |
386 |
r += htmltext('<li><a href="duplicate">%s</a></li>') % _('Duplicate')
|
387 |
387 |
if ET:
|
388 |
388 |
r += htmltext('<li><a href="export">%s</a></li>') % _('Export')
|
389 |
|
if not (get_publisher().has_site_option('postgresql') and get_cfg('postgresql', {})):
|
390 |
|
r += htmltext('<li><a href="archive">%s</a></li>') % _('Archive')
|
391 |
389 |
if self.formdef.roles:
|
392 |
390 |
r += htmltext('<li><a href="invite">%s</a></li>') % _('Invites')
|
393 |
391 |
r += htmltext('</ul>')
|
... | ... | |
723 |
721 |
'attachment; filename=%s.wcs' % self.formdef.url_name)
|
724 |
722 |
return '<?xml version="1.0" encoding="iso-8859-15"?>\n' + ET.tostring(x)
|
725 |
723 |
|
726 |
|
def archive(self):
|
727 |
|
if get_publisher().has_site_option('postgresql') and get_cfg('postgresql', {}):
|
728 |
|
raise TraversalError()
|
729 |
|
|
730 |
|
if get_request().form.get('job'):
|
731 |
|
return self.archive_processing()
|
732 |
|
if get_request().form.get('download'):
|
733 |
|
return self.archive_download()
|
734 |
|
|
735 |
|
form = Form(enctype='multipart/form-data')
|
736 |
|
|
737 |
|
form.add(DateWidget, 'date', title = _('Archive forms handled before'))
|
738 |
|
form.add(CheckboxWidget, 'not-done', title = _('Include forms that have not been handled'),
|
739 |
|
value = False)
|
740 |
|
form.add(CheckboxWidget, 'keep', title = _('Do not remove forms'),
|
741 |
|
value = False)
|
742 |
|
form.add_submit('submit', _('Submit'))
|
743 |
|
form.add_submit('cancel', _('Cancel'))
|
744 |
|
|
745 |
|
if form.get_widget('cancel').parse():
|
746 |
|
return redirect('.')
|
747 |
|
|
748 |
|
if not form.is_submitted() or form.has_errors():
|
749 |
|
get_response().breadcrumb.append(('archive', _('Archive')))
|
750 |
|
self.html_top(title = _('Archive Forms'))
|
751 |
|
r = TemplateIO(html=True)
|
752 |
|
r += htmltext('<h2>%s</h2>') % _('Archive Forms')
|
753 |
|
r += form.render()
|
754 |
|
return r.getvalue()
|
755 |
|
else:
|
756 |
|
return self.archive_submit(form)
|
757 |
|
|
758 |
|
def archive_submit(self, form):
|
759 |
|
|
760 |
|
class Archiver:
|
761 |
|
def __init__(self, formdef):
|
762 |
|
self.formdef = formdef
|
763 |
|
|
764 |
|
def archive(self, job=None):
|
765 |
|
all_forms = self.formdef.data_class().select()
|
766 |
|
|
767 |
|
if form.get_widget('not-done').parse() is False:
|
768 |
|
not_endpoint_status = self.formdef.workflow.get_not_endpoint_status()
|
769 |
|
not_endpoint_status_ids = ['wf-%s' % x.id for x in not_endpoint_status]
|
770 |
|
all_forms = [x for x in all_forms if x.status not in not_endpoint_status_ids]
|
771 |
|
|
772 |
|
if form.get_widget('date').parse():
|
773 |
|
date = form.get_widget('date').parse()
|
774 |
|
date = time.strptime(date, misc.date_format())
|
775 |
|
all_forms = [x for x in all_forms if (
|
776 |
|
x.evolution and x.evolution[-1].time < date) or (
|
777 |
|
x.receipt_time < date)]
|
778 |
|
|
779 |
|
self.fd = StringIO()
|
780 |
|
t = tarfile.open('wcs.tar.gz', 'w:gz', fileobj=self.fd)
|
781 |
|
t.add(self.formdef.get_object_filename(), 'formdef')
|
782 |
|
for formdata in all_forms:
|
783 |
|
t.add(formdata.get_object_filename(), '%s/%s' % (self.formdef.url_name, str(formdata.id)))
|
784 |
|
t.close()
|
785 |
|
|
786 |
|
if form.get_widget('keep').parse() is False:
|
787 |
|
for f in all_forms:
|
788 |
|
f.remove_self()
|
789 |
|
|
790 |
|
if job:
|
791 |
|
job.file_content = self.fd.getvalue()
|
792 |
|
job.store()
|
793 |
|
|
794 |
|
count = self.formdef.data_class().count()
|
795 |
|
archiver = Archiver(self.formdef)
|
796 |
|
if count > 100: # Arbitrary threshold
|
797 |
|
job = get_response().add_after_job(
|
798 |
|
str(N_('Archiving forms')),
|
799 |
|
archiver.archive)
|
800 |
|
return redirect('archive?job=%s' % job.id)
|
801 |
|
else:
|
802 |
|
archiver.archive()
|
803 |
|
|
804 |
|
response = get_response()
|
805 |
|
response.set_content_type('application/x-wcs-archive')
|
806 |
|
response.set_header('content-disposition',
|
807 |
|
'attachment; filename=%s-archive.wcs' % self.formdef.url_name)
|
808 |
|
return archiver.fd.getvalue()
|
809 |
|
|
810 |
|
def archive_processing(self):
|
811 |
|
try:
|
812 |
|
job = AfterJob.get(get_request().form.get('job'))
|
813 |
|
except KeyError:
|
814 |
|
return redirect('.')
|
815 |
|
|
816 |
|
self.html_top(title=_('Archiving'))
|
817 |
|
r = TemplateIO(html=True)
|
818 |
|
r += get_session().display_message()
|
819 |
|
get_response().add_javascript(['jquery.js', 'afterjob.js'])
|
820 |
|
r += htmltext('<dl class="job-status">')
|
821 |
|
r += htmltext('<dt>')
|
822 |
|
r += _(job.label)
|
823 |
|
r += htmltext('</dt>')
|
824 |
|
r += htmltext('<dd>')
|
825 |
|
r += htmltext('<span class="afterjob" id="%s">') % job.id
|
826 |
|
r += _(job.status)
|
827 |
|
r += htmltext('</span>')
|
828 |
|
r += htmltext('</dd>')
|
829 |
|
r += htmltext('</dl>')
|
830 |
|
|
831 |
|
r += htmltext('<div class="done">')
|
832 |
|
r += htmltext('<a href="archive?download=%s">%s</a>') % (job.id, _('Download Archive'))
|
833 |
|
r += htmltext('</div>')
|
834 |
|
return r.getvalue()
|
835 |
|
|
836 |
|
def archive_download(self):
|
837 |
|
try:
|
838 |
|
job = AfterJob.get(get_request().form.get('download'))
|
839 |
|
except KeyError:
|
840 |
|
return redirect('.')
|
841 |
|
|
842 |
|
if not job.status == 'completed':
|
843 |
|
raise TraversalError()
|
844 |
|
response = get_response()
|
845 |
|
response.set_content_type('application/x-wcs-archive')
|
846 |
|
response.set_header('content-disposition',
|
847 |
|
'attachment; filename=%s-archive.wcs' % self.formdef.url_name)
|
848 |
|
return job.file_content
|
849 |
|
|
850 |
724 |
def invite(self):
|
851 |
725 |
if not self.formdef.roles:
|
852 |
726 |
return template.error_page(
|