def __iter__(self): for item in self.previous: pathkey = self.pathkey(*item.keys())[0] typekey = self.comment_type_key(*item.keys())[0] # item doesn't exist or the type of comment cannot be # created if not pathkey or not typekey: # TODO: log a note yield item continue comment_type = item[typekey] if comment_type == "plone.app.discussion" and not PAD_INSTALLED: # TODO: log a note yield item continue path = item[pathkey] obj = self.context.unrestrictedTraverse(path.lstrip('/'), None) # path doesn't exist if obj is None: yield item continue # TODO: check to see if the object supports commenting... title = item.get('title', '') text = item.get('text', '') creator = item.get('author_name', '') creation_date = item.get('published', '') modification_date = item.get('updated', '') mime_type = item.get('mime_type', 'text/x-html-safe') if comment_type == "plone.app.discussion": conversation = IConversation(obj) # create a reply object comment = CommentFactory() comment.title = title comment.text = text comment.creator = creator comment.author_name = creator comment.author_username = creator comment.mime_type = mime_type # TODO: strptime is is python2.5+, need python2.4 solution if not isinstance(creation_date, datetime): creation_date = datetime.strptime( creation_date, self.date_format) comment.creation_date = creation_date if not isinstance(modification_date, datetime): modification_date = datetime.strptime( modification_date, self.date_format) comment.modification_date = modification_date conversation.addComment(comment) # TODO: fire events if comment_type == "plone": # TODO: create default plone content pass yield item
def migrate_replies(context, in_reply_to, replies, depth=0, just_delete=0): # Recursive function to migrate all direct replies # of a comment. Returns True if there are no replies to # this comment left, and therefore the comment can be removed. if len(replies) == 0: return True workflow = context.portal_workflow oldchain = workflow.getChainForPortalType('Discussion Item') new_workflow = workflow.comment_review_workflow mt = getToolByName(self.context, 'portal_membership') if type(oldchain) == TupleType and len(oldchain) > 0: oldchain = oldchain[0] for reply in replies: # log indent = " " for i in range(depth): indent += " " log("%smigrate_reply: '%s'." % (indent, reply.title)) should_migrate = True if filter_callback and not filter_callback(reply): should_migrate = False if just_delete: should_migrate = False new_in_reply_to = None if should_migrate: # create a reply object comment = CommentFactory() comment.title = reply.Title() comment.text = reply.cooked_text comment.mime_type = 'text/html' comment.creator = reply.Creator() try: comment.author_username = reply.author_username except AttributeError: comment.author_username = reply.Creator() member = mt.getMemberById(comment.author_username) if member: comment.author_name = member.fullname if not comment.author_name: # In migrated site member.fullname = '' # while member.getProperty('fullname') has the # correct value if member: comment.author_name = member.getProperty( 'fullname') else: comment.author_name = comment.author_username try: comment.author_email = reply.email except AttributeError: comment.author_email = None comment.creation_date = DT2dt(reply.creation_date) comment.modification_date = DT2dt(reply.modification_date) comment.reply_to = in_reply_to if in_reply_to == 0: # Direct reply to a content object new_in_reply_to = conversation.addComment(comment) else: # Reply to another comment comment_to_reply_to = conversation.get(in_reply_to) replies = IReplies(comment_to_reply_to) new_in_reply_to = replies.addComment(comment) # migrate the review state old_status = workflow.getStatusOf(oldchain, reply) new_status = { 'action': None, 'actor': None, 'comment': 'Migrated workflow state', 'review_state': old_status and old_status.get( 'review_state', new_workflow.initial_state) or 'published', 'time': DateTime() } workflow.setStatusOf('comment_review_workflow', comment, new_status) auto_transition = new_workflow._findAutomaticTransition( comment, new_workflow._getWorkflowStateOf(comment)) if auto_transition is not None: new_workflow._changeStateOf(comment, auto_transition) else: new_workflow.updateRoleMappingsFor(comment) comment.reindexObject( idxs=['allowedRolesAndUsers', 'review_state']) self.total_comments_migrated += 1 # migrate all talkbacks of the reply talkback = getattr(reply, 'talkback', None) no_replies_left = migrate_replies( context, new_in_reply_to, talkback.getReplies(), depth=depth + 1, just_delete=not should_migrate) if no_replies_left: # remove reply and talkback talkback.deleteReply(reply.id) obj = aq_parent(talkback) obj.talkback = None log("%sremove %s" % (indent, reply.id)) self.total_comments_deleted += 1 # Return True when all comments on a certain level have been # migrated. return True
def migrate_replies(context, in_reply_to, replies, depth=0, just_delete=0): # Recursive function to migrate all direct replies # of a comment. Returns True if there are no replies to # this comment left, and therefore the comment can be removed. if len(replies) == 0: return True workflow = context.portal_workflow oldchain = workflow.getChainForPortalType('Discussion Item') new_workflow = workflow.comment_review_workflow mt = getToolByName(self.context, 'portal_membership') if type(oldchain) == TupleType and len(oldchain) > 0: oldchain = oldchain[0] for reply in replies: # log indent = " " for i in range(depth): indent += " " log("%smigrate_reply: '%s'." % (indent, reply.title)) should_migrate = True if filter_callback and not filter_callback(reply): should_migrate = False if just_delete: should_migrate = False new_in_reply_to = None if should_migrate: # create a reply object comment = CommentFactory() comment.title = reply.Title() comment.text = reply.cooked_text comment.mime_type = 'text/html' comment.creator = reply.Creator() try: comment.author_username = reply.author_username except AttributeError: comment.author_username = reply.Creator() member = mt.getMemberById(comment.author_username) if member: comment.author_name = member.fullname if not comment.author_name: # In migrated site member.fullname = '' # while member.getProperty('fullname') has the # correct value if member: comment.author_name = member.getProperty( 'fullname' ) else: comment.author_name = comment.author_username try: comment.author_email = reply.email except AttributeError: comment.author_email = None comment.creation_date = DT2dt(reply.creation_date) comment.modification_date = DT2dt(reply.modification_date) comment.reply_to = in_reply_to if in_reply_to == 0: # Direct reply to a content object new_in_reply_to = conversation.addComment(comment) else: # Reply to another comment comment_to_reply_to = conversation.get(in_reply_to) replies = IReplies(comment_to_reply_to) new_in_reply_to = replies.addComment(comment) # migrate the review state old_status = workflow.getStatusOf(oldchain, reply) new_status = { 'action': None, 'actor': None, 'comment': 'Migrated workflow state', 'review_state': old_status and old_status.get( 'review_state', new_workflow.initial_state ) or 'published', 'time': DateTime() } workflow.setStatusOf('comment_review_workflow', comment, new_status) auto_transition = new_workflow._findAutomaticTransition( comment, new_workflow._getWorkflowStateOf(comment)) if auto_transition is not None: new_workflow._changeStateOf(comment, auto_transition) else: new_workflow.updateRoleMappingsFor(comment) comment.reindexObject(idxs=['allowedRolesAndUsers', 'review_state']) self.total_comments_migrated += 1 # migrate all talkbacks of the reply talkback = getattr(reply, 'talkback', None) no_replies_left = migrate_replies( context, new_in_reply_to, talkback.getReplies(), depth=depth + 1, just_delete=not should_migrate) if no_replies_left: # remove reply and talkback talkback.deleteReply(reply.id) obj = aq_parent(talkback) obj.talkback = None log("%sremove %s" % (indent, reply.id)) self.total_comments_deleted += 1 # Return True when all comments on a certain level have been # migrated. return True
def __iter__(self): for item in self.previous: pathkey = self.pathkey(*list(item.keys()))[0] path = item[pathkey] obj = self.context.unrestrictedTraverse( str(path).lstrip("/"), None) # path doesn't exist if obj is None: yield item continue discussion = item.get("discussions", []) if not discussion: yield item continue id_map = {} conversation = IConversation(obj) # remove all comments to avoid duplication when override is disabled # noqa if list(conversation.items()): comments_id = [x[0] for x in conversation.items()] for value in comments_id: try: del conversation[value] except Exception: logger.warning( "WARNING: Discussion with id {0} not found". format( # noqa value)) pass for comment in discussion: new_comment = CommentFactory() new_comment.text = comment.get("text") new_comment.creator = comment.get("creator") new_comment.author_name = comment.get("author_name") new_comment.author_username = comment.get("author_username") new_comment.author_email = comment.get("author_email") new_comment.in_reply_to = id_map.get( comment.get("in_reply_to"), 0) new_comment.mime_type = comment.get("mime_type") new_comment._owner = comment.get("_owner") new_comment.__ac_local_roles__ = comment.get( "__ac_local_roles__") new_comment.user_notification = comment.get( "user_notification") new_comment.creation_date = DateTime( comment.get("creation_date")).asdatetime() new_comment.modification_date = DateTime( comment.get("modification_date")).asdatetime() conversation.addComment(new_comment) comment_wf = new_comment.workflow_history.data.get( "comment_review_workflow") if comment_wf: new_comment.workflow_history.data.get( "comment_review_workflow")[ # noqa 0]["review_state"] = comment["status"] id_map.update( {comment.get("comment_id"): int(new_comment.comment_id)}) logger.info(("Added comment with id {0} to item {1}".format( new_comment.comment_id, obj.absolute_url()))) yield item