Skip to main content
 首页 » 编程设计

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

2025年05月04日13飞鱼

亲爱的,

我一直在创建一个脚本来读取 txt 并在 Plone 站点 (Plone 4.3.10) 中上传。 脚本在这里: Script Python using plone.api to create File appear error WrongType when set a file

我使用 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,首先,你太棒了!

我的操作系统是:

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 的 super 帮助下,脚本 python 用于从 txt 上传 File 原型(prototype)并用分号分隔。

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() 

请您参考如下方法:

以下内容适用于 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.. AFAIK 两者都是一样的。

>>> 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 在那里并且工作正常。


更新:原型(prototype)文件内容示例。

这现在必须工作:-)

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

...  
>>> 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。