Пример #1
0
def get_others(rels, node):
    ''' other items of the node's type related to something it is related to.
    For example: "Other editions by the editor Joseph H. Peterson"
    :param rels: default relationship list
    :param node: the item node
    :return: customized data for this label
    '''
    label = node['label']
    others = []
    for rel in rels:
        start = rel['start']
        end = rel['end']

        # must be different types of data, and not entities in a grimoire
        if start['label'] != end['label'] and \
                (end['label'] != 'demon' and start['label'] != 'grimoire'):
            # other = "editions"
            other = start if start['label'] != label else end
            other_items = graph.others_of_type(label,
                                               other['props']['uid'],
                                               node['props']['uid'])
            if other_items['nodes']:
                others.append({
                    'title': 'Other %s related to the %s %s' %
                             (helpers.pluralize(label),
                              helpers.format_filter(other['label']),
                              other['props']['identifier']),
                    'data': other_items['nodes']
                })
    return others
Пример #2
0
def get_others(rels, node):
    ''' other items of the node's type related to something it is related to.
    For example: "Other editions by the editor Joseph H. Peterson"
    :param rels: default relationship list
    :param node: the item node
    :return: customized data for this label
    '''
    label = node['label']
    others = []
    for rel in rels:
        start = rel['start']
        end = rel['end']

        # must be different types of data, and not entities in a grimoire
        if start['label'] != end['label'] and \
                (end['label'] != 'demon' and start['label'] != 'grimoire'):
            # other = "editions"
            other = start if start['label'] != label else end
            other_items = graph.others_of_type(label, other['props']['uid'],
                                               node['props']['uid'])
            if other_items['nodes']:
                others.append({
                    'title':
                    'Other %s related to the %s %s' %
                    (helpers.pluralize(label),
                     helpers.format_filter(
                         other['label']), other['props']['identifier']),
                    'data':
                    other_items['nodes']
                })
    return others
Пример #3
0
def entity_item(node, rels):
    ''' entity item page
    :param node: the item node
    :param rels: default relationship list
    :return: customized data for this label
    '''
    data = generic_item(node, rels)

    # removes duplication of two-way sister rels
    rels = [r for r in rels if r['type'] != 'is_a_sister_of' \
            or r['end']['id'] != node['id']]

    data['rels'] = helpers.exclude_rels(data['rels'], [
        'lists', 'teaches', 'skilled_in', 'serves', 'facilitates',
        'appears_like', 'can', 'for'
    ])
    grimoires = extract_rel_list(rels, 'grimoire', 'start') + \
                extract_rel_list(rels, 'book', 'start')
    if grimoires:
        data['sidebar'].append({'title': 'Grimoires', 'data': grimoires})

    outcomes = extract_rel_list_by_type(rels, 'for', 'end')
    if outcomes:
        data['main'].append({'title': 'Powers', 'data': outcomes})

    appearance = extract_rel_list(rels, 'creature', 'end')
    if appearance:
        data['main'].append({
            'title': 'Appearance',
            'data': appearance,
            'many': True
        })

    serves = extract_rel_list_by_type(rels, 'serves', 'end')
    serves = [
        s for s in serves if not s['props']['uid'] == node['props']['uid']
    ]
    if serves:
        data['main'].append({'title': 'Serves', 'data': serves})

    servants = extract_rel_list_by_type(rels, 'serves', 'start')
    servants = [
        s for s in servants if not s['props']['uid'] == node['props']['uid']
    ]
    if servants:
        data['main'].append({'title': 'Servants', 'data': servants})

    if not data['content']:
        content = 'The %s %s appears in %s' % \
                  (helpers.format_filter(node['label']),
                   node['props']['identifier'],
                   format_list(grimoires))
        data['content'] = markdown(content)
    return data
Пример #4
0
def entity_item(node, rels):
    ''' entity item page
    :param node: the item node
    :param rels: default relationship list
    :return: customized data for this label
    '''
    data = generic_item(node, rels)

    # removes duplication of two-way sister rels
    rels = [r for r in rels if r['type'] != 'is_a_sister_of' \
            or r['end']['id'] != node['id']]

    data['rels'] = helpers.exclude_rels(data['rels'], [
        'lists', 'teaches', 'skilled_in', 'serves', 'facilitates',
        'appears_like', 'can', 'for'])
    grimoires = extract_rel_list(rels, 'grimoire', 'start') + \
                extract_rel_list(rels, 'book', 'start')
    if grimoires:
        data['sidebar'].append({'title': 'Grimoires', 'data': grimoires})

    outcomes = extract_rel_list_by_type(rels, 'for', 'end')
    if outcomes:
        data['main'].append({'title': 'Powers', 'data': outcomes})

    appearance = extract_rel_list(rels, 'creature', 'end')
    if appearance:
        data['main'].append({
            'title': 'Appearance',
            'data': appearance, 'many': True})

    serves = extract_rel_list_by_type(rels, 'serves', 'end')
    serves = [s for s in serves if
              not s['props']['uid'] == node['props']['uid']]
    if serves:
        data['main'].append({'title': 'Serves', 'data': serves})

    servants = extract_rel_list_by_type(rels, 'serves', 'start')
    servants = [s for s in servants if
                not s['props']['uid'] == node['props']['uid']]
    if servants:
        data['main'].append({'title': 'Servants', 'data': servants})

    if not data['content']:
        content = 'The %s %s appears in %s' % \
                  (helpers.format_filter(node['label']),
                   node['props']['identifier'],
                   format_list(grimoires))
        data['content'] = markdown(content)
    return data
