def serialize_node_for_page_list(content: Content, context: Context): if content.type==ContentType.Page: if not content.parent: folder = None else: folder = Context(CTX.DEFAULT).toDict(content.parent) result = DictLikeClass( id = content.content_id, label = content.label, status = context.toDict(content.get_status()), folder = folder ) return result if content.type==ContentType.File: result = DictLikeClass( id = content.content_id, label = content.label, status = context.toDict(content.get_status()), folder = Context(CTX.DEFAULT).toDict(content.parent) ) return result # TODO - DA - 2014-10-16 - THE FOLLOWING CODE SHOULD BE REMOVED # # if content.type==ContentType.Folder: # return DictLikeClass( # id = content.content_id, # label = content.label, # ) raise NotImplementedError('node type / context not implemented: {} {}'. format(content.type, context.context_string))
def serialize_node_for_page_list(content: Content, context: Context): if content.type==ContentType.Page: if not content.parent: folder = None else: folder = Context(CTX.DEFAULT).toDict(content.parent) result = DictLikeClass( id = content.content_id, label = content.label, status = context.toDict(content.get_status()), folder = folder ) return result if content.type==ContentType.File: result = DictLikeClass( id = content.content_id, label = content.label if content.label else content.file_name, status = context.toDict(content.get_status()), folder = Context(CTX.DEFAULT).toDict(content.parent) ) return result # TODO - DA - 2014-10-16 - THE FOLLOWING CODE SHOULD BE REMOVED # # if content.type==ContentType.Folder: # return DictLikeClass( # id = content.content_id, # label = content.label, # ) raise NotImplementedError('node type / context not implemented: {} {}'. format(content.type, context.context_string))
def serialize_content_for_general_list(content: Content, context: Context): content_type = ContentType(content.type) last_activity_date = content.get_last_activity_date() last_activity_date_formatted = format_datetime(last_activity_date, locale=tg.i18n.get_lang()[0]) last_activity_label = format_timedelta( datetime.utcnow() - last_activity_date, locale=tg.i18n.get_lang()[0], ) last_activity_label = last_activity_label.replace(' ', '\u00A0') # espace insécable return DictLikeClass( id=content.content_id, folder = DictLikeClass({'id': content.parent_id}) if content.parent else None, workspace=context.toDict(content.workspace) if content.workspace else None, label=content.get_label(), url=ContentType.fill_url(content), type=DictLikeClass(content_type.toDict()), status=context.toDict(content.get_status()), is_deleted=content.is_deleted, is_archived=content.is_archived, is_editable=content.is_editable, last_activity = DictLikeClass({'date': last_activity_date, 'label': last_activity_date_formatted, 'delta': last_activity_label}) )
def serialize_content_for_general_list(content: Content, context: Context): content_type = ContentType(content.type) last_activity_date = content.get_last_activity_date() last_activity_date_formatted = format_datetime(last_activity_date, locale=tg.i18n.get_lang()[0]) last_activity_label = format_timedelta( datetime.utcnow() - last_activity_date, locale=tg.i18n.get_lang()[0], ) last_activity_label = last_activity_label.replace(' ', '\u00A0') # espace insécable return DictLikeClass( id=content.content_id, folder = DictLikeClass({'id': content.parent_id}) if content.parent else None, workspace=context.toDict(content.workspace) if content.workspace else None, label=content.get_label(), url=ContentType.fill_url(content), type=DictLikeClass(content_type.toDict()), status=context.toDict(content.get_status()), is_deleted=content.is_deleted, is_archived=content.is_archived, is_editable=content.is_editable, last_activity = DictLikeClass({'date': last_activity_date, 'label': last_activity_date_formatted, 'delta': last_activity_label}) )
def serialize_content_for_workspace_and_folder(content: Content, context: Context): thread_nb_all = content.get_child_nb(ContentType.Thread) thread_nb_open = content.get_child_nb(ContentType.Thread) file_nb_all = content.get_child_nb(ContentType.File) file_nb_open = content.get_child_nb(ContentType.File) folder_nb_all = content.get_child_nb(ContentType.Folder) folder_nb_open = content.get_child_nb(ContentType.Folder) page_nb_all = content.get_child_nb(ContentType.Page) page_nb_open = content.get_child_nb(ContentType.Page) content_nb_all = thread_nb_all +\ thread_nb_open +\ file_nb_all +\ file_nb_open +\ folder_nb_all +\ folder_nb_open +\ page_nb_all +\ page_nb_open result = None if content.type==ContentType.Folder: allowed_content = DictLikeClass(content.properties['allowed_content']), result = DictLikeClass( id=content.content_id, label=content.label, created=content.created, workspace=context.toDict(content.workspace), allowed_content=DictLikeClass(content.properties['allowed_content']), allowed_content_types=context.toDict(content.get_allowed_content_types()), selected_revision='latest', status=context.toDict(content.get_status()), owner=context.toDict(content.owner), thread_nb=DictLikeClass(all=thread_nb_all, open=thread_nb_open), file_nb=DictLikeClass(all=file_nb_all, open=file_nb_open), folder_nb=DictLikeClass(all=folder_nb_all, open=folder_nb_open), page_nb=DictLikeClass(all=page_nb_all, open=page_nb_open), content_nb=DictLikeClass(all = content_nb_all) ) elif content.type==ContentType.Page: result = DictLikeClass( id = content.content_id, label = content.label, created = content.created, workspace = context.toDict(content.workspace), owner = DictLikeClass( id = content.owner.user_id, name = content.owner.get_display_name() ), status = DictLikeClass(id='', label=''), #FIXME - EXPORT DATA ) return result
def serialize_content_for_workspace_and_folder(content: Content, context: Context): thread_nb_all = content.get_child_nb(ContentType.Thread) thread_nb_open = content.get_child_nb(ContentType.Thread) file_nb_all = content.get_child_nb(ContentType.File) file_nb_open = content.get_child_nb(ContentType.File) folder_nb_all = content.get_child_nb(ContentType.Folder) folder_nb_open = content.get_child_nb(ContentType.Folder) page_nb_all = content.get_child_nb(ContentType.Page) page_nb_open = content.get_child_nb(ContentType.Page) content_nb_all = thread_nb_all +\ thread_nb_open +\ file_nb_all +\ file_nb_open +\ folder_nb_all +\ folder_nb_open +\ page_nb_all +\ page_nb_open result = None if content.type==ContentType.Folder: allowed_content = DictLikeClass(content.properties['allowed_content']), result = DictLikeClass( id=content.content_id, label=content.label, created=content.created, workspace=context.toDict(content.workspace), allowed_content=DictLikeClass(content.properties['allowed_content']), allowed_content_types=context.toDict(content.get_allowed_content_types()), selected_revision='latest', status=context.toDict(content.get_status()), owner=context.toDict(content.owner), thread_nb=DictLikeClass(all=thread_nb_all, open=thread_nb_open), file_nb=DictLikeClass(all=file_nb_all, open=file_nb_open), folder_nb=DictLikeClass(all=folder_nb_all, open=folder_nb_open), page_nb=DictLikeClass(all=page_nb_all, open=page_nb_open), content_nb=DictLikeClass(all = content_nb_all) ) elif content.type==ContentType.Page: result = DictLikeClass( id = content.content_id, label = content.label, created = content.created, workspace = context.toDict(content.workspace), owner = DictLikeClass( id = content.owner.user_id, name = content.owner.get_display_name() ), status = DictLikeClass(id='', label=''), #FIXME - EXPORT DATA ) return result
def serialize_node_for_page(item: Content, context: Context): if item.type == ContentType.Thread: return DictLikeClass( content=item.description, created=item.created, icon=ContentType.get_icon(item.type), id=item.content_id, label=item.label, links=[], owner=context.toDict(item.owner), parent=context.toDict(item.parent), selected_revision='latest', status=context.toDict(item.get_status()), type=item.type, workspace=context.toDict(item.workspace), comments=reversed(context.toDict(item.get_comments())), is_new=item.has_new_information_for(context.get_user()), history=Context(CTX.CONTENT_HISTORY).toDict(item.get_history()), urls=context.toDict({ 'mark_read': context.url( Content.format_path( '/workspaces/{wid}/folders/{fid}/{ctype}s/{cid}/put_read', item)), 'mark_unread': context.url( Content.format_path( '/workspaces/{wid}/folders/{fid}/{ctype}s/{cid}/put_unread', item)) }), ) if item.type == ContentType.Comment: return DictLikeClass( is_new=item.has_new_information_for(context.get_user()), content=item.description, created=item.created, created_as_delta=item.created_as_delta(), icon=ContentType.get_icon(item.type), id=item.content_id, label=item.label, owner=context.toDict(item.owner), # REMOVE parent = context.toDict(item.parent), type=item.type, urls=context.toDict({ 'delete': context.url( '/workspaces/{wid}/folders/{fid}/{ctype}/{cid}/comments/{commentid}/put_delete' .format(wid=item.workspace_id, fid=item.parent.parent_id, ctype=item.parent.type + 's', cid=item.parent.content_id, commentid=item.content_id)) })) if item.type == ContentType.Folder: return Context(CTX.DEFAULT).toDict(item)
def serialize_node_for_thread(item: Content, context: Context): if item.type in (ContentType.Thread, ContentType.Task, ContentType.Ticket): return DictLikeClass( content = item.description, created = item.created, updated = item.last_revision.updated, revision_nb = len(item.revisions), icon = ContentType.get_icon(item.type), id = item.content_id, label = item.label, links=[], owner = context.toDict(item.owner), last_modification_author=context.toDict(item.last_revision.owner), parent = context.toDict(item.parent), selected_revision = 'latest', status = context.toDict(item.get_status()), type = item.type, workspace = context.toDict(item.workspace), comments = reversed(context.toDict(item.get_comments())), is_new=item.has_new_information_for(context.get_user()), history = Context(CTX.CONTENT_HISTORY).toDict(item.get_history()), is_editable=item.is_editable, is_deleted=item.is_deleted, is_archived=item.is_archived, urls = context.toDict({ 'mark_read': context.url(Content.format_path('/workspaces/{wid}/folders/{fid}/{ctype}s/{cid}/put_read', item)), 'mark_unread': context.url(Content.format_path('/workspaces/{wid}/folders/{fid}/{ctype}s/{cid}/put_unread', item)) }), ) if item.type == ContentType.Comment: return DictLikeClass( is_new=item.has_new_information_for(context.get_user()), content = item.description, created = item.created, created_as_delta = item.created_as_delta(), icon = ContentType.get_icon(item.type), id = item.content_id, label = item.label, owner = context.toDict(item.owner), # REMOVE parent = context.toDict(item.parent), type = item.type, urls = context.toDict({ 'delete': context.url('/workspaces/{wid}/folders/{fid}/{ctype}/{cid}/comments/{commentid}/put_delete'.format(wid = item.workspace_id, fid=item.parent.parent_id, ctype=item.parent.type+'s', cid=item.parent.content_id, commentid=item.content_id)) }) ) if item.type==ContentType.Folder: return Context(CTX.DEFAULT).toDict(item)
def serialize_node_for_thread_list(content: Content, context: Context): if content.type == ContentType.Thread: return DictLikeClass(id=content.content_id, url=ContentType.fill_url(content), label=content.get_label(), status=context.toDict(content.get_status()), folder=context.toDict(content.parent), workspace=context.toDict(content.workspace) if content.workspace else None, comment_nb=len(content.get_comments())) if content.type == ContentType.Folder: return Context(CTX.DEFAULT).toDict(content) raise NotImplementedError
def serialize_node_for_thread_list(content: Content, context: Context): if content.type==ContentType.Thread: return DictLikeClass( id = content.content_id, url=ContentType.fill_url(content), label=content.get_label(), status=context.toDict(content.get_status()), folder=context.toDict(content.parent), workspace=context.toDict(content.workspace) if content.workspace else None, comment_nb=len(content.get_comments()) ) if content.type==ContentType.Folder: return Context(CTX.DEFAULT).toDict(content) raise NotImplementedError
def serialize_item(content: Content, context: Context): if ContentType.Comment==content.type: content = content.parent result = DictLikeClass( id = content.content_id, label = content.label, icon = ContentType.get_icon(content.type), status = context.toDict(content.get_status()), folder = context.toDict(DictLikeClass(id = content.parent.content_id if content.parent else None)), workspace = context.toDict(content.workspace), is_deleted = content.is_deleted, is_archived = content.is_archived, url = context.url('/workspaces/{wid}/folders/{fid}/{ctype}/{cid}'.format(wid = content.workspace_id, fid=content.parent_id, ctype=content.type+'s', cid=content.content_id)), last_action = context.toDict(content.get_last_action()) ) return result
def serialize_item(content: Content, context: Context): if ContentType.Comment==content.type: content = content.parent result = DictLikeClass( id = content.content_id, label = content.label if content.label else content.file_name, icon = ContentType.get_icon(content.type), status = context.toDict(content.get_status()), folder = context.toDict(DictLikeClass(id = content.parent.content_id if content.parent else None)), workspace = context.toDict(content.workspace), is_deleted = content.is_deleted, is_archived = content.is_archived, url = context.url('/workspaces/{wid}/folders/{fid}/{ctype}/{cid}'.format(wid = content.workspace_id, fid=content.parent_id, ctype=content.type+'s', cid=content.content_id)), last_action = context.toDict(content.get_last_action()) ) return result
def _build_email_body(self, mako_template_filepath: str, role: UserRoleInWorkspace, content: Content, actor: User) -> str: """ Build an email body and return it as a string :param mako_template_filepath: the absolute path to the mako template to be used for email body building :param role: the role related to user to whom the email must be sent. The role is required (and not the user only) in order to show in the mail why the user receive the notification :param content: the content item related to the notification :param actor: the user at the origin of the action / notification (for example the one who wrote a comment :param config: the global configuration :return: the built email body as string. In case of multipart email, this method must be called one time for text and one time for html """ logger.debug( self, 'Building email content from MAKO template {}'.format( mako_template_filepath)) template = Template(filename=mako_template_filepath) # TODO - D.A. - 2014-11-06 - move this # Import is here for circular import problem import tracim.lib.helpers as helpers dictified_item = Context( CTX.EMAIL_NOTIFICATION, self._global_config.WEBSITE_BASE_URL).toDict(content) dictified_actor = Context(CTX.DEFAULT).toDict(actor) main_title = dictified_item.label content_intro = '' content_text = '' call_to_action_text = '' action = content.get_last_action().id if ActionDescription.COMMENT == action: content_intro = l_( '<span id="content-intro-username">{}</span> added a comment:' ).format(actor.display_name) content_text = content.description call_to_action_text = l_('Answer') elif ActionDescription.CREATION == action: # Default values (if not overriden) content_text = content.description call_to_action_text = l_('View online') if ContentType.Thread == content.type: call_to_action_text = l_('Answer') content_intro = l_( '<span id="content-intro-username">{}</span> started a thread entitled:' ).format(actor.display_name) content_text = '<p id="content-body-intro">{}</p>'.format(content.label) + \ content.get_last_comment_from(actor).description elif ContentType.File == content.type: content_intro = l_( '<span id="content-intro-username">{}</span> added a file entitled:' ).format(actor.display_name) if content.description: content_text = content.description else: content_text = '<span id="content-body-only-title">{}</span>'.format( content.label) elif ContentType.Page == content.type: content_intro = l_( '<span id="content-intro-username">{}</span> added a page entitled:' ).format(actor.display_name) content_text = '<span id="content-body-only-title">{}</span>'.format( content.label) elif ActionDescription.REVISION == action: content_text = content.description call_to_action_text = l_('View online') if ContentType.File == content.type: content_intro = l_( '<span id="content-intro-username">{}</span> uploaded a new revision.' ).format(actor.display_name) content_text = '' elif ContentType.Page == content.type: content_intro = l_( '<span id="content-intro-username">{}</span> updated this page.' ).format(actor.display_name) previous_revision = content.get_previous_revision() title_diff = '' if previous_revision.label != content.label: title_diff = htmldiff(previous_revision.label, content.label) content_text = str(l_('<p id="content-body-intro">Here is an overview of the changes:</p>'))+ \ title_diff + \ htmldiff(previous_revision.description, content.description) elif ContentType.Thread == content.type: content_intro = l_( '<span id="content-intro-username">{}</span> updated the thread description.' ).format(actor.display_name) previous_revision = content.get_previous_revision() title_diff = '' if previous_revision.label != content.label: title_diff = htmldiff(previous_revision.label, content.label) content_text = str(l_('<p id="content-body-intro">Here is an overview of the changes:</p>'))+ \ title_diff + \ htmldiff(previous_revision.description, content.description) # elif ContentType.Thread == content.type: # content_intro = l_('<span id="content-intro-username">{}</span> updated this page.').format(actor.display_name) # previous_revision = content.get_previous_revision() # content_text = l_('<p id="content-body-intro">Here is an overview of the changes:</p>')+ \ # htmldiff(previous_revision.description, content.description) elif ActionDescription.EDITION == action: call_to_action_text = l_('View online') if ContentType.File == content.type: content_intro = l_( '<span id="content-intro-username">{}</span> updated the file description.' ).format(actor.display_name) content_text = '<p id="content-body-intro">{}</p>'.format(content.get_label()) + \ content.description elif ActionDescription.STATUS_UPDATE == action: call_to_action_text = l_('View online') intro_user_msg = l_('<span id="content-intro-username">{}</span> ' 'updated the following status:') content_intro = intro_user_msg.format(actor.display_name) intro_body_msg = '<p id="content-body-intro">{}: {}</p>' content_text = intro_body_msg.format( content.get_label(), content.get_status().label, ) if '' == content_intro and content_text == '': # Skip notification, but it's not normal logger.error( self, 'A notification is being sent but no content. ' 'Here are some debug informations: [content_id: {cid}]' '[action: {act}][author: {actor}]'.format( cid=content.content_id, act=action, actor=actor)) raise ValueError('Unexpected empty notification') # Import done here because cyclic import from tracim.config.app_cfg import CFG body_content = template.render( base_url=self._global_config.WEBSITE_BASE_URL, _=l_, h=helpers, user_display_name=role.user.display_name, user_role_label=role.role_as_label(), workspace_label=role.workspace.label, content_intro=content_intro, content_text=content_text, main_title=main_title, call_to_action_text=call_to_action_text, result=DictLikeClass(item=dictified_item, actor=dictified_actor), CFG=CFG.get_instance(), ) return body_content
def _build_email_body(self, mako_template_filepath: str, role: UserRoleInWorkspace, content: Content, actor: User) -> str: """ Build an email body and return it as a string :param mako_template_filepath: the absolute path to the mako template to be used for email body building :param role: the role related to user to whom the email must be sent. The role is required (and not the user only) in order to show in the mail why the user receive the notification :param content: the content item related to the notification :param actor: the user at the origin of the action / notification (for example the one who wrote a comment :param config: the global configuration :return: the built email body as string. In case of multipart email, this method must be called one time for text and one time for html """ logger.debug(self, 'Building email content from MAKO template {}'.format(mako_template_filepath)) template = Template(filename=mako_template_filepath) # TODO - D.A. - 2014-11-06 - move this # Import is here for circular import problem import tracim.lib.helpers as helpers dictified_item = Context(CTX.EMAIL_NOTIFICATION, self._global_config.WEBSITE_BASE_URL).toDict(content) dictified_actor = Context(CTX.DEFAULT).toDict(actor) main_title = dictified_item.label content_intro = '' content_text = '' call_to_action_text = '' action = content.get_last_action().id if ActionDescription.COMMENT == action: content_intro = l_('<span id="content-intro-username">{}</span> added a comment:').format(actor.display_name) content_text = content.description call_to_action_text = l_('Answer') elif ActionDescription.CREATION == action: # Default values (if not overriden) content_text = content.description call_to_action_text = l_('View online') if ContentType.Thread == content.type: call_to_action_text = l_('Answer') content_intro = l_('<span id="content-intro-username">{}</span> started a thread entitled:').format(actor.display_name) content_text = '<p id="content-body-intro">{}</p>'.format(content.label) + \ content.get_last_comment_from(actor).description elif ContentType.File == content.type: content_intro = l_('<span id="content-intro-username">{}</span> added a file entitled:').format(actor.display_name) if content.description: content_text = content.description else: content_text = '<span id="content-body-only-title">{}</span>'.format(content.label) elif ContentType.Page == content.type: content_intro = l_('<span id="content-intro-username">{}</span> added a page entitled:').format(actor.display_name) content_text = '<span id="content-body-only-title">{}</span>'.format(content.label) elif ActionDescription.REVISION == action: content_text = content.description call_to_action_text = l_('View online') if ContentType.File == content.type: content_intro = l_('<span id="content-intro-username">{}</span> uploaded a new revision.').format(actor.display_name) content_text = '' elif ContentType.Page == content.type: content_intro = l_('<span id="content-intro-username">{}</span> updated this page.').format(actor.display_name) previous_revision = content.get_previous_revision() title_diff = '' if previous_revision.label != content.label: title_diff = htmldiff(previous_revision.label, content.label) content_text = str(l_('<p id="content-body-intro">Here is an overview of the changes:</p>'))+ \ title_diff + \ htmldiff(previous_revision.description, content.description) elif ContentType.Thread == content.type: content_intro = l_('<span id="content-intro-username">{}</span> updated the thread description.').format(actor.display_name) previous_revision = content.get_previous_revision() title_diff = '' if previous_revision.label != content.label: title_diff = htmldiff(previous_revision.label, content.label) content_text = str(l_('<p id="content-body-intro">Here is an overview of the changes:</p>'))+ \ title_diff + \ htmldiff(previous_revision.description, content.description) # elif ContentType.Thread == content.type: # content_intro = l_('<span id="content-intro-username">{}</span> updated this page.').format(actor.display_name) # previous_revision = content.get_previous_revision() # content_text = l_('<p id="content-body-intro">Here is an overview of the changes:</p>')+ \ # htmldiff(previous_revision.description, content.description) elif ActionDescription.EDITION == action: call_to_action_text = l_('View online') if ContentType.File == content.type: content_intro = l_('<span id="content-intro-username">{}</span> updated the file description.').format(actor.display_name) content_text = '<p id="content-body-intro">{}</p>'.format(content.get_label()) + \ content.description elif ActionDescription.STATUS_UPDATE == action: call_to_action_text = l_('View online') intro_user_msg = l_( '<span id="content-intro-username">{}</span> ' 'updated the following status:' ) content_intro = intro_user_msg.format(actor.display_name) intro_body_msg = '<p id="content-body-intro">{}: {}</p>' content_text = intro_body_msg.format( content.get_label(), content.get_status().label, ) if '' == content_intro and content_text == '': # Skip notification, but it's not normal logger.error( self, 'A notification is being sent but no content. ' 'Here are some debug informations: [content_id: {cid}]' '[action: {act}][author: {actor}]'.format( cid=content.content_id, act=action, actor=actor ) ) raise ValueError('Unexpected empty notification') # Import done here because cyclic import from tracim.config.app_cfg import CFG body_content = template.render( base_url=self._global_config.WEBSITE_BASE_URL, _=l_, h=helpers, user_display_name=role.user.display_name, user_role_label=role.role_as_label(), workspace_label=role.workspace.label, content_intro=content_intro, content_text=content_text, main_title=main_title, call_to_action_text=call_to_action_text, result = DictLikeClass(item=dictified_item, actor=dictified_actor), CFG=CFG.get_instance(), ) return body_content
def serialize_content_for_workspace_and_folder(content: Content, context: Context): thread_nb_all = content.get_child_nb(ContentType.Thread) thread_nb_open = content.get_child_nb(ContentType.Thread) ticket_nb_all = content.get_child_nb(ContentType.Ticket) ticket_nb_open = content.get_child_nb(ContentType.Ticket) task_nb_all = content.get_child_nb(ContentType.Task) task_nb_open = content.get_child_nb(ContentType.Task) file_nb_all = content.get_child_nb(ContentType.File) file_nb_open = content.get_child_nb(ContentType.File) folder_nb_all = content.get_child_nb(ContentType.Folder) folder_nb_open = content.get_child_nb(ContentType.Folder) page_nb_all = content.get_child_nb(ContentType.Page) page_nb_open = content.get_child_nb(ContentType.Page) content_nb_all = thread_nb_all +\ thread_nb_open +\ file_nb_all +\ file_nb_open +\ folder_nb_all +\ folder_nb_open +\ page_nb_all +\ page_nb_open result = None if content.type==ContentType.Folder: allowed_content = DictLikeClass(content.properties['allowed_content']), result = DictLikeClass( id=content.content_id, label=content.label, created=content.created, updated=content.last_revision.updated, last_modification_author=context.toDict(content.last_revision.owner), revision_nb=len(content.revisions), workspace=context.toDict(content.workspace), allowed_content=DictLikeClass(content.properties['allowed_content']), allowed_content_types=context.toDict(content.get_allowed_content_types()), selected_revision='latest', status=context.toDict(content.get_status()), owner=context.toDict(content.owner), thread_nb=DictLikeClass(all=thread_nb_all, open=thread_nb_open), file_nb=DictLikeClass(all=file_nb_all, open=file_nb_open), folder_nb=DictLikeClass(all=folder_nb_all, open=folder_nb_open), page_nb=DictLikeClass(all=page_nb_all, open=page_nb_open), task_nb=DictLikeClass(all=task_nb_all, open=task_nb_open), ticket_nb=DictLikeClass(all=ticket_nb_all, open=ticket_nb_open), content_nb=DictLikeClass(all = content_nb_all), is_archived=content.is_archived, is_deleted=content.is_deleted, is_editable=content.is_editable, ) elif content.type==ContentType.Page: result = DictLikeClass( id = content.content_id, label = content.label, created = content.created, workspace = context.toDict(content.workspace), owner = DictLikeClass( id = content.owner.user_id, name = content.owner.get_display_name() ), status = DictLikeClass(id='', label=''), #FIXME - EXPORT DATA ) return result