跳转到主要内容

从Plone向感兴趣成员(观察者)发送电子邮件

项目描述

Travis CI badge Coveralls badge

介绍

collective.watcherlist 是一个包,允许您保存一个列表,当项目更新时,想接收电子邮件的人都可以在这个列表中。主要用例类似于 Products.Poi,这是一个 Plone 的问题跟踪器。该产品让您创建问题跟踪器。在这个跟踪器中,人们可以添加问题。跟踪器有管理员。每次发布新问题,管理员都应该收到电子邮件。当管理员对问题进行回复时,原始发布者(以及其他管理员)应该收到电子邮件。任何对跟踪问题感兴趣的人,都应该能够将自己添加到接收电子邮件的人的列表中。此功能曾包含在 Poi 中,但现在已将其提取到这个 collective.watcherlist 包中。

谁应该使用这个包?

这不是一个面向最终用户的包。它出厂时没有任何功能。这是一个集成商或开发人员的包。您需要在您的包中编写一些 Python 和 zcml 代码(就像现在的 Poi 一样)来将 collective.watcherlist 集成到您的代码中。

我们很高兴使用 ZCA(Zope 组件架构)来允许其他人注册他们自己的适配器和自己的电子邮件文本,因此除了 Zope 之外,该包的意义不大。我们还从 Plone 中导入了一些代码,因此您将需要这些代码。如果您想在裸 Zope 或 CMF 中使用它,请联系我:我们可能可以进行一些条件导入。

collective.watcherlist 也可能作为新闻通讯产品的基座。如果您觉得 Singing and Dancing 对您来说太过于复杂,或者太难适应您的特定需求,您可以尝试围绕 collective.watcherlist 编写一些代码。

基本集成步骤

在最简单的情况下,所需的集成如下

  • 注册一个从您的内容类型到 collective.watcherlist.interfaces.IWatcherList 的适配器。在许多情况下,使用默认实现作为此适配器的工厂是合适的:collective.watcherlist.watchers.WatcherList

  • 创建一个 HTML 表单,人们可以在其中添加自己到监视者列表。这也可以是一个带有自定义脚本适配器的 PloneFormGen 表单。

  • 注册一个从您的内容类型继承的 BrowserView,继承自 collective.watcherlist.browser.BaseMail 并覆盖其属性 subjectplain 和/或 html

  • 创建一个事件处理器或其他代码,获取您的内容类型的适配器,并使用它发送电子邮件,邮件主题和内容由您创建的浏览器视图定义。

事件集成

此插件与 zope 的事件和 plone 的内容规则兼容。它在监视列表上执行所有基本操作时触发 zope 事件

  • ToggleWatchingEvent

  • RemovedFromWatchingEvent

  • AddedToWatchingEvent

这些事件被注册为可用的内容规则触发器,因此您可以根据它创建规则。

它还提供了一个内容规则操作,您可以创建一个添加或从上下文关联的监视列表中删除当前用户的操作。

致谢

人员

公司

collective.watcherlist

示例集成

让我们举一个例子,说明您在自己的代码中需要做什么来使用此包。我们定义一个类,其中包含有关某个聚会的一些信息

>>> class Party(object):
...     def __init__(self, reason):
...         self.reason = reason
...         self.invited = []

我们向ZCA说明如何将一个派对适配到观察者列表:如何将其转变为一个包含感兴趣人员列表的对象,并知道如何向他们发送电子邮件。通常,你会定义一个接口 IParty,比如声明 Party 类实现了该接口,并使用zcml注册一个适配器,如下所示

<adapter
    for=".interfaces.IParty"
    factory="collective.watcherlist.watchers.WatcherList"
    />

让我们忽略接口,使用Python(因为在测试中使用Python要简单一些)。我们将使用该软件包提供的默认观察者列表实现