Пример #5
0
def item(label, uid):
    ''' generic page for an item
    :param label: the desired neo4j label
    :param uid: the human-readable uid of the node
    :return: customized data for this label rendered item page template
    '''

    # load and validate url data
    label = helpers.sanitize(label)
    if not graph.validate_label(label):
        logging.error('Invalid label %s', label)
        return render_template(request.url,
                               'label-404.html',
                               labels=graph.get_labels())

    try:
        data = helpers.get_node(uid)
    except NameError:
        items = graph.get_all(label)
        return render_template(request.url, 'item-404.html',
                               items=items['nodes'],
                               search=graph.search(uid)['nodes'],
                               label=label)

    node = data['node']
    rels = data['rels']

    # ----- page header/metadata
    title = node['props']['identifier']

    # ----- formatted data
    switch = {
        'parent:book': grimoire_item,
        'parent:entity': entity_item,
        'art': art_item,
        'language': language_item,
        'edition': edition_item,
        'publisher': publisher_item,
        'editor': editor_item,
        'default': generic_item,
        'spell': spell_item,
        'talisman': spell_item,
        'parent:ingredient': ingredient_item,
        'outcome': outcome_item
    }

    key = node['parent_label'] if node['parent_label'] in switch else \
          (label if label in switch else 'default')
    item_data = switch[key](node, rels)

    item_data['rels'] = helpers.combine_rels(item_data['rels'])

    # ----- sidebar
    sidebar = []
    related = graph.related(uid, label)
    if related['nodes']:
        sidebar = [{'title': 'Similar %s' % \
                    helpers.capitalize_filter(helpers.pluralize(label)),
                    'data': related['nodes']}]
    sidebar += get_others(data['rels'], node)

    if not item_data['content'] and not item_data['excerpts']:
        item_data['content'] = 'The %s "%s."' % \
                               (helpers.format_filter(label),
                                helpers.unthe(title))

    max_main_length = max([len(i['data']) for i in item_data['main']] + [0])
    default_collapse = len(item_data['main']) > 2 or max_main_length > 30

    return render_template(request.url, 'item.html',
                           data=item_data,
                           title=title,
                           label=label,
                           sidebar=sidebar,
                           default_collapse=default_collapse)
Пример #6
0
def generic_item(node, rels):
    ''' standard item processing
    :param node: the item node
    :param rels: default relationship list
    :return: customized data for this label
    '''
    def format_field(field):
        ''' deal with array data '''
        if isinstance(field, list):
            return [{'text': i} for i in field]
        return [{'text': field}]

    data = {'id': node['id']}

    try:
        data['content'] = markdown(node['props']['content'])
    except AttributeError:
        data['content'] = ''

    # -- build timeline
    events = extract_rel_list(rels, 'event', 'end')
    for event in events:
        event['props']['relevant'] = True
    related = graph.get_related_events(node['props']['uid'])
    related = zip(related['nodes'], related['rels'])
    for rel_item in related:
        event = rel_item[0]
        this = 'this %s' % helpers.format_filter(node['label'])
        rel_type = helpers.format_filter(rel_item[1]['type'])
        if rel_item[1]['start']['props']['uid'] == node['props']['uid']:
            note = '(%s %s %s)' % \
                   (this, rel_type,
                    helpers.unthe(rel_item[1]['end']['props']['identifier']))
        else:
            note = '(%s %s)' % (rel_type, this)
        event['note'] = note
        events.append(event)
    data['timeline'], data['start_date'], \
            data['end_date'] = build_timeline(events)

    excerpts = extract_rel_list_by_type(rels, 'excerpt', 'end')
    for excerpt in excerpts:
        try:
            excerpt['props']['content'] = markdown(excerpt['props']['content'])
        except AttributeError:
            pass
    data['excerpts'] = excerpts

    data['images'] = extract_rel_list_by_type(rels, 'image',
                                              'end', label='image')

    # remove special node types from relationship lists
    remove = ['excerpt', 'event', 'image', 'contains_item']
    data['rels'] = helpers.exclude_rels(rels, remove)

    data['details'] = {k: format_field(node['props'][k]) for k in
                       node['props'] if k not in
                       ['content', 'uid', 'identifier', 'owned',
                        'buy', 'date_precision', 'isbn']}

    data['buy'] = node['props']['buy'] if 'buy' in node['props'] else None

    data['props'] = node['props']
    data['sidebar'] = []
    data['main'] = []
    data['has_details'] = len([d for d in data['details'] if \
                              data['details'][d]]) > 0
    data['link'] = node['link']

    return data
