Exemplo n.º 1
0
def anon_serialize_ahmia(store, language=GLSetting.memory_copy.default_language):
    """
    Request reaches only if ahmia is enabled
    """
    node = store.find(models.Node).one()

    mo = Rosetta(node.localized_strings)
    mo.acquire_storm_object(node)

    ret_dict = {
        "title": node.name,
        "description": mo.dump_localized_attr('description', language),

        # TODO support tags/keyword in Node.
        "keywords": "%s (GlobaLeaks instance)" % node.name,
        "relation": node.public_site,

        # TODO ask Ahmia to support a list of languages
        "language": node.default_language,

        # TODO say to the admin that its email will be public
        "contactInformation": u'',
        "type": "GlobaLeaks"
    }

    return ret_dict
Exemplo n.º 2
0
def receiver_serialize_internal_tip(internaltip, language):

    ret_dict = {
        'context_id': internaltip.context.id,
        'creation_date' : datetime_to_ISO8601(internaltip.creation_date),
        'expiration_date' : datetime_to_ISO8601(internaltip.expiration_date),
        'download_limit' : internaltip.download_limit,
        'access_limit' : internaltip.access_limit,
        'mark' : internaltip.mark,
        'wb_steps' : internaltip.wb_steps,
        'global_delete' : False,
        # this field "inform" the receiver of the new expiration date that can
        # be set, only if PUT with extend = True is updated
        'potential_expiration_date' : \
                datetime_to_ISO8601(utc_future_date(seconds=internaltip.context.tip_timetolive)),
        'extend' : False,
        'enable_private_messages': internaltip.context.enable_private_messages,
    }

    # context_name and context_description are localized fields
    mo = Rosetta(internaltip.context.localized_strings)
    mo.acquire_storm_object(internaltip.context)
    for attr in ['name', 'description']:
        key = "context_%s" % attr
        ret_dict[key] = mo.dump_localized_attr(attr, language)

    return ret_dict
Exemplo n.º 3
0
def anon_serialize_ahmia(store, language):
    """
    Serialize Ahmia.fi descriptor.
    """
    node = store.find(models.Node).one()

    mo = Rosetta(node.localized_strings)
    mo.acquire_storm_object(node)

    ret_dict = {
        "title": node.name,
        "description": mo.dump_localized_attr('description', language),

        # TODO support tags/keyword in Node.
        "keywords": "%s (GlobaLeaks instance)" % node.name,
        "relation": node.public_site,

        # TODO ask Ahmia to support a list of languages
        "language": node.default_language,

        # TODO say to the admin that its email will be public
        "contactInformation": u'',
        "type": "GlobaLeaks"
    }

    return ret_dict
Exemplo n.º 4
0
def collect_tip_overview(store, language):
    tip_description_list = []

    all_itips = store.find(models.InternalTip)
    for itip in all_itips:
        tip_description = {
            'id': itip.id,
            'creation_date': datetime_to_ISO8601(itip.creation_date),
            'creation_lifetime': datetime_to_ISO8601(itip.creation_date),
            'expiration_date': datetime_to_ISO8601(itip.expiration_date),
            'context_id': itip.context_id,
            'receivertips': [],
            'internalfiles': [],
            'comments': [],
            'wb_access_counter': 0,
            'wb_last_access': u'Never'
        }

        mo = Rosetta(itip.context.localized_strings)
        mo.acquire_storm_object(itip.context)
        tip_description['context_name'] = mo.dump_localized_attr('name', language)

        for rtip in itip.receivertips:
            tip_description['receivertips'].append({
                'access_counter': rtip.access_counter,
                'notification_date': datetime_to_ISO8601(rtip.notification_date),
                # 'creation_date': datetime_to_ISO8601(rtip.creation_date),
                'receiver_id': rtip.receiver.id,
                'receiver_username': rtip.receiver.user.username,
                'receiver_name': rtip.receiver.name,
                # last_access censored willingly
            })

        for ifile in itip.internalfiles:
            tip_description['internalfiles'].append({
                'name': ifile.name,
                'size': ifile.size,
                'content_type': ifile.content_type
            })

        for comment in itip.comments:
            tip_description['comments'].append({
                'type': comment.type,
                'lifetime': datetime_to_ISO8601(comment.creation_date),
            })

        # whistleblower tip has not a reference from itip, then:
        wbtip = store.find(models.WhistleblowerTip,
                           models.WhistleblowerTip.internaltip_id == itip.id).one()

        if wbtip is not None:
            tip_description.update({
                'wb_access_counter': wbtip.access_counter,
                'wb_last_access': datetime_to_ISO8601(wbtip.last_access)
            })

        tip_description_list.append(tip_description)

    return tip_description_list
