跳转到主要内容

Zope外部编辑器

项目描述

https://github.com/zopefoundation/Products.ExternalEditor/actions/workflows/tests.yml/badge.svg https://coveralls.io/repos/github/zopefoundation/Products.ExternalEditor/badge.svg Current version on PyPI Supported Python versions

Zope外部编辑器

Zope外部编辑器是一种将Zope与客户端工具更无缝集成的全新方式。它具有以下特性:

  • 在本地直接从ZMI编辑对象。

  • 与任何可以通过命令行打开文件的图形编辑器应用程序兼容,包括:emacs、gvim、xemacs、nedit、gimp等。

  • 自动将更改保存回Zope,而无需结束编辑会话。

  • 可以通过元类型或内容类型将任何客户端编辑器应用程序与任何Zope对象关联。可以编辑文本和二进制对象内容。

  • 在编辑对象时锁定对象。在编辑会话结束时自动解锁。

  • 可以自动添加文件扩展名以改进语法高亮或文件类型检测。

  • 与基本认证、cookie认证和Zope版本兼容。凭据将自动传递到辅助应用程序。无需重新认证。

  • https支持(需要OpenSSL)

Zope版本兼容性

对于Zope 4,请使用2.0版本及更高版本。对于4.0之前的Zope版本,请使用1.1分支的ExternalEditor版本。

使用方法

一旦您的浏览器配置完毕(请参阅安装说明),应用程序的使用方法与使用ZMI大致相同。要在外部编辑对象,只需单击ZMI中对象旁边的铅笔图标。对象将被下载并使用您选择的编辑器应用程序打开(您将在第一次被提示选择一个编辑器)。

您将对象编辑得就像任何其他文件一样。当您在编辑器中保存更改时,它们将自动在后台上传回Zope。当对象在您的编辑器中打开时,它将在Zope中锁定以防止并发编辑。当您结束编辑会话(即关闭编辑器)时,对象将解锁。

工作原理

好吧,这一切听起来都太好了,不是吗?那么它到底是如何工作的呢?首先,我会给你一个块图

+------------+     +------------+     +---------+        +------+
| Editor App | <-- | Helper App | <-- | Browser | <-/ /- | Zope |
+------------+     +------------+     +---------+        +------+
            ^       ^     ^                                ^
             \     /       \                              /
              v   v         -----------------------/ /----
             -------
            / Local \
            \  File /
             -------

现在,使这一切得以工作的是解决编辑器不知道Zope、必须仅处理本地文件的问题。此外,没有与编辑器通信的标准方式,因此唯一的通信渠道只能是包含对象内容或代码的本地文件。

要启动您的编辑器,当您使用浏览器下载特定类型的数据时,这是微不足道的。但这对你来说帮助不大,因为一旦数据下载,浏览器就不再参与其中。它只是创建一个临时文件,并启动已注册的应用程序,传递文件路径。一旦编辑器运行,它就只意识到本地文件,没有任何关于它从何而来的概念。

为了解决这个问题,我开发了一个辅助应用程序,其基本任务是双重的:

  • 确定为给定的Zope对象启动正确的编辑器

  • 当更改保存时,将数据带回到Zope

那么,让我们一步一步地看看它是如何工作的:

  1. 您点击Zope管理界面中的外部编辑器链接(铅笔图标)。

  2. 服务器上的产品代码创建了一个响应,该响应封装了必要的元数据(URL、元类型、内容类型、cookie等)和Zope对象的内容(可以是文本或二进制数据)。该响应具有虚构的内容类型“application/x-zope-edit”。

  3. 浏览器接收请求,并找到为“application/x-zope-edit”注册的辅助应用程序。它将响应数据本地保存到磁盘,并启动辅助应用程序进行处理。

  4. 辅助应用程序读取其配置文件和响应数据文件。从文件中解析元数据,并将内容复制到新的临时文件中。根据数据文件和配置确定合适的编辑程序。

  5. 编辑程序作为辅助应用程序的子进程启动,并将包含内容数据的文件传递给它。

  6. 如果配置了此功能,辅助应用程序会向Zope发送WebDAV锁定请求以锁定对象。

  7. 有时(如果配置了此功能),辅助应用程序将检查内容文件是否已更改。如果已更改,它将向Zope发送包含新数据的HTTP PUT请求。

  8. 当编辑程序关闭时,将再次检查内容文件,如果它已更改,则将其上传。然后向Zope发送WebDAV解锁请求。

  9. 辅助应用程序退出。

