Example #1
0
def explore_recent(request, format="html"):

    per_page = ENTRIES_PER_PAGE
    offset, prev = util.page_offset(request)

    inbox = api.inbox_get_explore(request.user,
                                  limit=(per_page + 1),
                                  offset=offset)

    # START inbox generation chaos
    # TODO(termie): refacccttttooorrrrr
    entries = api.entry_get_entries(request.user, inbox)
    per_page = per_page - (len(inbox) - len(entries))
    entries, more = util.page_entries(request, entries, per_page)

    stream_keys = [e.stream for e in entries]

    streams = api.stream_get_streams(request.user, stream_keys)

    actor_nicks = [e.owner for e in entries] + [e.actor for e in entries]
    actors = api.actor_get_actors(request.user, actor_nicks)

    # here comes lots of munging data into shape
    streams = prep_stream_dict(streams, actors)
    entries = prep_entry_list(entries, streams, actors)

    # END inbox generation chaos

    area = 'explore'
    sidebar_green_top = True

    c = template.RequestContext(request, locals())

    if format == 'html':
        t = loader.get_template('explore/templates/recent.html')
        return http.HttpResponse(t.render(c))
    elif format == 'json':
        t = loader.get_template('explore/templates/recent.json')
        r = util.HttpJsonResponse(t.render(c), request)
        return r
    elif format == 'atom':
        t = loader.get_template('explore/templates/recent.atom')
        r = util.HttpAtomResponse(t.render(c), request)
        return r
    elif format == 'rss':
        t = loader.get_template('explore/templates/recent.rss')
        r = util.HttpRssResponse(t.render(c), request)
        return r
Example #2
0
def actor_history(request, nick=None, format='html'):
    nick = clean.nick(nick)
    view = api.actor_lookup_nick(request.user, nick)

    if not view:
        raise exception.UserDoesNotExistError(nick, request.user)

    called_subscribe, sub_ref = common_views.call_api_from_request(
        request, 'subscription_request')
    if called_subscribe:
        if sub_ref.state == 'subscribed':
            message = 'Subscribed.'
        else:
            message = 'Subscription requested.'
        return util.RedirectFlash(view.url(), message)

    handled = common_views.handle_view_action(
        request, {
            'entry_remove': request.path,
            'entry_remove_comment': request.path,
            'entry_mark_as_spam': request.path,
            'subscription_remove': view.url(),
            'actor_add_contact': request.path,
            'actor_remove_contact': request.path,
            'post': request.path,
            'presence_set': request.path,
        })
    if handled:
        return handled

    privacy = 'public'
    if request.user:
        if view.nick == request.user.nick:
            privacy = 'private'
        # ROOT because we care whether or not request.user is a contact of
        # the view user's, not whether the request.user can see the contacts
        elif api.actor_has_contact(api.ROOT, view.nick, request.user.nick):
            privacy = 'contacts'

    # we're going to hide a bunch of stuff if this user is private and we
    # aren't allowed to see
    user_is_private = False
    if view.privacy < models.PRIVACY_PUBLIC and privacy == 'public':
        user_is_private = True

    per_page = ENTRIES_PER_PAGE
    offset, prev = util.page_offset(request)

    if privacy == 'public':
        if user_is_private:
            inbox = []
        else:
            inbox = api.inbox_get_actor_public(request.user,
                                               view.nick,
                                               limit=(per_page + 1),
                                               offset=offset)
    elif privacy == 'contacts':
        inbox = api.inbox_get_actor_contacts(request.user,
                                             view.nick,
                                             limit=(per_page + 1),
                                             offset=offset)
    elif privacy == 'private':
        inbox = api.inbox_get_actor_private(request.user,
                                            view.nick,
                                            limit=(per_page + 1),
                                            offset=offset)

    actor_streams = api.stream_get_actor_safe(request.user, view.nick)

    entries, more = _get_inbox_entries(request, inbox)
    contacts, channels, streams, entries = _assemble_inbox_data(
        request, entries, actor_streams, view)

    # If not logged in, cannot write
    is_owner = request.user and view.nick == request.user.nick

    try:
        presence = api.presence_get(request.user, view.nick)
        presence_stream = api.stream_get_presence(request.user, view.nick)
        last_entry = api.entry_get_last(request.user,
                                        presence_stream.keyname())
        view.last_entry = last_entry
    except exception.ApiException:
        pass

    # for add/remove contact
    if request.user:
        user_is_contact = api.actor_has_contact(request.user,
                                                request.user.nick, view.nick)
        view.my_contact = user_is_contact
    else:
        user_is_contact = False

    # for sidebar streams
    view_streams = _get_sidebar_streams(actor_streams, streams, request.user)

    # for sidebar_contacts
    contacts_count = view.extra.get('contact_count', 0)
    contacts_more = contacts_count > CONTACTS_PER_PAGE

    # for sidebar channels
    channels_count = view.extra.get('channel_count', 0)
    channels_more = channels_count > CHANNELS_PER_PAGE

    # Config for the template
    green_top = True
    sidebar_green_top = True
    selectable_icons = display.SELECTABLE_ICONS
    area = 'user'

    c = template.RequestContext(request, locals())

    if format == 'html':
        t = loader.get_template('actor/templates/history.html')
        return http.HttpResponse(t.render(c))
    elif format == 'json':
        t = loader.get_template('actor/templates/history.json')
        return util.HttpJsonResponse(t.render(c), request)
    elif format == 'atom':
        t = loader.get_template('actor/templates/history.atom')
        return util.HttpAtomResponse(t.render(c), request)
    elif format == 'rss':
        t = loader.get_template('actor/templates/history.rss')
        return util.HttpRssResponse(t.render(c), request)