Exemplo n.º 5
0
def get_receivertip_list(store, receiver_id, language):
    rtiplist = store.find(ReceiverTip, ReceiverTip.receiver_id == receiver_id)
    rtiplist.order_by(Desc(ReceiverTip.creation_date))

    node = store.find(Node).one()

    rtip_summary_list = []

    for rtip in rtiplist:

        can_postpone_expiration = (node.can_postpone_expiration or
                                   rtip.internaltip.context.can_postpone_expiration or
                                   rtip.receiver.can_postpone_expiration)

        can_delete_submission = (node.can_delete_submission or
                                 rtip.internaltip.context.can_delete_submission or
                                 rtip.receiver.can_delete_submission)

        rfiles_n = store.find(ReceiverFile,
                              (ReceiverFile.internaltip_id == rtip.internaltip.id,
                               ReceiverFile.receiver_id == receiver_id)).count()

        message_counter = store.find(Message,
                                     Message.receivertip_id == rtip.id).count()

        single_tip_sum = dict({
            'id': rtip.id,
            'creation_date': datetime_to_ISO8601(rtip.creation_date),
            'last_access': datetime_to_ISO8601(rtip.last_access),
            'expiration_date': datetime_to_ISO8601(rtip.internaltip.expiration_date),
            'access_counter': rtip.access_counter,
            'file_counter': rfiles_n,
            'comment_counter': rtip.internaltip.comments.count(),
            'message_counter': message_counter,
            'can_postpone_expiration': can_postpone_expiration,
            'can_delete_submission': can_delete_submission,
        })

        mo = Rosetta(rtip.internaltip.context.localized_strings)
        mo.acquire_storm_object(rtip.internaltip.context)
        single_tip_sum["context_name"] = mo.dump_localized_attr('name', language)

        preview_data = []

        for s in rtip.internaltip.wb_steps:
            for f in s['children']:
                if f['preview']:
                    preview_data.append(f)

        single_tip_sum.update({'preview': preview_data})
        rtip_summary_list.append(single_tip_sum)

    return rtip_summary_list
Exemplo n.º 6
0
def wb_serialize_tip(internaltip, language):
    ret_dict = {
        'id': internaltip.id,
        'context_id': internaltip.context.id,
        'creation_date': datetime_to_ISO8601(internaltip.creation_date),
        'last_activity': datetime_to_ISO8601(internaltip.creation_date),
        'expiration_date': datetime_to_ISO8601(internaltip.expiration_date),
        'wb_steps': internaltip.wb_steps,
        'enable_private_messages': internaltip.context.enable_private_messages,
        'show_receivers': internaltip.context.show_receivers,
    }

    # context_name and context_description are localized fields
    mo = Rosetta(internaltip.context.localized_strings)
    mo.acquire_storm_object(internaltip.context)
    for attr in ['name', 'description']:
        key = "context_%s" % attr
        ret_dict[key] = mo.dump_localized_attr(attr, language)

    return ret_dict
Exemplo n.º 7
0
def anon_serialize_ahmia(store, language):
    """
    Serialize Ahmia.fi descriptor.
    """
    node = store.find(models.Node).one()

    mo = Rosetta(node.localized_strings)
    mo.acquire_storm_object(node)

    ret_dict = {
        'title': node.name,
        'description': mo.dump_localized_attr('description', language),
        'keywords': '%s (GlobaLeaks instance)' % node.name,
        'relation': node.public_site,
        'language': node.default_language,
        'contactInformation': u'',
        'type': 'GlobaLeaks'
    }

    return ret_dict
