/
configlet.py
185 lines (133 loc) · 5.28 KB
/
configlet.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
##############################################################################
#
# Copyright (c) 2009 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""
$Id$
"""
import random
import BTrees
from zope import interface, event, component
from zope.app.intid.interfaces import IIntIds, IIntIdRemovedEvent
from zope.component import getUtility, getMultiAdapter, ComponentLookupError
from zope.proxy import removeAllProxies
from zope.publisher.browser import TestRequest
from zojax.authentication.interfaces import IPrincipalRemovingEvent
from zojax.catalog.utils import getRequest
from zojax.mailtemplate.interfaces import IMailTemplate
from catalog import AcknowledgementsCatalog
from interfaces import IAcknowledgements, IContentAcknowledgementAware
from interfaces import IAcknowledgementAddedEvent, IContentAcknowledgement
from interfaces import IAcknowledgementRemovedEvent
class AcknowledgementConfiglet(object):
interface.implements(IAcknowledgements)
family = BTrees.family32
_v_nextid = None
_randrange = random.randrange
@property
def records(self):
data = self.data.get('records')
if data is None:
data = self.family.IO.BTree()
self.data['records'] = data
return data
@property
def catalog(self):
catalog = self.data.get('catalog')
if catalog is None:
catalog = AcknowledgementsCatalog()
self.data['catalog'] = catalog
return catalog
def _generateId(self):
records = self.records
while True:
if self._v_nextid is None:
self._v_nextid = self._randrange(0, self.family.maxint)
id = self._v_nextid
self._v_nextid += 1
if id not in records:
return id
self._v_nextid = None
def search(self, **kw):
return self.catalog.search(**kw)
def objectRecords(self, object):
return self.catalog.search(object=object)
def updateObjectRecords(self, object):
catalog = self.catalog
for record in catalog.search(object=object):
catalog.index_doc(record.id, record)
def getObject(self, id):
return self.records[id]
def add(self, record):
if record.oid is None:
return
object = getUtility(IIntIds).queryObject(record.oid)
if not IContentAcknowledgementAware.providedBy(object):
return
record.id = self._generateId()
self.records[record.id] = record
self.catalog.index_doc(record.id, record)
event.notify(AcknowledgementAddedEvent(object, record))
def remove(self, rid):
records = self.records
record = records[rid]
event.notify(AcknowledgementRemovedEvent(record.object, record))
self.catalog.unindex_doc(rid)
del records[rid]
def removeObject(self, object):
records = self.records
for rid in self.catalog.search(object).uids:
event.notify(
AcknowledgementRemovedEvent(object, records[rid]))
self.catalog.unindex_doc(rid)
del records[rid]
def verifyRecord(self, uid, oid=None, object=None):
if oid:
object = getUtility(IIntIds).queryObject(oid)
result = self.catalog.search(object=object,
principal={'any_of': (uid,)})
if len(result) > 0:
return result[0]
return False
class AcknowledgementEvent(object):
def __init__(self, object, record):
self.object = object
self.record = record
class AcknowledgementAddedEvent(AcknowledgementEvent):
interface.implements(IAcknowledgementAddedEvent)
class AcknowledgementRemovedEvent(AcknowledgementEvent):
interface.implements(IAcknowledgementRemovedEvent)
@component.adapter(IContentAcknowledgementAware, IIntIdRemovedEvent)
def objectRemovingHandler(object, ev):
removeAllProxies(getUtility(IAcknowledgements)).removeObject(object)
@component.adapter(IPrincipalRemovingEvent)
def principalRemovingHandler(event):
catalog = getUtility(IAcknowledgements)
for record in catalog.search(principal={'any_of': (event.principal.id,)}):
catalog.remove(record.id)
@component.adapter(IContentAcknowledgementAware, IAcknowledgementAddedEvent)
def acknowledgementAddedHandler(object, ev):
obj = IContentAcknowledgement(object)
if not obj:
return
emails = obj.emails_list
if not emails:
return
try:
template = getMultiAdapter((ev.record, getRequest()),
IMailTemplate,
'html')
except ComponentLookupError:
template = getMultiAdapter((ev.record, TestRequest()),
IMailTemplate,
'html')
template.send(emails)