>>> from zope.component import getGlobalSiteManager
>>> from collective.watcherlist.watchers import WatcherList
>>> sm = getGlobalSiteManager()
>>> sm.registerAdapter(WatcherList, (Party, ))

现在我们创建一个派对并邀请人员

>>> birthday = Party("Maurits' birthday")
>>> birthday.invited.append('Fred')
>>> birthday.invited.append('Mirella')

我们看看是否可以获取该派对的观察者列表

>>> from collective.watcherlist.interfaces import IWatcherList
>>> watcherlist = IWatcherList(birthday)
>>> watcherlist
<collective.watcherlist.watchers.WatcherList object at ...>

我们可以从这个列表中询问很多事情

>>> watcherlist.watchers
[]
>>> watcherlist.send_emails
True
>>> watcherlist.addresses
()

我们可以添加观察者。这些应该是电子邮件地址(至少在Plone环境中)或网站的成员ID。在你的包中,你可能会创建一个按钮或其他小表单,人们可以使用它将自己添加到列表中,或者创建一些代码来自动添加某些人,就像Poi为创建新问题的创建者所做的那样。代码很简单

>>> watcherlist.watchers.append('maurits@example.org')
>>> watcherlist.watchers.append('reinout@example.org')
>>> watcherlist.watchers
['maurits@example.org', 'reinout@example.org']
>>> watcherlist.addresses
('maurits@example.org', 'reinout@example.org')

你总是可以关闭电子邮件发送。这会使得没有任何地址被报告

>>> watcherlist.send_emails = False
>>> watcherlist.watchers
['maurits@example.org', 'reinout@example.org']
>>> watcherlist.addresses
()

撤销该操作

>>> watcherlist.send_emails = True
>>> watcherlist.watchers
['maurits@example.org', 'reinout@example.org']
>>> watcherlist.addresses
('maurits@example.org', 'reinout@example.org')

现在我们发送一封电子邮件。我们简单地从我们定义的浏览器视图中获取电子邮件文本和主题。在测试中,这意味着我们需要给派对一个请求对象

>>> from zope.publisher.browser import TestRequest
>>> birthday.REQUEST = TestRequest()

我们现在发送一封邀请电子邮件,但失败了

>>> watcherlist.send('invitation')
Traceback (most recent call last):
...
ComponentLookupError...

这意味着我们需要创建一个具有该名称的浏览器视图。作为基础,我们应该采用 collective.watcherlist 包中定义的基本浏览器视图。它包含三个你通常会覆盖的属性:主题、纯文本和HTML

>>> from collective.watcherlist.browser import BaseMail
>>> class PartyMail(BaseMail):
...     @property
...     def subject(self):
...         return self.context.reason
...     @property
...     def plain(self):
...         return "Invited are %s" % self.context.invited
...     @property
...     def html(self):
...         return "<p>%s</p>" % self.plain

你通常会使用zcml注册这个视图,就像其他任何浏览器视图一样。但在这里我们在Python代码中这样做

>>> from zope.interface import Interface
>>> sm.registerAdapter(PartyMail, (Party, TestRequest), Interface, 'invitation')

然后我们再次发送邀请,以纯文本和HTML的形式。在这个测试中,我们没有设置合适的邮件主机,所以我们简单地打印相关信息,以便我们可以看到会发生什么

>>> watcherlist.send('invitation')
Subject = Maurits' birthday
Addresses = ('maurits@example.org', 'reinout@example.org')
Message =
From...
Content-Type: multipart/alternative;...
...
Content-Type: text/plain; charset="us-ascii"
...
Invited are ['Fred', 'Mirella']
...
Content-Type: text/html; charset="us-ascii"
...
<p>Invited are ['Fred', 'Mirella']</p>
...

让我们忽略HTML,看看这是否会简化邮件

>>> PartyMail.html = ''
>>> watcherlist.send('invitation')
Subject = Maurits' birthday
Addresses = ('maurits@example.org', 'reinout@example.org')
Message =
From...
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
<BLANKLINE>
Invited are ['Fred', 'Mirella']