配置

辅助应用程序支持多种配置选项,每个选项都可以在任何对象元类型、内容类型或域的组合中触发。这允许您为不同类型的Zope对象和内容或甚至不同的服务器创建适当的行为。配置文件存储在文件“~/.zope-external-edit”(Unix)或“~ZopeEdit.ini”(Windows)中。如果辅助应用程序启动时未找到配置文件,则会在您的家目录中创建一个默认配置文件。

配置文件遵循标准的Python ConfigParser格式,这与Windows中的旧.ini文件格式非常相似。文件由以下格式的部分和选项组成

[section 1]
option1 = value
option2 = value

[section 2]
...

选项

配置文件所有部分可用的选项如下

editor

用于调用编辑应用程序的命令行或插件名称。在Windows上,如果找不到要编辑的对象的编辑设置,辅助应用程序将根据对象的MIME类型或文件扩展名在文件类型注册表中搜索合适的编辑器(可以使用下述扩展选项指定)。默认情况下,将本地正在编辑的文件的路径追加到此命令行。要在命令行中间插入文件路径,请分别使用“$1”(Unix)和“%1”(Windows)。

save_interval

(浮点数) 辅助应用程序检查已编辑文件更改的间隔(秒)。

use_locks

(1或0) 是否使用WebDAV锁定。用户编辑必须具有适当的WebDAV相关权限才能正常工作。

always_borrow_locks

(1或0) 当启用use_locks时,此功能会抑制尝试编辑已锁定对象时的警告。当启用时,外部编辑器将始终“借用”现有的锁定令牌而不是自己执行锁定。当使用CMFStaging等工具时非常有用。如果省略,则此选项默认为0。

cleanup_files

(1或0) 是否删除创建的临时文件。警告:来自浏览器的临时文件包含认证信息,因此将此设置为0是一种安全风险,尤其是在共享机器上。如果设置为1,则该文件将在编辑器启动之前尽快删除。仅将此设置为0以进行调试。

extension

(文本) 添加到内容文件的文件扩展名。允许更好地处理图像并可以改进语法高亮。

temp_dir

(路径) 存储正在编辑的对象本地副本的路径。默认为操作系统临时目录。注意:此设置在Windows 8上没有明显的影响

long_file_name

(1或0) 是否在文件名中包含对象的全路径,包括主机名(默认)或仅包含正在编辑的对象的id。关闭此选项以在编辑器中获得较短的文件名,以及不喜欢长名称的编辑器。

file_name_separator

(字符串) 用于分隔外部编辑器中长文件名路径元素的字符或字符组。默认为逗号(,)。这必须是平台文件名中合法的字符(即,不要使用路径分隔符字符!)。如果将“long_file_name”设置为0,则忽略此选项。

部分

配置文件的部分指定了选项下应用的对象和内容类型。

只有一个强制部分“[general]”,应定义所有上述没有默认值的选项。如果没有其他部分为给定对象定义选项,则使用一般设置。