Exemplo n.º 8
0
def wb_serialize_tip(internaltip, language):
    ret_dict = {
        'context_id': internaltip.context.id,
        'creation_date': datetime_to_ISO8601(internaltip.creation_date),
        'last_activity': datetime_to_ISO8601(internaltip.creation_date),
        'expiration_date': datetime_to_ISO8601(internaltip.expiration_date),
        'download_limit': internaltip.download_limit,
        'access_limit': internaltip.access_limit,
        'mark': internaltip.mark,
        'wb_steps': internaltip.wb_steps,
        'enable_private_messages': internaltip.context.enable_private_messages,
        'show_receivers': internaltip.context.show_receivers,
    }

    # context_name and context_description are localized fields
    mo = Rosetta(internaltip.context.localized_strings)
    mo.acquire_storm_object(internaltip.context)
    for attr in ['name', 'description']:
        key = "context_%s" % attr
        ret_dict[key] = mo.dump_localized_attr(attr, language)

    return ret_dict
Exemplo n.º 9
0
def get_receiver_list_receiver(store, user_id, tip_id, language):

    rtip = access_tip(store, user_id, tip_id)

    receiver_list = []
    for rtip in rtip.internaltip.receivertips:

        receiver_desc = {
            "gpg_key_status": rtip.receiver.gpg_key_status,
            "can_delete_submission": rtip.receiver.can_delete_submission,
            "name": unicode(rtip.receiver.name),
            "receiver_id": unicode(rtip.receiver.id),
            "access_counter": rtip.access_counter,
        }

        mo = Rosetta(rtip.receiver.localized_strings)
        mo.acquire_storm_object(rtip.receiver)
        receiver_desc["description"] = mo.dump_localized_attr(
            "description", language)

        receiver_list.append(receiver_desc)

    return receiver_list
Exemplo n.º 10
0
def get_receiver_list_wb(store, wb_tip_id, language):
    """
    @return:
        This function contain the serialization of the receiver, this function is
        used only by /wbtip/receivers API

        The returned struct contain information on read/unread messages
    """

    wb_tip = store.find(WhistleblowerTip,
                        WhistleblowerTip.id == unicode(wb_tip_id)).one()

    if not wb_tip:
        raise errors.TipReceiptNotFound

    # This part of code is used only in the short time between the first
    # WB access and the delivery schedule. In this moment
    # wb_tip.internaltips.receivertips is EMPTY, therefore we force
    # the Receivers values below
    if not wb_tip.internaltip.receivertips.count():
        receiver_list = []

        log.debug("Early access from the WB to the Tip (creation_date: %s UTC),"\
                  " Receiver not yet present: fallback on receiver list" %
                  datetime_to_pretty_str(wb_tip.creation_date))

        for receiver in wb_tip.internaltip.receivers:

            # This is the reduced version of Receiver serialization
            receiver_desc = {
                "name": receiver.name,
                "id": receiver.id,
                "gpg_key_status": receiver.gpg_key_status,
                "access_counter": 0,
                "unread_messages": 0,
                "read_messages": 0,
                "your_messages": 0,
                "creation_date": datetime_to_ISO8601(datetime_now()),
                # XXX ReceiverTip last activity ?
            }

            mo = Rosetta(receiver.localized_strings)
            mo.acquire_storm_object(receiver)
            receiver_desc["description"] = mo.dump_localized_attr(
                "description", language)

            receiver_list.append(receiver_desc)

        return receiver_list
    else:
        receiver_list = []
        for rtip in wb_tip.internaltip.receivertips:

            your_messages = store.find(
                Message, Message.receivertip_id == rtip.id,
                Message.type == u'whistleblower').count()

            unread_messages = store.find(Message,
                                         Message.receivertip_id == rtip.id,
                                         Message.type == u'receiver',
                                         Message.visualized == False).count()

            read_messages = store.find(Message,
                                       Message.receivertip_id == rtip.id,
                                       Message.type == u'receiver',
                                       Message.visualized == True).count()

            # if you change something here, check also 20 lines before!
            receiver_desc = {
                "name": rtip.receiver.name,
                "id": rtip.receiver.id,
                "access_counter": rtip.access_counter,
                "unread_messages": unread_messages,
                "read_messages": read_messages,
                "your_messages": your_messages,
                "creation_date": datetime_to_ISO8601(datetime_now()),
                # XXX ReceiverTip last activity ?
            }

            mo = Rosetta(rtip.receiver.localized_strings)
            mo.acquire_storm_object(rtip.receiver)
            receiver_desc["description"] = mo.dump_localized_attr(
                "description", language)

            receiver_list.append(receiver_desc)

        return receiver_list