如果没有纯文本也没有HTML,我们不会发送任何内容

>>> PartyMail.plain = ''
>>> watcherlist.send('invitation')

让我们再次添加一些HTML,看看是否只有HTML可以正常工作

>>> PartyMail.html = '<p>You are invited.</p>'
>>> watcherlist.send('invitation')
Subject = Maurits' birthday
Addresses = ('maurits@example.org', 'reinout@example.org')
Message =
From...
MIME-Version: 1.0
Content-Type: text/html; charset="us-ascii"
Content-Transfer-Encoding: 7bit
<BLANKLINE>
<p>You are invited.</p>

如果我们为这个观察者列表关闭电子邮件发送……就不会发送任何电子邮件

>>> watcherlist.send_emails = False
>>> watcherlist.send('invitation')

重置该操作

>>> watcherlist.send_emails = True

查看 Products.Poi 以获取更多你可以做什么的示例。

变更日志

3.1.0 (2018-04-26)

  • 不再使用Plone 4.1、4.2或Python 2.6进行测试。它应该仍然可以工作,但我不想在Travis上花费时间修复构建。[maurits]

3.0.1 (2018-04-26)

  • 声明 zope.formlib 依赖。[maurits]

3.0 (2016-12-23)

  • 默认情况下通过 immediate=False。这曾经是 True。原始的想法是立即发送电子邮件,这样我们就可以自己捕获任何错误并继续使用警告。但是,自从Plone 4.1以来,电子邮件默认在事务结束时发送,并且异常被捕获。对于立即邮件,它们不会被那里捕获。所以对于我们的用例,最合理的是不立即发送电子邮件,因为这样Plone已经做了我们想要的事情。如果你想要恢复旧的行为,你仍然可以将 immediate=True 传递给 mailer.simple_send_mail 或现在也可以传递给 watchers.send。这修复了 问题 #8。[maurits]

  • 在监视器列表中检查 allow_recursive。默认值是 true,与之前的操作行为相同。当值为 false 时,addresses 属性仅会在当前项上查找监视器,而不会在父项上查找。一个示例用法是在 Products.Poi 中,只有在问题尚未分配时才允许递归。(我打算在为客户编写的自定义代码中使用它)。[maurits]

  • 去除我们从成员或网站获取的电子邮件地址。我有一个网站,其中一些电子邮件地址是 test@example.org\r\n,在发送时会出错。[maurits]

2.0 (2016-07-07)

  • 移除了对 Plone 3.3 和 4.0 的向后兼容代码。我们已经不再在 3.3 上进行测试,而 4.0 的维护过于困难。[maurits]

  • 修复了 Plone 5 的电子邮件发送问题。提高了代码质量。修复了 Travis 测试。[maurits]

  • 当内部监视器列表类型为列表(而不是元组)时,确保在切换监视器时更新它。[skurfer]

1.2 (2013-12-03)

  • 为内容规则添加了事件、触发器和操作。[Gagaro]

1.1 (2012-11-06)

1.0 (2012-04-21)

  • 在浏览器中以纯文本形式显示测试时,强制使用 text/plain 作为内容类型。[maurits]

0.3 (2011-05-09)

  • 在发送电子邮件时捕获 MailHostErrors。[maurits]

0.2 (2010-02-27)

  • 现在可以将 only_these_addresses 作为参数传递给 send 方法。这将强制只向这些地址发送邮件,而忽略其他所有地址。[maurits]

  • 修复了当电子邮件的纯文本或 HTML 部分不是 Unicode 时可能出现的 UnicodeDecodeError。[maurits]

0.1 (2010-02-26)

  • 初始发布

项目详情


下载文件

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

源代码分发

collective.watcherlist-3.1.0.tar.gz (33.1 kB 查看哈希)

上传时间 源代码

支持者:

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误记录 StatusPage StatusPage 状态页面