Пример #7
0
def item(label, uid):
    ''' generic page for an item
    :param label: the desired neo4j label
    :param uid: the human-readable uid of the node
    :return: customized data for this label rendered item page template
    '''

    # load and validate url data
    label = helpers.sanitize(label)
    if not graph.validate_label(label):
        logging.error('Invalid label %s', label)
        return render_template(request.url,
                               '404.html',
                               labels=graph.get_labels())

    try:
        data = helpers.get_node(uid)
    except NameError:
        items = graph.get_all(label)
        return render_template(request.url,
                               '404.html',
                               items=items['nodes'],
                               search=graph.search(uid)['nodes'],
                               label=label)

    node = data['node']
    rels = data['rels']

    # ----- page header/metadata
    title = node['props']['identifier']

    # ----- formatted data
    switch = {
        'parent:book': grimoire_item,
        'parent:entity': entity_item,
        'art': art_item,
        'language': language_item,
        'edition': edition_item,
        'publisher': publisher_item,
        'editor': editor_item,
        'default': generic_item,
        'spell': spell_item,
        'talisman': spell_item,
        'parent:ingredient': ingredient_item,
        'outcome': outcome_item
    }

    key = node['parent_label'] if node['parent_label'] in switch else \
          (label if label in switch else 'default')
    item_data = switch[key](node, rels)

    item_data['rels'] = helpers.combine_rels(item_data['rels'])

    # ----- sidebar
    sidebar = []
    related = graph.related(uid, label)
    if related['nodes']:
        sidebar = [{'title': 'Similar %s' % \
                    helpers.capitalize_filter(helpers.pluralize(label)),
                    'data': related['nodes']}]
    sidebar += get_others(data['rels'], node)

    if not item_data['content'] and not item_data['excerpts']:
        item_data['content'] = 'The %s "%s."' % \
                               (helpers.format_filter(label),
                                helpers.unthe(title))

    max_main_length = max([len(i['data']) for i in item_data['main']] + [0])
    default_collapse = len(item_data['main']) > 2 or max_main_length > 30

    return render_template(request.url,
                           'item.html',
                           data=item_data,
                           title=title,
                           label=label,
                           sidebar=sidebar,
                           default_collapse=default_collapse)
Пример #8
0
def generic_item(node, rels):
    ''' standard item processing
    :param node: the item node
    :param rels: default relationship list
    :return: customized data for this label
    '''
    def format_field(field):
        ''' deal with array data '''
        if isinstance(field, list):
            return [{'text': i} for i in field]
        return [{'text': field}]

    data = {'id': node['id']}

    try:
        content = node['props']['content'].encode('ascii', 'xmlcharrefreplace')
        data['content'] = markdown(content)
    except AttributeError:
        data['content'] = ''

    # -- build timeline
    events = extract_rel_list(rels, 'event', 'end')
    for event in events:
        event['props']['relevant'] = True
    related = graph.get_related_events(node['props']['uid'])
    related = zip(related['nodes'], related['rels'])
    for rel_item in related:
        event = rel_item[0]
        this = 'this %s' % helpers.format_filter(node['label'])
        rel_type = helpers.format_filter(rel_item[1]['type'])
        if rel_item[1]['start']['props']['uid'] == node['props']['uid']:
            note = '(%s %s %s)' % \
                   (this, rel_type,
                    helpers.unthe(rel_item[1]['end']['props']['identifier']))
        else:
            note = '(%s %s)' % (rel_type, this)
        event['note'] = note
        events.append(event)
    data['timeline'], data['start_date'], \
            data['end_date'] = build_timeline(events)

    excerpts = extract_rel_list_by_type(rels, 'excerpt', 'end')
    for excerpt in excerpts:
        try:
            excerpt['props']['content'] = markdown(excerpt['props']['content'])
        except AttributeError:
            pass
    data['excerpts'] = excerpts

    data['images'] = extract_rel_list_by_type(rels,
                                              'image',
                                              'end',
                                              label='image')

    # remove special node types from relationship lists
    remove = ['excerpt', 'event', 'image', 'contains_item']
    data['rels'] = helpers.exclude_rels(rels, remove)

    data['details'] = {
        k: format_field(node['props'][k])
        for k in node['props'] if k not in [
            'content', 'uid', 'identifier', 'owned', 'buy', 'date_precision',
            'isbn', 'full_version'
        ]
    }

    if 'full_version' in node['props']:
        data['full_version'] = node['props']['full_version']

    data['buy'] = node['props']['buy'] if 'buy' in node['props'] else None

    data['props'] = node['props']
    data['sidebar'] = []
    data['main'] = []
    data['has_details'] = len([d for d in data['details'] if \
                              data['details'][d]]) > 0
    data['link'] = node['link']

    return data