Example #3
0
def actor_contacts(request, nick=None, format='html'):
    nick = clean.nick(nick)

    view = api.actor_lookup_nick(request.user, nick)

    if not view:
        raise exception.UserDoesNotExistError(nick, request.user)

    handled = common_views.handle_view_action(
        request, {
            'actor_add_contact': request.path,
            'actor_remove_contact': request.path,
        })
    if handled:
        return handled

    per_page = CONTACTS_PER_PAGE
    offset, prev = util.page_offset_nick(request)

    contact_nicks = api.actor_get_contacts(request.user,
                                           view.nick,
                                           limit=(per_page + 1),
                                           offset=offset)
    actor_nicks = contact_nicks
    actors = api.actor_get_actors(request.user, actor_nicks)
    # clear deleted actors
    actors = dict([(k, v) for k, v in actors.iteritems() if v])
    per_page = per_page - (len(contact_nicks) - len(actors))

    # TODO(termie): incorporate this into paging so we only fetch the range
    #               on this page
    # add some extra info so we can let the user do contextual actions
    # on these homeboys
    if request.user and request.user.nick == view.nick:
        # looking at self, find out who of these people follow me so
        # I can highlight them
        for actor in actors:
            if api.actor_is_follower(request.user, view.nick, actor):
                actors[actor].my_follower = True
            actors[actor].my_contact = True
            actors[actor].rel = 'contact'
        whose = 'Your'
    elif request.user:
        my_contacts_nicks = api.actor_get_contacts(request.user,
                                                   request.user.nick)
        for f in my_contacts_nicks:
            try:
                actors[f].my_contact = True
            except:
                pass
        for x in actors:
            actors[x].rel = 'contact'
        whose = "%s's" % view.display_nick()

    # here comes lots of munging data into shape
    actor_tiles = [actors[x] for x in contact_nicks if x in actors]

    actor_tiles_count = view.extra.get('contact_count', 0)
    actor_tiles, actor_tiles_more = util.page_actors(request, actor_tiles,
                                                     per_page)

    area = 'people'

    c = template.RequestContext(request, locals())

    if format == 'html':
        t = loader.get_template('actor/templates/contacts.html')
        return http.HttpResponse(t.render(c))
    elif format == 'json':
        t = loader.get_template('actor/templates/contacts.json')
        return util.HttpJsonResponse(t.render(c), request)
Example #4
0
def actor_item(request, nick=None, item=None, format='html'):
    # The nick passed in the url looks ugly with the escaped @ in it and is
    # generally just shorter if we only use the lead part of the nick
    # however the entire system expects full nicks so we should expand this
    # as soon as possible
    nick = clean.nick(nick)

    # Most pages have the concept of a viewer and an actor being viewed,
    # in all cases the viewer is `request.user` and the actor being viewed
    # should be named `view`
    view = api.actor_lookup_nick(request.user, nick)

    if not view:
        raise exception.UserDoesNotExistError(nick, request.user)

    # With very few exceptions, whenever we are referring to a an
    # instance that is an entity from the datastore we append `_ref`
    # to the variable name to distinguish it from the variable that
    # is simply a string identifier.
    # In the code below `stream_ref` and `entry_ref` are both entity
    # references, while `entry` is simply the string key_name of an entry
    stream_ref = api.stream_get_presence(request.user, view.nick)
    if not stream_ref:
        raise http.Http404()

    if item == 'last':
        entry_ref = api.entry_get_last(request.user, stream_ref.keyname())
        return http.HttpResponseRedirect(entry_ref.url())
    else:
        entry = '%s/%s' % (stream_ref.key().name(), item)
        entry_ref = api.entry_get_safe(request.user, entry)

    # Most api calls will return None if the entity being looked up does
    # not exist so we usually want to verify the return values
    if not entry_ref:
        raise http.Http404()

    # When handling user actions the following pattern more or less applies
    # if 'parameter_unique_to_action' in request.(POST|GET|REQUEST):
    #   try:
    #     validate.nonce(request, 'nonce_action')
    #     validate.anything_else_that_is_related_to_ui_rather_than_call()
    #
    #     local_variable = request.(POST|GET|REQUEST).get('request_arg')
    #     # or
    #     params = util.query_dict_to_keywords(request.(POST|GET|REQUEST))
    #
    #     # Our goal is to have most of the logic for any action translate
    #     # directly into an api call on behalf of the requesting user
    #     # such that the api call is responsible for validating all input
    #     # and raising any applicable errors
    #     result = api.some_api_method(request.user,
    #                                  method_variable=local_variable,
    #                                  ...)
    #     # or
    #     result = api.some_api_method(request.user,  **params)
    #
    #     # All actions should issue a redirect with a success message
    #     return util.RedirectFlash('some_url', 'some success message')
    #   except:
    #     exception.handle_exception(request)
    #
    # When an exception occurs we expect the rest of the page to be able
    # to be processed normally as if no action had been taken, the error
    # handling section of the template should display the errors caught
    # by the exception.handle_exception() call

    handled = common_views.handle_view_action(
        request, {
            'entry_add_comment': entry_ref.url(request=request),
            'entry_remove': view.url(request=request),
            'entry_remove_comment': entry_ref.url(request=request),
            'entry_mark_as_spam': entry_ref.url(request=request)
        })
    if handled:
        return handled

    comments = api.entry_get_comments(request.user, entry_ref.key().name())

    # To minimize the number of lookups to the datastore once we know
    # all the data we will be displaying on a page we attempt to make
    # a list of all the actors associated with that data so that we can
    # fetch them all at once
    actor_nicks = [entry_ref.owner, entry_ref.actor
                   ] + [c.actor for c in comments]
    actors = api.actor_get_actors(request.user, actor_nicks)

    # Creates a copy of actors with lowercase keys (Django #6904: template filter
    # dictsort sorts case sensitive), excluding the currently logged in user.
    participants = {}
    for k, v in actors.iteritems():
        if (v and not (hasattr(request.user, 'nick')
                       and request.user.nick == v.nick)):
            participants[k.lower()] = v

    # Due to restrictions on Django's templating language most of the time
    # we will have to take an additional step of preparing all of our data
    # for display, this usually translates to attaching references to
    # actor or stream entities.
    # Functions that handle this preparation should be added to the
    # common.display module
    entry = display.prep_entry(entry_ref,
                               {stream_ref.key().name(): stream_ref}, actors)
    comments = display.prep_comment_list(comments, actors)

    # Additionally, to minimize more logic in the templates some variables
    # can be defined to configure the output, these are usually template specific
    # though some are common variables for anything that inherits from the
    # base templates
    green_top = True
    sidebar_green_top = True

    # The quickest way to make sure we are getting all of the things we care
    # about passed to the template without the temptation of making last minute
    # changes is just to pass `locals()` to the template context
    c = template.RequestContext(request, locals())

    # Ideally this is all that should be necessary to add additional output
    # formats, in practice it is yet to be seen whether additional data
    # preparation will be necessary before outputting in JSON or ATOM formats
    if format == 'html':

        # We always use the full path to the template to prevent naming conflicts
        # and difficult searches.
        t = loader.get_template('actor/templates/item.html')
        return http.HttpResponse(t.render(c))

    elif format == 'json':
        t = loader.get_template('actor/templates/item.json')
        return util.HttpJsonResponse(t.render(c), request)
Example #5
0
def actor_overview(request, nick, format='html'):
    nick = clean.nick(nick)

    view = api.actor_lookup_nick(request.user, nick)

    if not view:
        raise exception.UserDoesNotExistError(nick, request.user)

    if not request.user or view.nick != request.user.nick:
        # Instead of displaying the overview, redirect to the public-facing page
        return http.HttpResponseRedirect(view.url())

    handled = common_views.handle_view_action(
        request, {
            'entry_remove': request.path,
            'entry_remove_comment': request.path,
            'entry_mark_as_spam': request.path,
            'presence_set': request.path,
            'settings_hide_comments': request.path,
            'post': request.path,
        })
    if handled:
        return handled

    per_page = ENTRIES_PER_PAGE
    offset, prev = util.page_offset(request)

    inbox = api.inbox_get_actor_overview(request.user,
                                         view.nick,
                                         limit=(per_page + 1),
                                         offset=offset)

    actor_streams = api.stream_get_actor(request.user, view.nick)
    entries, more = _get_inbox_entries(request, inbox,
                                       view.extra.get('comments_hide', 0))
    contacts, channels, streams, entries = _assemble_inbox_data(
        request, entries, actor_streams, view)

    # Check for unconfirmed emails
    unconfirmeds = api.activation_get_actor_email(request.user, view.nick)
    if unconfirmeds:
        unconfirmed_email = unconfirmeds[0].content

    # If not logged in, cannot write
    is_owner = False
    try:
        is_owner = view.nick == request.user.nick
    except:
        pass
    presence = api.presence_get(request.user, view.nick)

    # for sidebar streams
    view_streams = _get_sidebar_streams(actor_streams, streams)

    # for sidebar_contacts
    contacts_count = view.extra.get('contact_count', 0)
    contacts_more = contacts_count > CONTACTS_PER_PAGE

    # for sidebar channels
    channels_count = view.extra.get('channel_count', 0)
    channels_more = channels_count > CHANNELS_PER_PAGE

    # Config for the template
    green_top = True
    sidebar_green_top = True
    selectable_icons = display.SELECTABLE_ICONS

    area = 'home'

    # TODO(tyler/termie):  This conflicts with the global settings import.
    # Also, this seems fishy.  Do none of the settings.* items work in templates?
    import settings

    c = template.RequestContext(request, locals())

    if format == 'html':
        t = loader.get_template('actor/templates/overview.html')
        return http.HttpResponse(t.render(c))
    elif format == 'json':
        t = loader.get_template('actor/templates/overview.json')
        return util.HttpJsonResponse(t.render(c), request)
    elif format == 'atom':
        t = loader.get_template('actor/templates/overview.atom')
        return util.HttpAtomResponse(t.render(c), request)
    elif format == 'rss':
        t = loader.get_template('actor/templates/overview.rss')
        return util.HttpRssResponse(t.render(c), request)
Example #6
0
def actor_history(request, nick=None, format='html'):
    nick = clean.nick(nick)
    view = api.actor_lookup_nick(request.user, nick)

    if not view:
        raise exception.UserDoesNotExistError(nick, request.user)

    called_subscribe, sub_ref = common_views.call_api_from_request(
        request, 'subscription_request')
    if called_subscribe:
        if sub_ref.state == 'subscribed':
            message = 'Subscribed.'
        else:
            message = 'Subscription requested.'
        return util.RedirectFlash(view.url(), message)

    handled = common_views.handle_view_action(
        request, {
            'entry_remove': request.path,
            'entry_remove_comment': request.path,
            'entry_mark_as_spam': request.path,
            'subscription_remove': view.url(),
            'actor_add_contact': request.path,
            'actor_remove_contact': request.path,
            'post': request.path,
            'presence_set': request.path,
        })
    if handled:
        return handled

    privacy = 'public'
    if request.user:
        if view.nick == request.user.nick:
            privacy = 'private'
        # ROOT because we care whether or not request.user is a contact of
        # the view user's, not whether the request.user can see the contacts
        elif api.actor_has_contact(api.ROOT, view.nick, request.user.nick):
            privacy = 'contacts'

    # we're going to hide a bunch of stuff if this user is private and we
    # aren't allowed to see
    user_is_private = False
    if view.privacy < models.PRIVACY_PUBLIC and privacy == 'public':
        user_is_private = True

    per_page = ENTRIES_PER_PAGE
    offset, prev = util.page_offset(request)

    if privacy == 'public':
        if user_is_private:
            inbox = []
        else:
            inbox = api.inbox_get_actor_public(request.user,
                                               view.nick,
                                               limit=(per_page + 1),
                                               offset=offset)
    elif privacy == 'contacts':
        inbox = api.inbox_get_actor_contacts(request.user,
                                             view.nick,
                                             limit=(per_page + 1),
                                             offset=offset)
    elif privacy == 'private':
        inbox = api.inbox_get_actor_private(request.user,
                                            view.nick,
                                            limit=(per_page + 1),
                                            offset=offset)

    # START inbox generation chaos
    # TODO(termie): refacccttttooorrrrr
    entries = api.entry_get_entries(request.user, inbox)
    per_page = per_page - (len(inbox) - len(entries))
    entries, more = util.page_entries(request, entries, per_page)

    stream_keys = [e.stream for e in entries]
    try:
        actor_streams = api.stream_get_actor(request.user, view.nick)
    except exception.ApiException:
        actor_streams = []
    stream_keys += [s.key().name() for s in actor_streams]
    streams = api.stream_get_streams(request.user, stream_keys)

    try:
        contact_nicks = api.actor_get_contacts(request.user,
                                               view.nick,
                                               limit=CONTACTS_PER_PAGE)
    except exception.ApiException:
        contact_nicks = []

    actor_nicks = (contact_nicks + [view.nick] +
                   [s.owner for s in streams.values()] +
                   [e.owner for e in entries] + [e.actor for e in entries])
    actors = api.actor_get_actors(request.user, actor_nicks)

    # here comes lots of munging data into shape
    contacts = [actors[x] for x in contact_nicks if actors[x]]
    streams = display.prep_stream_dict(streams, actors)
    entries = display.prep_entry_list(entries, streams, actors)

    # END inbox generation chaos

    # If not logged in, cannot write
    is_owner = request.user and view.nick == request.user.nick

    try:
        presence = api.presence_get(request.user, view.nick)
        presence_stream = api.stream_get_presence(request.user, view.nick)
        last_entry = api.entry_get_last(request.user,
                                        presence_stream.keyname())
        view.last_entry = last_entry
    except exception.ApiException:
        pass

    # for add/remove contact
    if request.user:
        user_is_contact = api.actor_has_contact(request.user,
                                                request.user.nick, view.nick)
        view.my_contact = user_is_contact
    else:
        user_is_contact = False

    # for sidebar streams
    view_streams = dict([(x.key().name(), streams[x.key().name()])
                         for x in actor_streams])
    if request.user:
        # un/subscribe buttons are possible only, when logged in

        # TODO(termie): what if there are quite a lot of streams?
        for stream in view_streams.values():
            stream.subscribed = api.subscription_exists(
                request.user,
                stream.key().name(), 'inbox/%s/overview' % request.user.nick)

    # for sidebar_contacts
    contacts_count = view.extra.get('contact_count', 0)
    contacts_more = contacts_count > CONTACTS_PER_PAGE

    # Config for the template
    green_top = True
    sidebar_green_top = True
    selectable_icons = display.SELECTABLE_ICONS
    area = 'user'

    c = template.RequestContext(request, locals())

    if format == 'html':
        t = loader.get_template('actor/templates/history.html')
        return http.HttpResponse(t.render(c))
    elif format == 'json':
        t = loader.get_template('actor/templates/history.json')
        r = util.HttpJsonResponse(t.render(c), request)
        return r
    elif format == 'atom':
        t = loader.get_template('actor/templates/history.atom')
        r = util.HttpAtomResponse(t.render(c), request)
        return r
    elif format == 'rss':
        t = loader.get_template('actor/templates/history.rss')
        r = util.HttpRssResponse(t.render(c), request)
        return r
Example #7
0
def actor_overview(request, nick, format='html'):
    nick = clean.nick(nick)

    view = api.actor_lookup_nick(request.user, nick)

    if not view:
        raise exception.UserDoesNotExistError(nick, request.user)

    if not request.user or view.nick != request.user.nick:
        # Instead of displaying the overview, redirect to the public-facing page
        return http.HttpResponseRedirect(view.url())

    handled = common_views.handle_view_action(
        request, {
            'entry_remove': request.path,
            'entry_remove_comment': request.path,
            'entry_mark_as_spam': request.path,
            'presence_set': request.path,
            'settings_hide_comments': request.path,
            'post': request.path,
        })
    if handled:
        return handled

    per_page = ENTRIES_PER_PAGE
    offset, prev = util.page_offset(request)

    inbox = api.inbox_get_actor_overview(request.user,
                                         view.nick,
                                         limit=(per_page + 1),
                                         offset=offset)

    # START inbox generation chaos
    # TODO(termie): refacccttttooorrrrr
    entries = api.entry_get_entries(request.user, inbox)

    if view.extra.get('comments_hide', 0):
        # TODO(tyler): This is certainly not the most eloquent way to filter
        # through entries to remove comments.
        entries = [x for x in entries if not x.stream.endswith('comments')]

    per_page = per_page - (len(inbox) - len(entries))
    entries, more = util.page_entries(request, entries, per_page)

    stream_keys = [e.stream for e in entries]
    actor_streams = api.stream_get_actor(request.user, view.nick)
    stream_keys += [s.key().name() for s in actor_streams]
    streams = api.stream_get_streams(request.user, stream_keys)

    contact_nicks = api.actor_get_contacts(request.user,
                                           view.nick,
                                           limit=CONTACTS_PER_PAGE)
    actor_nicks = (contact_nicks + [view.nick] +
                   [s.owner for s in streams.values()] +
                   [e.owner for e in entries] + [e.actor for e in entries])
    actors = api.actor_get_actors(request.user, actor_nicks)

    # here comes lots of munging data into shape
    # clear deleted contacts
    contacts = [actors[x] for x in contact_nicks if actors[x]]
    streams = display.prep_stream_dict(streams, actors)
    entries = display.prep_entry_list(entries, streams, actors)

    # END inbox generation chaos

    # Check for unconfirmed emails
    unconfirmeds = api.activation_get_actor_email(request.user, view.nick)
    if unconfirmeds:
        unconfirmed_email = unconfirmeds[0].content

    # If not logged in, cannot write
    is_owner = False
    try:
        is_owner = view.nick == request.user.nick
    except:
        pass
    presence = api.presence_get(request.user, view.nick)

    # for sidebar streams
    view_streams = dict([(x.key().name(), streams[x.key().name()])
                         for x in actor_streams])

    # for sidebar_contacts
    contacts_count = view.extra.get('contact_count', 0)
    contacts_more = contacts_count > CONTACTS_PER_PAGE

    # Config for the template
    green_top = True
    sidebar_green_top = True
    selectable_icons = display.SELECTABLE_ICONS

    area = 'home'

    # TODO(tyler/termie):  This conflicts with the global settings import.
    # Also, this seems fishy.  Do none of the settings.* items work in templates?
    import settings

    c = template.RequestContext(request, locals())

    if format == 'html':
        t = loader.get_template('actor/templates/overview.html')
        return http.HttpResponse(t.render(c))
    elif format == 'json':
        t = loader.get_template('actor/templates/overview.json')
        r = util.HttpJsonResponse(t.render(c), request)
        return r
    elif format == 'atom':
        t = loader.get_template('actor/templates/overview.atom')
        r = util.HttpAtomResponse(t.render(c), request)
        return r
    elif format == 'rss':
        t = loader.get_template('actor/templates/overview.rss')
        r = util.HttpRssResponse(t.render(c), request)
        return r
Example #8
0
def channel_history(request, nick, format='html'):
    """ the page for a channel

  if the channel does not exist we go to create channel instead

  should let you join a channel or post to it if you already are a member
  also leave it if you are a member,
  display the posts to this channel and the member list if you are allowed
  to see them

  if you are an admin you should have the options to modify the channel
  """
    nick = clean.channel(nick)

    view = api.actor_lookup_nick(request.user, nick)
    if not view:
        return http.HttpResponseRedirect('/channel/create?channel=%s' % nick)

    admins = api.channel_get_admins(request.user, channel=view.nick)
    members = api.channel_get_members(request.user, channel=view.nick)

    handled = common_views.handle_view_action(
        request, {
            'channel_join': request.path,
            'channel_part': request.path,
            'channel_post': request.path,
            'entry_remove': request.path,
            'entry_remove_comment': request.path,
            'entry_mark_as_spam': request.path,
            'subscription_remove': request.path,
            'subscription_request': request.path,
        })
    if handled:
        return handled

    privacy = 'public'

    user_can_post = False
    user_is_admin = False
    if not request.user:
        pass
    elif api.channel_has_admin(request.user, view.nick, request.user.nick):
        privacy = 'private'
        user_can_post = True
        user_is_admin = True
    elif api.channel_has_member(request.user, view.nick, request.user.nick):
        privacy = 'contacts'
        user_can_post = True

    per_page = CHANNEL_HISTORY_PER_PAGE
    offset, prev = util.page_offset(request)

    if privacy == 'public':
        inbox = api.inbox_get_actor_public(request.user,
                                           view.nick,
                                           limit=(per_page + 1),
                                           offset=offset)
    elif privacy == 'contacts':
        inbox = api.inbox_get_actor_contacts(request.user,
                                             view.nick,
                                             limit=(per_page + 1),
                                             offset=offset)
    elif privacy == 'private':
        inbox = api.inbox_get_actor_private(api.ROOT,
                                            view.nick,
                                            limit=(per_page + 1),
                                            offset=offset)

    # START inbox generation chaos
    # TODO(termie): refacccttttooorrrrr

    entries = api.entry_get_entries(request.user, inbox)
    # clear out deleted entries
    per_page = per_page - (len(inbox) - len(entries))
    entries, more = util.page_entries(request, entries, per_page)

    stream_keys = [e.stream for e in entries]
    actor_streams = api.stream_get_actor(request.user, view.nick)
    stream_keys += [s.key().name() for s in actor_streams]
    streams = api.stream_get_streams(request.user, stream_keys)

    contact_nicks = api.actor_get_contacts(request.user, view.nick)
    actor_nicks = (contact_nicks + admins + members + [view.nick] +
                   [s.owner
                    for s in streams.values()] + [e.actor for e in entries])
    actors = api.actor_get_actors(request.user, actor_nicks)

    # here comes lots of munging data into shape
    contacts = [actors[x] for x in contact_nicks if actors[x]]
    streams = display.prep_stream_dict(streams, actors)
    entries = display.prep_entry_list(entries, streams, actors)
    admins = [actors[x] for x in admins if actors[x]]
    members = [actors[x] for x in members if actors[x]]

    # END inbox generation chaos

    presence = api.presence_get(request.user, view.nick)

    # for sidebar_members
    members_count = view.extra['member_count']
    members_more = members_count > CONTACTS_PER_PAGE

    # for sidebar_admins
    admins_count = view.extra['admin_count']
    admins_more = admins_count > CONTACTS_PER_PAGE

    # config for templates
    green_top = True
    sidebar_green_top = True
    selectable_icons = display.SELECTABLE_ICONS

    # for sidebar streams (copied from actor/views.py.  refactor)
    view_streams = dict([(x.key().name(), streams[x.key().name()])
                         for x in actor_streams])
    if request.user:
        # un/subscribe buttons are possible only, when logged in

        # TODO(termie): what if there are quite a lot of streams?
        for stream in view_streams.values():
            stream.subscribed = api.subscription_exists(
                request.user,
                stream.key().name(), 'inbox/%s/overview' % request.user.nick)

    area = 'channel'
    c = template.RequestContext(request, locals())

    if format == 'html':
        t = loader.get_template('channel/templates/history.html')
        return http.HttpResponse(t.render(c))
    elif format == 'json':
        t = loader.get_template('channel/templates/history.json')
        r = util.HttpJsonResponse(t.render(c), request)
        return r
    elif format == 'atom':
        t = loader.get_template('channel/templates/history.atom')
        r = util.HttpAtomResponse(t.render(c), request)
        return r
    elif format == 'rss':
        t = loader.get_template('channel/templates/history.rss')
        r = util.HttpRssResponse(t.render(c), request)
        return r