Exemplo n.º 11
0
def collect_tip_overview(store, language):
    tip_description_list = []
    all_itips = store.find(models.InternalTip)
    all_itips.order_by(Desc(models.InternalTip.creation_date))

    for itip in all_itips:
        tip_description = {
            "id": itip.id,
            "creation_date": datetime_to_ISO8601(itip.creation_date),
            "creation_lifetime": datetime_to_ISO8601(itip.creation_date),
            "expiration_date": datetime_to_ISO8601(itip.expiration_date),
            "context_id": itip.context_id,
            "status": itip.mark,
            "receivertips": [],
            "internalfiles": [],
            "comments": [],
        }

        mo = Rosetta(itip.context.localized_strings)
        mo.acquire_storm_object(itip.context)
        tip_description['context_name'] = mo.dump_localized_attr(
            'name', language)

        # strip uncompleted submission, until GLClient open new submission
        # also if no data has been supply
        if itip.mark == u'submission':
            continue

        for rtip in itip.receivertips:
            tip_description['receivertips'].append({
                'access_counter':
                rtip.access_counter,
                'notification_date':
                datetime_to_ISO8601(rtip.notification_date),
                # 'creation_date': datetime_to_ISO8601(rtip.creation_date),
                'status':
                rtip.mark,
                'receiver_id':
                rtip.receiver.id,
                'receiver_username':
                rtip.receiver.user.username,
                'receiver_name':
                rtip.receiver.name,
                # last_access censored willingly
            })

        for ifile in itip.internalfiles:
            tip_description['internalfiles'].append({
                'name':
                ifile.name,
                'size':
                ifile.size,
                'status':
                ifile.mark,
                'content_type':
                ifile.content_type
            })

        for comment in itip.comments:
            tip_description['comments'].append({
                'type':
                comment.type,
                'lifetime':
                datetime_to_ISO8601(comment.creation_date),
            })

        # whistleblower tip has not a reference from itip, then:
        wbtip = store.find(
            models.WhistleblowerTip,
            models.WhistleblowerTip.internaltip_id == itip.id).one()

        if wbtip is not None:
            tip_description.update({
                'wb_access_counter':
                wbtip.access_counter,
                'wb_last_access':
                datetime_to_ISO8601(wbtip.last_access)
            })
        else:
            tip_description.update({
                'wb_access_counter': u'Deleted',
                'wb_last_access': u'Never'
            })

        tip_description_list.append(tip_description)

    return tip_description_list
Exemplo n.º 12
0
def get_receiver_tip_list(store, receiver_id, language=GLSetting.memory_copy.default_language):

    rtiplist = store.find(ReceiverTip, ReceiverTip.receiver_id == receiver_id)
    rtiplist.order_by(Desc(ReceiverTip.creation_date))

    node = store.find(Node).one()

    rtip_summary_list = []

    for rtip in rtiplist:

        postpone_superpower = (node.postpone_superpower or
                               rtip.internaltip.context.postpone_superpower or
                               rtip.receiver.postpone_superpower)

        can_delete_submission = (node.can_delete_submission or
                                 rtip.internaltip.context.can_delete_submission or
                                 rtip.receiver.can_delete_submission)

        rfiles_n = store.find(ReceiverFile,
            (ReceiverFile.internaltip_id == rtip.internaltip.id,
             ReceiverFile.receiver_id == receiver_id)).count()

        your_messages = store.find(Message,
                                   Message.receivertip_id == rtip.id,
                                   Message.type == u'receiver').count()

        unread_messages = store.find(Message,
                                     Message.receivertip_id == rtip.id,
                                     Message.type == u'whistleblower',
                                     Message.visualized == False).count()

        read_messages = store.find(Message,
                                   Message.receivertip_id == rtip.id,
                                   Message.type == u'whistleblower',
                                   Message.visualized == True).count()

        single_tip_sum = dict({
            'id' : rtip.id,
            'creation_date' : datetime_to_ISO8601(rtip.creation_date),
            'last_access' : datetime_to_ISO8601(rtip.last_access),
            'expiration_date' : datetime_to_ISO8601(rtip.internaltip.expiration_date),
            'access_counter': rtip.access_counter,
            'files_number': rfiles_n,
            'comments_number': rtip.internaltip.comments.count(),
            'unread_messages' : unread_messages,
            'read_messages' : read_messages,
            'your_messages' : your_messages,
            'postpone_superpower': postpone_superpower,
            'can_delete_submission': can_delete_submission,
        })

        mo = Rosetta(rtip.internaltip.context.localized_strings)
        mo.acquire_storm_object(rtip.internaltip.context)
        single_tip_sum["context_name"] = mo.dump_localized_attr('name', language)

        preview_data = []

        for s in rtip.internaltip.wb_steps:
            for f in s['children']:
                if f['preview']:
                    preview_data.append(f)

        single_tip_sum.update({ 'preview' : preview_data })
        rtip_summary_list.append(single_tip_sum)

    return rtip_summary_list
