如何使用 plone.api create 和 NamedBlobFile 在 Plone 中处理上传文件

How to handle upload File in Plone using plone.api create and NamedBlobFile

亲爱的,

我已经创建了一个脚本来读取 txt 并在 Plone 站点 (Plone 4.3.10) 中上传。 脚本在这里:

我使用 MrTango 描述的技巧: Save file to plone site using python

我的难点是将文件附加到FOR开头创建的新项目中,具体如下:

    file_obj.file = NamedBlobFile(
        data=open(pdf_path, 'r').read(),
        contentType='application/pdf',
        filename=unicode(file_obj.id, 'utf-8'),
    )

参数"data",从文件系统接收文件PDF,但是,不要在新创建的对象中设置文件。

感谢您的关注!

[更新]

使用 pdb,我看到一些输出、数据、contentType n 文件名显然设置正确。

所以,我哪里错了? 或者数据的输入是什么类型? 我不是专家 python 程序员...就像你看到的... 如果有人使用 plone.api 并将 pdf 上传到 plone,你是怎么做到的?

 36                             pdf_path,
 37                             filename=unicode(file_obj.id, 'utf-8'),
 38                     )
 39                     print('\n \n Criado: '+row['NDOPROCESSO']+'.')
 40                     transaction.commit()
 41
 42                     pdf_file.close()
 43  ->                 break
 44     csvfile.close()
 45
    (Pdb) file_obj.file.data
        'INMEQ/PastaGeral/PROCESSOINMEQ-AL.PDF'
    (Pdb) file_obj.file.contentType
        'application/pdf'
    (Pdb) file_obj.file.filename
        u'processoinmeq-al.pdf'

[更新 2]

@Mathias,首先,你很棒!

我的O.S。是:

jaf@ocs:~/plone4310/zinstance$ uname -a
Linux ocs 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt11-1+deb8u6 (2015-11-09) x86_64 GNU/Linux

看我的尝试:

jaf@ocs:~/plone4310/zinstance$ bin/instance -O a debug
Starting debugger (the name "app" is bound to the top-level Zope object)

>>> plone = app.a
>>> plone
<PloneSite at /a>
>>> from zope.component.hooks import setSite
>>> setSite(plone)
>>> from plone import api
>>> pdfpath = 'INMEQ/PastaGeral/PROCESSOINMEQ-AL.PDF' 
#I tried too with a full path, like you see in image print below
#'/home/jaf/plone4310/zinstance/INMEQ/PastaGeral/PROCESSOINMEQ-AL.PDF'
>>> pdfpath
'INMEQ/PastaGeral/PROCESSOINMEQ-AL.PDF'
>>> obj = api.content.create(type='File', title='a file', container=plone)
>>> obj
<ATFile at /a/a-file> #unique difference, between you and me, is ATFile not File.
>>> obj.id
'a-file'
>>> file_ = plone.get(obj.id)
>>> file_
<ATFile at /a/a-file>
>>> file_ = plone.get('a-file')
>>> file_
<ATFile at /a/a-file>
>>> from plone.namedfile.file import NamedFile
>>> pdf = open(pdfpath, 'r')
>>> pdf
<open file 'INMEQ/PastaGeral/PROCESSOINMEQ-AL.PDF', mode 'r' at 0x7f41b7b48030>
>>> file_.file = NamedFile(data=pdf, filename=unicode(obj.id, 'utf-8'), contentType='application/pdf')
>>> file_.file
<plone.namedfile.file.NamedFile object at 0x7f41b7b42500>
>>> import transaction
>>> transaction.commit()
>>> file_.file
<plone.namedfile.file.NamedFile object at 0x7f41b7b42500>
>>>

文件所在位置:

在 transaction.commit() 之后,我们有了它。

[更新 3 - 并且有效]

在@Mathias 的超级帮助下,脚本 python 用于上传 File 来自 txt 的原型并用分号分隔。

from zope.site.hooks import setSite
from plone import api
import transaction
import csv
import os

local_path = '/path_to_plone_instace/plone4310/zinstance'
scan_path = 'path_with_txt_and_PDFs'
geral_path = 'folder_with_pdf_only'
txt_name = 'file_with_content.txt'
plone_site = 'plone_site'
plone_site_pasta = 'folder_upload_in_plone'

portal = app[plone_site]
setSite(portal)
container = portal[plone_site_pasta]

with open(os.path.join(local_path, scan_path, txt_name), 'rb') as csvfile:
    reader = csv.DictReader(csvfile, delimiter=';', quotechar='|')
    for row in reader:
        pdf_id = str(row['PDF_ID'])
        pdf_file = open(os.path.join(local_path, scan_path, geral_path, str(pdf_id)), 'r')

        file_obj = api.content.create(
            container=container,
            type='File',
            title=str(row['PDF_TITLE']),
            description=str(row['PDF_DESCRIPTION']),
            safe_id=True,
            excludeFromNav=True
        )

        file_ = container.get(file_obj.id)

        file_.setFile(pdf_file)

        if int(file_obj.getFile().size()) <= 0:
            print str(file_obj.id) + ', Empty FILE!!! size: ' + str(file_obj.getFile().size())

        else:
            print str(file_obj.title) + ', success created, with size: ' + str(file_obj.getFile().size())

            transaction.commit()

csvfile.close()

PDF 是一种二进制格式,因此您可能需要阅读有关如何在 Python 中打开文件的信息。 data=open(pdf_path, 'rb') 之类的内容应该有所帮助。

我还建议您了解 pdb 并在此行之前插入一个断点,这样您就可以检查一切是否按预期工作。

以下在 Plone 4.3.10 + plone.app.contenttypes(默认 DX 类型)上工作

>>> plone = app.Plonedemo
>>> plone
<PloneSite at /Plonedemo>
>>> from zope.component.hooks import setSite
>>> setSite(plone)
>>> from plone import api
>>> pdfpath = '/Users/PATHTOPDF'

>>> obj = api.content.create(
...     type='File',
...     title='a file',
...     container=plone)
>>> file_ = plone.get('a-file')
>>> file_
<File at /Plonedemo/a-file>

我使用 NameFile 而不是 NamedBlobFile..据我所知两者都是一样的。

>>> from plone.namedfile.file import NamedFile

看来您需要提供文件处理程序而不是实际内容。

>>> pdf = open(pdfpath, 'r')
>>> pdf
<open file '/Users/PATHTOPDF', mode 'r' at 0x10dca3150>
>>> file_.file = NamedFile(data=pdf, filename=u'bla.pdf', contentType='application/pdf')
>>> import transaction
>>> transaction.commit()
>>> file_.file
<plone.namedfile.file.NamedFile object at 0x10dca0230>

启动实例后,文件包括。 PDF 在那里并且工作正常。


更新:原型示例 File 内容。

这现在必须工作:-)

我假设你有一个原型文件内容 您可以按照相同的步骤,直到将文件添加到内容中。

... 
>>> pdf = open(pdfpath, 'r')
>>> pdf
<open file '/Users/PATHTOPDF', mode 'r' at 0x10dca3150>
>>> file_.setFile(pdf)  # filehandler, NOT THE NAMEDFILE.
>>> obj.getFile().size()
155847
>>> import transaction
>>> transaction.commit()

此示例使用 Archetypes 默认值 setter/getter。