附加部分可以应用于特定域、内容类型或元类型。由于对象可以具有所有这些属性,选项将按此优先级顺序应用

  1. 整个内容类型选项(例如,[content-type:text/html])。

  2. 主要内容类型选项(例如,[content-type:text/*])。

  3. Zope元类型选项(例如,[meta-type:File])。

  4. 域选项(例如,[domain:www.mydomain.com])。如果需要,可以为每个域级别添加多个部分。

  5. 一般选项(即,[general])。

此方案允许您通过内容类型指定扩展名,通过元类型指定编辑器,通过域指定锁定设置,并为给定对象在一般选项下指定其他选项。

编辑器插件

为了更紧密的客户端集成,外部编辑器具有插件系统,允许它与支持的应用程序直接交互。

在Windows上,这通常意味着使用COM调用应用程序,打开内容文件,并等待用户保存和关闭文件。由于每个应用程序都有不同的远程脚本能力和API,因此必须为每个支持的应用程序和平台编写针对特定编辑器的插件。

此系统允许外部编辑器高效地连接到正在运行的应用程序,而无需重新启动它们,因此完全支持MDI环境。以下应用程序目前具有插件支持

Application       Platform    Plugin Module Name(s)
===================================================
HomeSite          Windows     homesite5, homesite
Dreamweaver       Windows     dreamweaver
Photoshop         Windows     photoshp, photoshop
MS Word           Windows     winword, word
MS Excel          Windows     excel
MS Powerpoint     Windows     powerpnt, powerpoint

外部编辑器在使用通用编辑器控制方法之前,将尝试为任何应用程序加载一个插件。它通过匹配编辑器命令行中的应用程序可执行文件名(无扩展名)与可用的插件来完成。

由于插件不需要编辑器应用程序的路径即可工作,如果需要,您可以在配置文件中指定编辑器的插件模块名称。例如,为了指定所有图像文件使用Photoshop,请在您的配置文件中添加以下部分(Windows上的ZopeEdit.ini)

[content-type:image/*]
editor=photoshop

这只是一个快捷方式,如果指定了完整的应用程序路径,仍将尽可能使用插件。

插件说明

Photoshop

Photoshop的COM API相当有限,外部编辑器无法检测到您已关闭文件,直到您退出整个应用程序(它仍然可以检测到保存)。因此,当使用它时,您可能想要关闭DAV锁定(use_locks=0)或借用锁定(always_borrow_locks=1)。

Dreamweaver

外部编辑器无法检测到您何时完成单个文件的编辑。使用Dreamweaver编辑的对象将在服务器上保持锁定状态,直到您退出应用程序。与上面的Photoshop一样,您可能想要关闭Dreamweaver的锁定。

如果您的 favorite 编辑器需要插件,因为一般支持不够好,请告诉我。请记住,我必须能够运行应用程序的副本才能为其开发插件。所以,除非应用程序是免费的,或者有完整的演示可供下载,否则我可能无法提供太多帮助。插件编写并不困难,我鼓励您为您的 favorite 编辑器编写一个插件,从阅读现有的一个开始。我很乐意将第三方插件包含在发行版中。

权限

外部编辑由“使用外部编辑器”权限控制。拥有此权限的用户可以从可编辑对象中启动外部编辑器。为了保存更改,用户将需要针对他们正在编辑的对象的额外权限。

如果用户希望使用内置的锁定支持,他们必须拥有“WebDAV访问”、“WebDAV锁定项”和“WebDAV解锁项”权限。

如果这些权限未在Zope中设置,则辅助应用程序将从Zope接收未经授权的错误,并将这些错误展示给用户。

与外部编辑器集成

zope中的外部编辑器产品安装了一个全局可用的对象,该对象可以格式化通过FTP/DAV可访问的对象,以便辅助应用程序使用。您可以在自己的内容管理应用程序中轻松利用此功能。

假设您有一个名为“my_stuff”的Zope文件夹中的可编辑FTP对象“document”。查看对象的URL将是

http://zopeserver/my_stuff/document

启动此文档外部编辑器的URL将是

http://zopeserver/my_stuff/externalEdit_/document

现在,如果您习惯于将视图附加到URL的末尾,这可能看起来有点奇怪。因为 externalEdit_ 需要与Python脚本和页面模板一起工作,这些脚本和模板会吞掉跟随自己的URL的剩余路径段,因此您必须在要编辑的对象之前直接调用 externalEdit_。您可以在ZPT中使用页面模板中的某些TAL来完成此操作

<a href='edit'
   attributes='href
   string:${here/aq_parent/absolute_url}/externalEdit_/${here/getId}'>
   Edit Locally
</a>

作为替代方案,您还可以在调用其index_html方法时直接将您想要编辑的对象的路径传递给 externalEdit_ 对象。它可以通过URL直接调用或从Python脚本中调用。 externalEdit_ 将返回适当的响应数据以供编辑的对象使用。您可以通过URL调用它

http://zopeserver/externalEdit_?path=/my_stuff/document

或通过Python

return context.externalEdit_.index_html(
    context.REQUEST, context.RESPONSE, path='/my_stuff/document')

当与已使用DAV锁定的CMS集成外部编辑器时,它默认会在显示确认对话框后允许用户借用服务器上制作的锁。尽管您可以通过在外部编辑器配置文件中指定“always_borrow_locks = 1”使其自动进行,但可能希望在服务器上使用时将其作为默认行为。为此,您可以在URL中指定自动借用锁(新功能),即

http://zopeserver/my_stuff/externalEdit_/document?borrow_lock=1

外部编辑器还定义了一个全局方法,您可以通过调用它来为合适的对象插入铅笔图标链接。该方法会自动检查对象是否支持外部编辑以及用户是否有“使用外部编辑器”权限。如果两者都为真,则返回插入外部编辑器图标链接的HTML代码。否则,返回空字符串。

该方法是‘externalEditLink_(object)’。如果适当,对象参数是要为其创建链接的对象。以下是一些示例页面模板代码,用于在当前文件夹中插入对象的链接以及在适当位置插入外部编辑器图标

<div tal:repeat="object here/objectValues">
  <a href="#"
     tal:attributes="href object/absolute_url"
     tal:content="object/title_or_id">Object Title</a>
  <span tal:replace="structure python:here.externalEditLink_(object)" />
</div>

结论

希望您喜欢使用这款软件。如果您有任何评论、建议或希望报告一个错误,请向作者发送电子邮件

Casey Duncan

变更日志

4.0.1 (2024-09-16)

  • 编辑内容时纠正了Pdata的使用(#23

4.0 (2023-07-04)

  • 确保对象的可编辑正文被转换为字节(#20

  • 添加对Python 3.11的支持。

  • 停止对Python 2.7、3.5、3.6的支持。

3.1.0 (2022-06-24)

  • 添加对Python 3.9、3.10的支持。

  • 更改包结构,将包代码移动到 src 子文件夹。

  • 修复了阻止ZMI渲染的bug(#18

3.0.1 (2020-10-30)

错误修复

  • 添加对最近的Python 3版本的支持[ale-rt]

3.0 (2019-02-16)

  • 修复Zope 4的zmi-patches。[pbauer]

  • 停止对Python 2.6的支持。

  • 将测试适应Zope 4。

  • setup.py 中添加所需依赖。

  • 为Python 2/3兼容性做准备 [davilima6]

2.0.3 (2017-07-17)

  • 文档Zope版本兼容性 [dataflake]

2.0.2 (2017-02-14)

  • 修复了findResult中的反射型XSS。这适用于PloneHotfix20170117。 [maurits]

2.0.1 (2016-09-08)

  • 在manage_tabs中引用变量以避免XSS。来自Products.PloneHotfix20160830。 [maurits]

2.0.0 (2015-09-09)

1.1.0 (2010-12-01)

  • 添加了对未知mimetype浏览器的支持 - 现在我们无论用户代理是什么都添加.zem扩展。

  • 修改了缓存的参数 - MSIE的特殊情况。

  • 纠正并添加了测试

  • 将客户端源代码移动到另一个包:collective.zopeedit。

1.0 (2010-07-01)

  • 更新manage_main、manage_tabs和findResult猴子补丁,以包括来自Zope 2.12的修复。

1.0a2 (2009-11-13)

  • 从Globals中删除了导入。

  • 清除旧Zope 2 Interface接口以实现Zope 2.12兼容性。

1.0a1 (2008-03-05)

  • 更新包元数据,使其可作为包使用。

01/03/2007 - 0.9.3

  • 修复了“manage_FTPget”覆盖“Content-Type”头的问题。

  • 仅在win32系统上运行ExpandEnvironmentStrings。

9/14/2006 - 0.9.2

  • 添加了“skip_data”选项,以便外部编辑器只发送元数据部分并跳过将数据追加到“body”。

  • 添加一个简单的回调注册表,可用于在通过外部编辑器编辑文件时添加额外的元数据头或设置特殊的响应头。

  • 使用rfc822.Message解析正在编辑的文件的元数据。

  • 不要在Zope >= 2.10中发出关于已弃用“methods”的警告。

  • 修复了manage_main.dtml中的acquisition问题,与Zope中应用的相同修复同步。

6/23/2005 - 0.9.1

  • 0.9版本中包含了旧插件pyc文件。这个版本包含最新的插件。

6/20/2005 - 0.9

  • 当使用Excel插件时,用户看到像“TypeError:此对象不支持枚举”这样的错误。我们现在让用户处理这些问题。

  • 当使用Excel插件时,用户偶尔会收到以“致命错误:<unknown>。Path”形式出现的错误,随后用户无法将文档保存回Zope,因为外部编辑器进程已退出。

  • 使用涉及COM(Word、Excel、Powerpoint等)的任何插件编辑文档时,文档的更改可能不会保存回Zope。

  • 如果用户在主动保存之前退出Word,如果在编辑的文档中存在未保存的更改,则无论用户是否在Word提供的“您是否想在退出前保存”对话框中回答“是”,这些更改都不会保存到服务器。

  • 现在,外部编辑的对象的“title”属性现在可以通过EE返回给zopeedit客户端的标题集合中。

  • 现在可以使用JavaScript或VBScript从IE中检测客户端是否安装了外部编辑器,假设客户端软件是通过InnoSetup安装程序安装的。有关更多信息,请参阅“win32/ocx.txt”。

  • 外部编辑器现在与Zope 2.7.1+返回“filestream iterator”的对象兼容。(如果升级:此修复不需要更新EE客户端,只需更新EE Zope产品)。

  • 正确转义man页面中的连字符。感谢Federico Sevilla III。

  • 在锁定Zope中的文件之前检查编辑器是否已启动。这可以防止在锁请求完成之前关闭编辑器时发生错误。

  • 在Posix平台上不询问用户要使用哪个编辑器。相反,只需告诉用户编辑配置文件。askstring()函数在Python 2.3.4中的隐藏根Tk窗口中不起作用。感谢Christopher Mann。

7/13/04 - 0.8

  • 将外部编辑器图标添加到ZMI面包屑中以编辑对象。

  • 使用Python 2.3.4、Pythonwin构建163和py2exe 0.5编译了Windows辅助应用二进制文件。

  • 添加由Manuel Aristarann提供的Dreamweaver插件。也感谢Anton Stonor。

  • 为Zope 2.7的有序文件夹对象添加ZMI支持。

  • 修复了从旧版本的CookieCrumber检测基本认证信息的bug。感谢David D. Smith和Federico Sevilla III。

  • 绕过在SSL上运行时的IE浏览器错误。感谢Marc-Aurele Darche。

  • 为MacOS X(尤其是Mac IE)添加了对“.zem”文件扩展名的支持,以简化辅助应用程序的集成,特别是在缺少MIME支持的情况下。感谢Zac Bir的贡献。

  • 添加了“long_file_name”和“file_name_separator”配置选项。

  • 修复了在Win32系统下使用Excel插件编辑Excel文件时出现的“调用被调用方拒绝”的COM错误。感谢Chris McDonough。

4/23/04 - 0.7.2

  • 将默认配置更改为仅使用.txt扩展名来表示text/plain。为css和javascript文件添加扩展名。

  • 修复了Windows二进制文件中的包装错误,该错误禁用了一些插件。这修复了MSOffice等“编辑器无法正确启动”的错误。

  • 修复了在非常短的编辑会话中没有任何更改时,EE可能认为编辑器从未启动的bug。感谢Maik Ihde。

11/7/03 - 0.7.1

  • 修复了Windows二进制文件中的编码bug。感谢Chris McDonough。

  • 添加了关于配置IE通过SSL保存文件的提示。感谢Jonah Bossewitch。

4/1/03 - 0.7

  • 为Unix添加了工作的distutils设置。

  • 现在可以通过请求传递borrow_lock=1来指定服务器,使辅助应用程序借用锁,从而抑制默认出现的对话框。感谢Shane Hathaway。

  • 在Word和Powerpoint插件中改进了打开文件检查,感谢Yura Petrov。

  • 添加了Microsoft Word、Excel和Powerpoint的插件。

  • 从Debian发行版添加了man页面。感谢Federico Sevilla III和Andreas Tille。

11/02/02 - 0.6

  • 使用Python 2.2.2和PythonWin 148构建了Windows辅助应用程序。

  • 现在,externalEdit_对象接受一个路径参数,用于编辑对象,允许如下的URL:http://zope/externalEdit_?path=/some/object。这允许外部编辑器与应用程序更好地协同工作,这些应用程序利用了自己的遍历魔法。感谢Tres Seaver。

  • 修复了解锁重试代码中的NameError bug。感谢Federico Sevilla III。

  • 添加了对不合规SSL服务器的解决方案。现在软件会静默忽略来自httplib的“EOF违反协议”错误。感谢Christopher Deckard。

  • 删除了stderr写入以解决Windows上的“无效文件描述符”错误。感谢Martijn Peters。

  • 添加了Photoshop插件(win32)

  • 添加了HomeSite插件(win32)

  • 为辅助应用程序添加了win32编辑器插件支持。

8/19/02 - 0.5

  • 为Zope find模板添加了补丁,以便您可以直接从ZMI中的查找结果使用外部编辑器。感谢Jim Washington。

  • 提取了外部编辑器链接生成器。现在产品注册了一个全局方法externalEditLink_,可以调用以生成任何对象的外部编辑器图标链接。

  • 外部编辑现在受“使用外部编辑器”权限控制,允许非管理员使用它。用户还必须拥有编辑/修改他们编辑的对象的权限,如果需要,还要进行WebDAV锁定。感谢Reineke和他人。

  • Unix编辑器命令行解析现在更健壮,并正确处理带引号的参数。您还可以在编辑器命令中指定“$1”占位符,以表示内容文件名插入的位置。如果省略,则将其附加到命令行末尾。“%1”在Windows中继续以类似方式工作。感谢Marc St-Jean。

  • 修复了编辑大型(分块)文件和图像的bug。外部编辑器现在正确地将数据流式传输到客户端。感谢所有报告了此bug不同症状的用户。

  • 修复了在Squishdot站点内部编辑对象的bug。感谢Kevin Salt。

  • 添加了借用现有DAV锁的功能。这允许外部编辑器与其他使用锁的系统(如CMFStaging)协同工作。可以通过设置always_borrow_locks配置标志来在编辑时抑制借用锁警告对话框。

  • 修复了当产品与mysqlUserFolder一起使用时的认证bug。感谢ViNiL。

6/30/02 - 0.4.2

  • 为Windows二进制软件包添加了SSL支持。感谢Federico Sevilla III。

6/29/02 - 0.4.1

  • 修复了致命错误时的悬挂DAV锁bug。感谢Marc St-Jean。

  • 修复了content_type的错误,现在会检查它是否可调用。感谢Arnaud Bienvenu。

  • 修复了Windows上编辑二进制数据的错误。感谢Eric Kamm。

  • 修复了在Posix平台上设置编辑器的错误。

6/24/02 - 0.4

  • 添加了–version命令行参数

  • 将manage_FTPget设置为可编辑内容的默认源,而不是因CMF Wiki Pages而出错的document_src。

  • 修复了Windows中的“body_file”错误。

  • 为Windows添加了使用py2exe和Inno setup的二进制构建支持。

  • 修复了Windows配置文件定位器。现在它会在程序目录中查找,然后是用户的主目录(如果指定)

  • 修复了Windows注册表编辑器查找中的错误。

6/16/02 - 0.3

  • 改进了在锁定尝试失败后保存的行为。

  • 现在可以在Windows上使用Pythonwin运行(掌声)。对过程控制进行了大量重构。感谢Oliver Deckmyn,Gabriel Genellina和Arno Gross进行测试、补丁和建议。

  • 添加了“temp_dir”配置选项,用于指定与操作系统默认值不同的临时文件目录。还进一步改进了临时文件名生成。

  • 添加了对特定领域配置选项的支持。

  • 修复了来自CookieCrumbler的编码认证数据中的尾随换行符错误。感谢Harald Koschinski。

  • 您现在可以在配置文件中将命令行参数传递给编辑器,或者在不使用shell脚本的情况下将编辑器包装在xterm中。

  • 重新编写了“编辑器未启动”错误消息,使其更有意义。

  • 修复了https检测错误。外部编辑器现在经过测试并与https一起工作。非常感谢Hans-Dieter Stich和Martin Groenemeyer的帮助和想法。

  • 使可以编辑ZClasses的方法对象成为可能。感谢Jim Washington

  • 重构了manage_main中的链接生成代码,使其使用父级的absolute_url而不是URL1。感谢Jim Washington

  • 从Configuration类析构函数中移除了隐式保存。

  • 添加了缓存头,以防止客户端缓存编辑数据。感谢Gabriel Genellina指出这一点。

  • 增加了对编辑CMF文档的改进支持

  • 消除了短会话或其他错误发生时的虚假“编辑器未启动”错误。

5/16/02 - 0.2

  • 修复了产品卸载错误

5/15/02 - 0.1

  • 初始发布

项目详细信息


下载文件

下载适合您平台的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。

源分布

products_externaleditor-4.0.1.tar.gz (47.7 kB 查看哈希)

上传时间

构建分布

Products.ExternalEditor-4.0.1-py3-none-any.whl (34.8 kB 查看哈希)

上传时间 Python 3

由以下支持