Exemplo n.º 13
0
 def localize_and_append_receiver(receiver, receiver_desc):
     mo = Rosetta(receiver.localized_strings)
     mo.acquire_storm_object(receiver)
     receiver_desc["description"] = mo.dump_localized_attr("description", language)
     receiver_list.append(receiver_desc)
Exemplo n.º 14
0
def get_receiver_list_wb(store, wb_tip_id, language=GLSetting.memory_copy.default_language):
    """
    @return:
        This function contain the serialization of the receiver, this function is
        used only by /wbtip/receivers API

        The returned struct contain information on read/unread messages
    """

    wb_tip = store.find(WhistleblowerTip,
                        WhistleblowerTip.id == unicode(wb_tip_id)).one()

    if not wb_tip:
        raise errors.TipReceiptNotFound

    # This part of code is used only in the short time between the first
    # WB access and the delivery schedule. In this moment
    # wb_tip.internaltips.receivertips is EMPTY, therefore we force
    # the Receivers values below
    if not wb_tip.internaltip.receivertips.count():
        receiver_list = []

        log.debug("Early access from the WB to the Tip (creation_date: %s UTC),"\
                  " Receiver not yet present: fallback on receiver list" %
                  datetime_to_pretty_str(wb_tip.creation_date))

        for receiver in wb_tip.internaltip.receivers:

            # This is the reduced version of Receiver serialization
            receiver_desc = {
                "name": receiver.name,
                "id": receiver.id,
                "gpg_key_status": receiver.gpg_key_status,
                "access_counter" : 0,
                "unread_messages" : 0,
                "read_messages" : 0,
                "your_messages" : 0,
                "creation_date" : datetime_to_ISO8601(datetime_now()),
                # XXX ReceiverTip last activity ?
            }

            mo = Rosetta(receiver.localized_strings)
            mo.acquire_storm_object(receiver)
            receiver_desc["description"] = mo.dump_localized_attr("description", language)

            receiver_list.append(receiver_desc)

        return receiver_list
    else:
        receiver_list = []
        for rtip in wb_tip.internaltip.receivertips:


            your_messages = store.find(Message,
                                       Message.receivertip_id == rtip.id,
                                       Message.type == u'whistleblower').count()

            unread_messages = store.find(Message,
                                         Message.receivertip_id == rtip.id,
                                         Message.type == u'receiver',
                                         Message.visualized == False).count()

            read_messages = store.find(Message,
                                       Message.receivertip_id == rtip.id,
                                       Message.type == u'receiver',
                                       Message.visualized == True).count()

            # if you change something here, check also 20 lines before!
            receiver_desc = {
                "name": rtip.receiver.name,
                "id": rtip.receiver.id,
                "access_counter" : rtip.access_counter,
                "unread_messages" : unread_messages,
                "read_messages" : read_messages,
                "your_messages" : your_messages,
                "creation_date" : datetime_to_ISO8601(datetime_now()),
                # XXX ReceiverTip last activity ?
            }

            mo = Rosetta(rtip.receiver.localized_strings)
            mo.acquire_storm_object(rtip.receiver)
            receiver_desc["description"] = mo.dump_localized_attr("description", language)

            receiver_list.append(receiver_desc)

        return receiver_list
Exemplo n.º 15
0
def get_receiver_tip_list(store, receiver_id, language):

    rtiplist = store.find(ReceiverTip, ReceiverTip.receiver_id == receiver_id)
    rtiplist.order_by(Desc(ReceiverTip.creation_date))

    node = store.find(Node).one()

    rtip_summary_list = []

    for rtip in rtiplist:

        postpone_superpower = (node.postpone_superpower or
                               rtip.internaltip.context.postpone_superpower or
                               rtip.receiver.postpone_superpower)

        can_delete_submission = (node.can_delete_submission or
                                 rtip.internaltip.context.can_delete_submission or
                                 rtip.receiver.can_delete_submission)

        rfiles_n = store.find(ReceiverFile,
            (ReceiverFile.internaltip_id == rtip.internaltip.id,
             ReceiverFile.receiver_id == receiver_id)).count()

        your_messages = store.find(Message,
                                   Message.receivertip_id == rtip.id,
                                   Message.type == u'receiver').count()

        unread_messages = store.find(Message,
                                     Message.receivertip_id == rtip.id,
                                     Message.type == u'whistleblower',
                                     Message.visualized == False).count()

        read_messages = store.find(Message,
                                   Message.receivertip_id == rtip.id,
                                   Message.type == u'whistleblower',
                                   Message.visualized == True).count()

        single_tip_sum = dict({
            'id' : rtip.id,
            'creation_date' : datetime_to_ISO8601(rtip.creation_date),
            'last_access' : datetime_to_ISO8601(rtip.last_access),
            'expiration_date' : datetime_to_ISO8601(rtip.internaltip.expiration_date),
            'access_counter': rtip.access_counter,
            'files_number': rfiles_n,
            'comments_number': rtip.internaltip.comments.count(),
            'unread_messages' : unread_messages,
            'read_messages' : read_messages,
            'your_messages' : your_messages,
            'postpone_superpower': postpone_superpower,
            'can_delete_submission': can_delete_submission,
        })

        mo = Rosetta(rtip.internaltip.context.localized_strings)
        mo.acquire_storm_object(rtip.internaltip.context)
        single_tip_sum["context_name"] = mo.dump_localized_attr('name', language)

        preview_data = []

        for s in rtip.internaltip.wb_steps:
            for f in s['children']:
                if f['preview']:
                    preview_data.append(f)

        single_tip_sum.update({ 'preview' : preview_data })
        rtip_summary_list.append(single_tip_sum)

    return rtip_summary_list
Exemplo n.º 16
0
def collect_tip_overview(store, language=GLSetting.memory_copy.default_language):

    tip_description_list = []
    all_itips = store.find(models.InternalTip)
    all_itips.order_by(Desc(models.InternalTip.creation_date))

    for itip in all_itips:
        tip_description = {
            "id": itip.id,
            "creation_date": datetime_to_ISO8601(itip.creation_date),
            "creation_lifetime": datetime_to_ISO8601(itip.creation_date),
            "expiration_date": datetime_to_ISO8601(itip.expiration_date),
            "context_id": itip.context_id,
            "status": itip.mark,
            "receivertips": [],
            "internalfiles": [],
            "comments": [],
        }

        mo = Rosetta(itip.context.localized_strings)
        mo.acquire_storm_object(itip.context)
        tip_description['context_name'] = mo.dump_localized_attr('name', language)

        # strip uncompleted submission, until GLClient open new submission
        # also if no data has been supply
        if itip.mark == models.InternalTip._marker[0]:
            continue

        for rtip in itip.receivertips:
            tip_description['receivertips'].append({
                'access_counter': rtip.access_counter,
                'notification_date': datetime_to_ISO8601(rtip.notification_date),
                # 'creation_date': datetime_to_ISO8601(rtip.creation_date),
                'status': rtip.mark,
                'receiver_id': rtip.receiver.id,
                'receiver_username': rtip.receiver.user.username,
                'receiver_name': rtip.receiver.name,
                # last_access censored willingly
            })

        for ifile in itip.internalfiles:
            tip_description['internalfiles'].append({
                'name': ifile.name,
                'size': ifile.size,
                'status': ifile.mark,
                'content_type': ifile.content_type
            })

        for comment in itip.comments:
            tip_description['comments'].append({
                'type': comment.type,
                'lifetime': datetime_to_ISO8601(comment.creation_date),
            })

        # whistleblower tip has not a reference from itip, then:
        wbtip = store.find(models.WhistleblowerTip,
            models.WhistleblowerTip.internaltip_id == itip.id).one()

        if wbtip is not None:
            tip_description.update({
                'wb_access_counter': wbtip.access_counter,
                'wb_last_access': datetime_to_ISO8601(wbtip.last_access)
            })
        else:
            tip_description.update({
                'wb_access_counter': u'Deleted', 'wb_last_access': u'Never'
            })

        tip_description_list.append(tip_description)

    return tip_description_list