38
38
import StringIO
39
39
from AccessControl import ClassSecurityInfo
40
40
from blob import add_OfsBlobFile
41
+ from BTrees .OOBTree import BTree
41
42
from Comment import CommentsManager
42
43
from DateTime import DateTime
43
44
from Globals import InitializeClass
44
45
from OFS .ObjectManager import ObjectManager
45
46
from OFS .PropertyManager import PropertyManager
46
47
from OFS .SimpleItem import SimpleItem
48
+ from zope .annotation .interfaces import IAnnotations
47
49
from zope .event import notify
48
50
from zope .interface import alsoProvides , implements
49
51
from zope .lifecycleevent import ObjectModifiedEvent
52
54
from Products .PageTemplates .ZopePageTemplate import ZopePageTemplate
53
55
from Products .Reportek import constants
54
56
from Products .Reportek .CatalogAware import CatalogAware
55
- from Products .Reportek .interfaces import IFeedback
57
+ from Products .Reportek .interfaces import IFeedback , IFeedbackHistory
56
58
from Products .Reportek .RepUtils import DFlowCatalogAware , parse_uri
57
59
58
60
__version__ = "$Rev$" [6 :- 2 ]
61
+ ANNOTATION_KEY = "feedback.history"
59
62
logger = logging .getLogger ("Reportek" )
60
63
61
64
manage_addFeedbackForm = PageTemplateFile ("zpt/feedback/add" , globals ())
@@ -247,7 +250,7 @@ class ReportFeedback(
247
250
# Create a SecurityInfo for this class. We will use this
248
251
# in the rest of our class definition to make security
249
252
# assertions.
250
- implements (IFeedback )
253
+ implements (IFeedback , IFeedbackHistory )
251
254
security = ClassSecurityInfo ()
252
255
253
256
def __init__ (
@@ -275,6 +278,7 @@ def __init__(
275
278
self .postingdate = DateTime ()
276
279
self .message = message
277
280
self .feedback_status = feedback_status
281
+ self .__history = None
278
282
279
283
def update_item (self , postingdate = None ):
280
284
"""If the parameter is provided, updates the postingdate to it
@@ -409,34 +413,38 @@ def deserialize_html_feedback(self, value):
409
413
value = value .get ("data" , "" )
410
414
return value , kwargs
411
415
412
- security .declareProtected ("Change Feedback" , "manage_editFeedback " )
416
+ security .declareProtected ("Change Feedback" , "edit " )
413
417
414
418
def edit (self ):
415
419
"""Edits the properties of the feedback.
416
420
To be used by the FME"""
417
- VALID_ATTRS = [
418
- "title" ,
419
- "feedback-data" ,
420
- "content_type" ,
421
- "document_id" ,
422
- "feedback_status" ,
423
- "message" ,
424
- ]
421
+ VALID_ATTRS_MAP = {
422
+ "title" : "title" ,
423
+ "feedback-data" : "feedbacktext" ,
424
+ "content_type" : "content_type" ,
425
+ "document_id" : "document_id" ,
426
+ "feedback_status" : "feedback_status" ,
427
+ "message" : "message" ,
428
+ }
429
+ history = {}
425
430
accept = self .REQUEST .environ .get ("HTTP_ACCEPT" )
426
431
if accept == "application/json" :
427
432
if "IDisableCSRFProtection" in dir (plone .protect .interfaces ):
428
433
alsoProvides (
429
434
self .REQUEST ,
430
435
plone .protect .interfaces .IDisableCSRFProtection ,
431
436
)
432
- self .REQUEST .RESPONSE .setHeader ("Content-Type" , "application/json" )
437
+ self .REQUEST .RESPONSE .setHeader ("Content-Type" ,
438
+ "application/json" )
433
439
res = {}
434
440
data = json .loads (self .REQUEST .get ("BODY" ) or "{}" )
435
441
if not isinstance (data , dict ):
436
442
res ["result" ] = "Fail"
437
443
res ["message" ] = "Malformed body"
438
444
439
- for attr in VALID_ATTRS :
445
+ for attr in VALID_ATTRS_MAP .keys ():
446
+ history [VALID_ATTRS_MAP [attr ]] = getattr (
447
+ self , VALID_ATTRS_MAP [attr ])
440
448
if attr in data :
441
449
try :
442
450
if attr == "feedback-data" :
@@ -453,8 +461,10 @@ def edit(self):
453
461
res ["result" ] = "Fail"
454
462
res ["message" ] = err_msg
455
463
return json .dumps (res )
464
+ history ['author' ] = self .author
465
+ self .author = self .REQUEST .AUTHENTICATED_USER .getUserName ()
456
466
notify (ObjectModifiedEvent (self ))
457
-
467
+ self . add_to_history ( history )
458
468
res ["result" ] = "Success"
459
469
res ["message" ] = "Feedback updated"
460
470
return json .dumps (res , indent = 4 )
@@ -463,6 +473,34 @@ def edit(self):
463
473
"%s/manage_editFeedbackForm" % self .absolute_url ()
464
474
)
465
475
476
+ def _history (self , create = True ):
477
+ if getattr (self , '__history' , None ) is not None :
478
+ return self .__history
479
+
480
+ annotations = IAnnotations (self )
481
+ history = annotations .get (ANNOTATION_KEY , None )
482
+ if history is None and create :
483
+ history = annotations .setdefault (ANNOTATION_KEY , BTree ())
484
+ if history is not None :
485
+ self .__history = history
486
+ return self .__history
487
+
488
+ def get_history (self ):
489
+ history = self ._history (create = False )
490
+ return history
491
+
492
+ def add_to_history (self , history ):
493
+ annotations = self ._history ()
494
+ annotations .insert (DateTime ().HTML4 (), history )
495
+
496
+ @property
497
+ def author (self ):
498
+ return getattr (self , '_author' , 'Original author' )
499
+
500
+ @author .setter
501
+ def author (self , value ):
502
+ self ._author = value
503
+
466
504
security .declareProtected ("Change Feedback" , "manage_uploadFeedback" )
467
505
468
506
def manage_uploadFeedback (self , file = "" , REQUEST = None , filename = None ):
0 commit comments