def chord_diagram(request):
    """Display a circular chord diagram of the Belfast Group network.

    If a :class:`~django.contrib.flatpages.models.FlatPage` is found for
    this url, it is passed to the template to include in display.
    """
    fpage = get_flatpage(request)
    return render(request, "network/chord.html", {"flatpage": fpage})
def group_people(request, mode="egograph"):
    """Display a force-directed graph of people associated with the
    Belfast Group.

    :param mode: egograph: display people directly connected to the
       Belfast Group; groupsheet-model display a network model generated
       from information about the Group sheets.

    If a :class:`~django.contrib.flatpages.models.FlatPage` is found for
    this url, it is passed to the template to include in display.
    """

    fpage = get_flatpage(request)

    # graph of just people directly connected to the belfast group
    if mode == "egograph":
        js_view = "network:bg-js"
    elif mode == "groupsheet-model":
        js_view = "network:bg-gs-js"
    return render(
        request, "network/bg.html", {"bg_uri": BELFAST_GROUP_URI, "js_view": js_view, "mode": mode, "flatpage": fpage}
    )
def map(request):
    """Display a map of places associated with the people connected to the
    Belfast Group or mentioned in the digitized Group sheets on the site.

    If a :class:`~django.contrib.flatpages.models.FlatPage` is found for
    this url, it is passed to the template to include in display.
    """

    fpage = get_flatpage(request)

    people = {}
    # semi-redundant with json view functionality, but easier to build filter
    for pl in find_places():
        # lat/long should have been added in rdf data prep, but
        # check just in case, because missing lat/long breaks the map
        if not all([pl.latitude, pl.longitude]):
            continue

        for p in pl.people:
            if p.local_uri:
                people[str(p.identifier)] = p.fullname

    return render(request, "network/map.html", {"people": people, "flatpage": fpage})
def list_groupsheets(request):
    '''View to display a list of all Group sheets from the RDF data.  Includes
    logic to generate and filter by facets for digital editions, authors, coverage
    dates, and source collections.

    Looks for a :class:`~django.contrib.flatpages.models.FlatPage` for this url,
    and if found, passes to the template display at the top of the list of
    Group sheets.
    '''

    # get flatpage for this url, if any
    flatpage = get_flatpage(request)

    url_args = {}
    filters = {}
    filter_digital = request.GET.get('edition', None)
    if filter_digital is not None:
        filters['has_url'] = True
        url_args['edition'] = 'digital'

    filter_author = request.GET.get('author', None)
    if filter_author is not None:
        # filter is in slug form; use that to build local uri
        url_args['author'] = filter_author
        author_uri = local_uri(reverse('people:profile', args=[filter_author]),
                               request)
        filters['author'] = author_uri

    filter_source = request.GET.get('source', None)
    if filter_source is not None:
        url_args['source'] = filter_source
        # TODO: preferred label / slugs / local identifier for these?
        # currently arg is the uri
        filters['source'] = filter_source

    filter_time = request.GET.get('dates', None)
    if filter_time is not None:
        url_args['dates'] = filter_time
        filters['coverage'] = filter_time

    results = get_rdf_groupsheets(**filters)
    # TODO: support source filter; make more django-like

    # generate labels/totals for 'facet' filters
    digital_count = 0
    authors = defaultdict(int)
    sources = defaultdict(int)
    time_periods = defaultdict(int)
    for r in results:
        # if not already filtered on digital, get a count
        if filter_digital is None and r.url:
            digital_count += 1
        if filter_author is None:
            # use author list to ensure *all* authors are listed properly
            for author in r.author_list:
                authors[author] += 1
        if filter_source is None:
            for s in r.sources:
                sources[s] += 1
        if filter_time is None:
            time_periods[r.coverage] += 1

    # generate lists of dicts for easy sorting in django template
    authors = [{'author': k, 'total': v} for k, v in authors.iteritems()]
    sources = [{'source': k, 'total': v} for k, v in sources.iteritems()]
    time_periods = [{'time_period': k, 'total': v} for k, v in time_periods.iteritems()]

    facets = {'digital': digital_count, 'authors': authors, 'sources': sources,
              'time_periods': time_periods}

    url_suffix = ''
    url_suffix = urllib.urlencode(url_args)
    # if not empty, prepend & for easy combination with other url args
    if url_suffix != '':
        url_suffix = '&%s' % url_suffix

    # generate query args to remove individual filters
    filters = {}
    if filter_digital is not None:
        args = url_args.copy()
        del args['edition']
        filter_args = urllib.urlencode(args)
        filters['digital edition'] = '?' + (filter_args if filter_args else '')
    if filter_author is not None:
        args = url_args.copy()
        del args['author']
        # pull author display name from results
        # TODO: init rdfperson and use that label instead?
        if results:
            for a in results[0].author_list:
                # groupsheets may have multiple authors, so make sure
                # we get the correct label for the active filter
                if str(a.identifier) == author_uri:
                    filters["%s, %s" % (a.lastname, a.firstname)] = '?' + urllib.urlencode(args)
                    break

    if filter_source is not None:
        args = url_args.copy()
        del args['source']
        if results:
            # pull source name from results (TODO: shorter labels)
            for s in results[0].sources:
                # groupsheets may have multiple sources, so make sure
                # we get the correct label
                if str(s.identifier) == filter_source:
                    filters[s.name] = '?' + urllib.urlencode(args)
                    break

    if filter_time is not None:
        args = url_args.copy()
        del args['dates']
        filters[filter_time] = '?' + urllib.urlencode(args)


    return render(request, 'groupsheets/list.html',
                  {'documents': results, 'facets': facets,
                   'url_suffix': url_suffix, 'filters': filters,
                   'flatpage': flatpage})