Last active
January 22, 2021 09:07
-
-
Save cdw9/b61200b5a218f2711874e03523c94cbc to your computer and use it in GitHub Desktop.
Plone batch file download - adds a download link to folders, will create a .zip of all files or PDFs in the folder
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
... | |
<browser:page | |
name="download_files" | |
for="plone.app.contenttypes.interfaces.IFolder" | |
permission="cmf.ModifyPortalContent" | |
class=".folders.DownloadFiles" | |
/> | |
... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" | |
xmlns:tal="http://xml.zope.org/namespaces/tal" | |
xmlns:metal="http://xml.zope.org/namespaces/metal" | |
xmlns:i18n="http://xml.zope.org/namespaces/i18n" | |
lang="en" | |
metal:use-macro="context/main_template/macros/master" | |
i18n:domain="plone"> | |
<body> | |
<metal:block fill-slot="top_slot" | |
tal:define="disable_column_one python:request.set('disable_plone.leftcolumn',1); | |
disable_column_two python:request.set('disable_plone.rightcolumn',1);" /> | |
<metal:content-core fill-slot="content-core"> | |
<p>Submit the form below to download a .zip of files contained in this folder.</p> | |
<p>This process may take a while. | |
If the request times out, the zip file will still be created in this folder. | |
Check for the new file in | |
<a href="${context/absolute_url}/folder_contents">folder contents</a>.</p> | |
<form action=""> | |
<label for="file_type">File Types</label> | |
<select name="file_type" id="file_type"> | |
<option value="pdf">PDFs only</option> | |
<option value="all">All files</option> | |
</select> | |
<input type="submit" name="submit" value="Submit" /> | |
</form> | |
</metal:content-core> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0"?> | |
<object | |
i18n:domain="plone" | |
meta_type="Dexterity FTI" | |
name="Folder" | |
xmlns:i18n="http://xml.zope.org/namespaces/i18n"> | |
<action | |
action_id="download_files" | |
category="object" | |
condition_expr="" | |
i18n:attributes="title" | |
title="Download Files" | |
url_expr="string:${object_url}/download_files" | |
visible="True"> | |
<permission value="Modify portal content"/> | |
</action> | |
</object> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import transaction | |
from datetime import datetime | |
from plone import api | |
from plone.namedfile import NamedBlobFile | |
from Products.Five.browser import BrowserView | |
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile | |
from Products.statusmessages.interfaces import IStatusMessage | |
class DownloadFiles(BrowserView): | |
template = ViewPageTemplateFile('templates/download_files.pt') | |
def __init__(self, context, request): | |
self.context = context | |
self.request = request | |
def __call__(self): | |
form = self.request.form | |
if not form or 'file_type' not in form: | |
return self.template() | |
from_path = '/'.join(self.context.getPhysicalPath()) | |
files = api.content.find( | |
path=from_path, | |
portal_type='File', | |
) | |
if not files: | |
IStatusMessage(self.request).addStatusMessage(u"No files found!", "info") | |
return self.template() | |
today = datetime.today().strftime("%Y-%m-%d") | |
exp_path = 'export-{0}-{1}'.format(self.context.id, today) | |
if os.path.exists(exp_path): | |
os.system('rm -rf {}'.format(exp_path)) | |
os.mkdir(exp_path) | |
for file in files: | |
obj = file.getObject() | |
if form.get('file_type') == 'pdf' and 'pdf' not in obj.file.contentType: | |
continue | |
filename = obj.file.filename | |
f = open(os.path.join(exp_path, filename), 'wb') | |
f.write(obj.file.data) | |
f.close() | |
print("Saved {}".format(filename)) | |
os.system('zip -r {0}.zip {0}'.format(exp_path)) | |
os.system('rm -rf {}'.format(exp_path)) | |
zip_file = api.content.create( | |
type='File', | |
title=exp_path, | |
container=self.context, | |
) | |
zip_file.file = NamedBlobFile( | |
data=open('{}.zip'.format(exp_path), 'r'), | |
filename=u'{}.zip'.format(exp_path), | |
contentType='application/zip' | |
) | |
zip_file.reindexObject() | |
transaction.commit() | |
self.request.response.redirect(zip_file.absolute_url() + '/view') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment