Exemple #1
0
  def test_login_sso(self):
    o = util.override(DOMAIN=self.domain,
                      GAE_DOMAIN=self.gae_domain,
                      HOSTED_DOMAIN_ENABLED=True,
                      HOSTED_DOMAIN=self.hosted_domain,
                      SUBDOMAINS_ENABLED=True,
                      SSL_LOGIN_ENABLED=True,
                      )

    r = self.post_with_host('/login',
                            {'log': 'popular',
                             'pwd': self.passwords[clean.nick('popular')]
                             },
                            self.gae_domain,
                            ssl=True
                            )
    
    check_redirect = 'http://%s/login/noreally' % self.domain
    r = self.assertRedirectsPrefix(r, 
                                   check_redirect,
                                   status_code=302,
                                   target_status_code=302)
    r = self.assertRedirectsPrefix(r, 
                                   '/user/popular/overview',
                                   status_code=302,
                                   target_status_code=200)
    o.reset()
Exemple #2
0
def actor_invite(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 view.nick != request.user.nick:
    # Bounce the user to their own page (avoids any confusion for the wrong
    # nick in the url).
    return http.HttpResponseRedirect(
        '%s/invite' % request.user.url())
  
  handled = common_views.handle_view_action(
      request,
      { 'invite_request_email': request.path, })
  if handled:
    return handled

  if request.user and request.user.nick == view.nick:
    whose = 'Your'
  else:
    whose = "%s's" % view.display_nick()

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

  if format == 'html':
    t = loader.get_template('actor/templates/invite.html')
    return http.HttpResponse(t.render(c))
Exemple #3
0
 def test_login(self):
   log = 'popular'
   pwd = self.passwords[clean.nick(log)]
   r = self.client.post('/login', {'log': log, 'pwd': pwd})
   r = self.assertRedirectsPrefix(r, '/user/popular/overview')
   self.assertTemplateUsed(r, 'actor/templates/overview.html')
   self.assertTemplateUsed(r, 'common/templates/flash.html')
Exemple #4
0
def actor_invite(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 view.nick != request.user.nick:
        # Bounce the user to their own page (avoids any confusion for the wrong
        # nick in the url).
        return http.HttpResponseRedirect('%s/invite' % request.user.url())

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

    if request.user and request.user.nick == view.nick:
        whose = 'Your'
    else:
        whose = "%s's" % view.display_nick()

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

    if format == 'html':
        t = loader.get_template('actor/templates/invite.html')
        return http.HttpResponse(t.render(c))
Exemple #5
0
 def test_login(self):
     log = "popular"
     pwd = self.passwords[clean.nick(log)]
     r = self.client.post("/login", {"log": log, "pwd": pwd})
     r = self.assertRedirectsPrefix(r, "/user/popular/overview")
     self.assertTemplateUsed(r, "actor/templates/overview.html")
     self.assertTemplateUsed(r, "common/templates/flash.html")
Exemple #6
0
  def test_settings_change_avatar(self):
    nick = 'obligated'
    self.login(nick)

    nick = clean.nick(nick)
    old_avatar = api.actor_get(api.ROOT, nick).extra.get('icon',
                                                         'avatar_default')

    # TODO(teemu): add more tests for different file types (gif and jpg).
    # Alternatively, test those against api.avatar_upload.
    r = self.client.post('/user/obligated/settings/photo',
                         {
                           'avatar': 'default/animal_9',
                           '_nonce' :
                              util.create_nonce('obligated', 'change_photo'),
                         })
    r = self.assertRedirectsPrefix(r, '/user/obligated/settings/photo')

    new_avatar = api.actor_get(api.ROOT, nick).extra.get('icon',
                                                         'avatar_default')
    self.assertNotEquals(old_avatar, new_avatar)

    self.assertContains(r, 'Avatar changed')
    self.assertTemplateUsed(r, 'actor/templates/settings_photo.html')
    self.assertTemplateUsed(r, 'common/templates/flash.html')
Exemple #7
0
def actor_settings_redirect(request):
    if not request.user:
        return http.HttpResponseRedirect('/login?redirect_to=%s' %
                                         request.get_full_path())
    nick = clean.nick(request.user.nick)
    view = api.actor_lookup_nick(request.user, nick)
    return http.HttpResponseRedirect(view.url() + request.get_full_path())
Exemple #8
0
    def test_sign_in(self):
        nick = 'popular'
        password = self.passwords[clean.nick(nick)]

        r = self.receive('SIGN IN %s %s' % (nick, password))
        self.assertOutboxContains(
            r, 'Welcome to %s SMS %s' % (settings.SITE_NAME, nick))
Exemple #9
0
    def test_login_sso(self):
        o = util.override(
            DOMAIN=self.domain,
            GAE_DOMAIN=self.gae_domain,
            HOSTED_DOMAIN_ENABLED=True,
            HOSTED_DOMAIN=self.hosted_domain,
            SUBDOMAINS_ENABLED=True,
            SSL_LOGIN_ENABLED=True,
        )

        r = self.post_with_host('/login', {
            'log': 'popular',
            'pwd': self.passwords[clean.nick('popular')]
        },
                                self.gae_domain,
                                ssl=True)

        check_redirect = 'http://%s/login/noreally' % self.domain
        r = self.assertRedirectsPrefix(r,
                                       check_redirect,
                                       status_code=302,
                                       target_status_code=302)
        r = self.assertRedirectsPrefix(r,
                                       '/user/popular/overview',
                                       status_code=302,
                                       target_status_code=200)
        o.reset()
Exemple #10
0
 def test_login(self):
     log = 'popular'
     pwd = self.passwords[clean.nick(log)]
     r = self.client.post('/login', {'log': log, 'pwd': pwd})
     r = self.assertRedirectsPrefix(r, '/user/popular/overview')
     self.assertTemplateUsed(r, 'actor/templates/overview.html')
     self.assertTemplateUsed(r, 'common/templates/flash.html')
Exemple #11
0
def actor_settings_redirect(request):
  if not request.user:
    return http.HttpResponseRedirect(
        '/login?redirect_to=%s' % request.get_full_path())
  nick = clean.nick(request.user.nick)
  view = api.actor_lookup_nick(request.user, nick)
  return http.HttpResponseRedirect(view.url() + request.get_full_path())
Exemple #12
0
 def test_login_with_confirmed_email(self):
     log = 'hotness'
     pwd = self.passwords[clean.nick(log)]
     confirmed_email = '*****@*****.**'
     r = self.client.post('/login', {'log': confirmed_email, 'pwd': pwd})
     r = self.assertRedirectsPrefix(r, '/user/hotness/overview')
     self.assertTemplateUsed(r, 'actor/templates/overview.html')
     self.assertTemplateUsed(r, 'common/templates/flash.html')
Exemple #13
0
 def test_login_with_confirmed_email(self):
     log = "hotness"
     pwd = self.passwords[clean.nick(log)]
     confirmed_email = "*****@*****.**"
     r = self.client.post("/login", {"log": confirmed_email, "pwd": pwd})
     r = self.assertRedirectsPrefix(r, "/user/hotness/overview")
     self.assertTemplateUsed(r, "actor/templates/overview.html")
     self.assertTemplateUsed(r, "common/templates/flash.html")
Exemple #14
0
 def test_login_with_confirmed_email(self):
   log = 'hotness'
   pwd = self.passwords[clean.nick(log)]
   confirmed_email = '*****@*****.**'
   r = self.client.post('/login', {'log': confirmed_email, 'pwd': pwd})
   r = self.assertRedirectsPrefix(r, '/user/hotness/overview')
   self.assertTemplateUsed(r, 'actor/templates/overview.html')
   self.assertTemplateUsed(r, 'common/templates/flash.html')
Exemple #15
0
def actor_followers(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)

    follower_nicks = api.actor_get_followers(request.user,
                                             view.nick,
                                             limit=(per_page + 1),
                                             offset=offset)
    actor_nicks = follower_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(follower_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:
        for actor in actors:
            if api.actor_is_contact(request.user, view.nick, actor):
                actors[actor].my_contact = True
        whose = 'Your'
    else:
        whose = "%s's" % view.display_nick()

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

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

    area = 'people'

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

    # TODO: Other output formats.
    if format == 'html':
        t = loader.get_template('actor/templates/followers.html')
        return http.HttpResponse(t.render(c))
Exemple #16
0
def actor_followers(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)

  follower_nicks = api.actor_get_followers(request.user,
                                           view.nick,
                                           limit=(per_page + 1),
                                           offset=offset)
  actor_nicks = follower_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(follower_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:
    for actor in actors:
      if api.actor_is_contact(request.user, view.nick, actor):
        actors[actor].my_contact = True
    whose = 'Your'
  else:
    whose = "%s's" % view.display_nick()

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

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

  area = 'people'

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

  # TODO: Other output formats.
  if format == 'html':
    t = loader.get_template('actor/templates/followers.html')
    return http.HttpResponse(t.render(c))
Exemple #17
0
    def test_login_deleted(self):
        log = "popular"
        pwd = self.passwords[clean.nick(log)]
        r = self.client.post("/login", {"log": log, "pwd": pwd})
        r = self.assertRedirectsPrefix(r, "/user/popular/overview")
        self.assertTemplateUsed(r, "actor/templates/overview.html")
        self.assertTemplateUsed(r, "common/templates/flash.html")

        api.actor_remove(api.ROOT, "popular")
        r = self.client.post("/login", {"log": log, "pwd": pwd})
        self.assert_error_contains(r, "Invalid username")
        self.assertTemplateUsed(r, "login/templates/login.html")
Exemple #18
0
    def test_login_deleted(self):
        log = 'popular'
        pwd = self.passwords[clean.nick(log)]
        r = self.client.post('/login', {'log': log, 'pwd': pwd})
        r = self.assertRedirectsPrefix(r, '/user/popular/overview')
        self.assertTemplateUsed(r, 'actor/templates/overview.html')
        self.assertTemplateUsed(r, 'common/templates/flash.html')

        api.actor_remove(api.ROOT, 'popular')
        r = self.client.post('/login', {'log': log, 'pwd': pwd})
        self.assert_error_contains(r, 'Invalid username')
        self.assertTemplateUsed(r, 'login/templates/login.html')
Exemple #19
0
  def test_login_deleted(self):
    log = 'popular'
    pwd = self.passwords[clean.nick(log)]
    r = self.client.post('/login', {'log': log, 'pwd': pwd})
    r = self.assertRedirectsPrefix(r, '/user/popular/overview')
    self.assertTemplateUsed(r, 'actor/templates/overview.html')
    self.assertTemplateUsed(r, 'common/templates/flash.html')

    api.actor_remove(api.ROOT, 'popular')
    r = self.client.post('/login', {'log': log, 'pwd': pwd})
    self.assert_error_contains(r, 'Invalid username')
    self.assertTemplateUsed(r, 'login/templates/login.html')
Exemple #20
0
    def actor_remove_contact(self, from_jid, nick):
        jid_ref = api.actor_lookup_im(api.ROOT, from_jid.base())
        if not jid_ref:
            raise exception.ValidationError(
                "You must be signed in to post, please SIGN IN")
        nick = clean.nick(nick)

        try:
            api.actor_remove_contact(jid_ref, jid_ref.nick, nick)
            self.send_message((from_jid, ),
                              "%s stopped following %s" % (jid_ref.nick, nick))

        except:
            self.send_message((from_jid, ), "Leave FAILED:  %s" % nick)
Exemple #21
0
  def actor_add_contact(self, sender, nick):
    sender_ref = api.actor_lookup_mobile(api.ROOT, sender)
    if not sender_ref:
      raise exception.ValidationError(HELP_SIGN_IN)
    clean_nick = clean.nick(nick)

    try:
      api.actor_add_contact(sender_ref, sender_ref.nick, clean_nick)
      self.send_message((sender,),
                        "%s followed %s" % (sender_ref.display_nick(), nick))

    except:
      self.send_message((sender,),
                        "Failed to follow %s" % nick)
Exemple #22
0
    def actor_remove_contact(self, sender, nick):
        sender_ref = api.actor_lookup_mobile(api.ROOT, sender)
        if not sender_ref:
            raise exception.ValidationError(HELP_SIGN_IN)
        clean_nick = clean.nick(nick)

        try:
            api.actor_remove_contact(sender_ref, sender_ref.nick, clean_nick)
            self.send_message(
                (sender, ),
                "%s stopped following %s" % (sender_ref.dispaly_nick(), nick))

        except:
            self.send_message((sender, ), "Failed to stop following %s" % nick)
Exemple #23
0
  def actor_remove_contact(self, from_jid, nick):
    jid_ref = api.actor_lookup_im(api.ROOT, from_jid.base())
    if not jid_ref:
      raise exception.ValidationError(
          "You must be signed in to post, please SIGN IN")
    nick = clean.nick(nick)

    try:
      api.actor_remove_contact(jid_ref, jid_ref.nick, nick)
      self.send_message((from_jid,),
                        "%s stopped following %s" % (jid_ref.nick, nick))

    except:
      self.send_message((from_jid,),
                        "Leave FAILED:  %s" % nick)
Exemple #24
0
    def test_login_user_cleanup(self):
        log = "broken"
        pwd = self.passwords[clean.nick(log)]

        actor_ref_pre = api.actor_get(api.ROOT, log)
        self.assert_(not actor_ref_pre.normalized_nick)
        self.assertRaises(exception.ApiException, api.stream_get_presence, api.ROOT, log)
        self.assertRaises(exception.ApiException, api.stream_get_comment, api.ROOT, log)

        r = self.client.post("/login", {"log": log, "pwd": pwd})
        r = self.assertRedirectsPrefix(r, "/user/broken/overview")

        actor_ref_post = api.actor_get(api.ROOT, log)
        self.assert_(actor_ref_post.normalized_nick)
        self.assert_(api.stream_get_presence(api.ROOT, log))
        self.assert_(api.stream_get_comment(api.ROOT, log))
Exemple #25
0
def reponse_if_exists(id, service=None):
    if service is None:
        view = api.actor_lookup_email(api.ROOT, id)
    else:
        eprofile = api.get_external_profile(service, id)
        if eprofile is not None:
            nick = clean.nick(eprofile.nick)
            view = api.actor_lookup_nick(api.ROOT, nick)
        else:
            return None

    if view:
        response = http.HttpResponseRedirect(view.url("/overview"))
        response = user.set_user_cookie(response, view)
        return response

    return None
Exemple #26
0
def create_nonce(user, action, offset=0):
  if not user:
    nick = ""
  else:
    try:
      nick = user.nick
    except AttributeError:
      if settings.MANAGE_PY:
        # extra case to make testing easier
        nick = clean.nick(user)
      else:
        raise
  i = math.ceil(time.time() / 43200)
  i += offset

  nonce = hash_generic(str(i) + action + nick)
  return nonce[-12:-2]
Exemple #27
0
def create_nonce(user, action, offset=0):
    if not user:
        nick = ""
    else:
        try:
            nick = user.nick
        except AttributeError:
            if settings.MANAGE_PY:
                # extra case to make testing easier
                nick = clean.nick(user)
            else:
                raise
    i = math.ceil(time.time() / 43200)
    i += offset

    nonce = hash_generic(str(i) + action + nick)
    return nonce[-12:-2]
Exemple #28
0
    def test_login_user_cleanup(self):
        log = 'broken'
        pwd = self.passwords[clean.nick(log)]

        actor_ref_pre = api.actor_get(api.ROOT, log)
        self.assert_(not actor_ref_pre.normalized_nick)
        self.assertRaises(exception.ApiException, api.stream_get_presence,
                          api.ROOT, log)
        self.assertRaises(exception.ApiException, api.stream_get_comment,
                          api.ROOT, log)

        r = self.client.post('/login', {'log': log, 'pwd': pwd})
        r = self.assertRedirectsPrefix(r, '/user/broken/overview')

        actor_ref_post = api.actor_get(api.ROOT, log)
        self.assert_(actor_ref_post.normalized_nick)
        self.assert_(api.stream_get_presence(api.ROOT, log))
        self.assert_(api.stream_get_comment(api.ROOT, log))
Exemple #29
0
  def add_comment(self, sender, nick, message):
    sender_ref = api.actor_lookup_mobile(api.ROOT, sender)
    if not sender_ref:
      raise exception.ValidationError(HELP_SIGN_IN)

    logging.debug("comment: %s %s %s", nick, sender_ref.nick, message)

    nick = clean.nick(nick)
    stream_entry = api.reply_get_cache(sender=nick,
                                       target=sender_ref.nick,
                                       service='sms')
    if not stream_entry:
      # Well, or memcache timed it out...  Or we crashed... Or... Or...
      raise exception.ValidationError(
          'The message to which you tried to respond doesn\'t exist')

    api.entry_add_comment(sender_ref, entry=stream_entry.keyname(),
                          content=message, nick=sender_ref.nick,
                          stream=stream_entry.stream)
Exemple #30
0
  def add_comment(self, from_jid, nick, message):
    jid_ref = api.actor_lookup_im(api.ROOT, from_jid.base())
    if not jid_ref:
      raise exception.ValidationError(
          "You must be signed in to post, please SIGN IN")

    logging.debug("comment: %s %s %s", nick, jid_ref.nick, message)

    nick = clean.nick(nick)
    stream_entry = api.reply_get_cache(sender=nick, 
                                       target=jid_ref.nick, 
                                       service='im')
    if not stream_entry:
      # Well, or memcache timed it out...  Or we crashed... Or... Or...
      raise exception.ValidationError(
          'The message to which you tried to respond doesn\'t exist')

    api.entry_add_comment(jid_ref, entry=stream_entry.keyname(),
                          content=message, nick=jid_ref.nick,
                          stream=stream_entry.stream)
Exemple #31
0
    def add_comment(self, sender, nick, message):
        sender_ref = api.actor_lookup_mobile(api.ROOT, sender)
        if not sender_ref:
            raise exception.ValidationError(HELP_SIGN_IN)

        logging.debug("comment: %s %s %s", nick, sender_ref.nick, message)

        nick = clean.nick(nick)
        stream_entry = api.reply_get_cache(sender=nick,
                                           target=sender_ref.nick,
                                           service='sms')
        if not stream_entry:
            # Well, or memcache timed it out...  Or we crashed... Or... Or...
            raise exception.ValidationError(
                'The message to which you tried to respond doesn\'t exist')

        api.entry_add_comment(sender_ref,
                              entry=stream_entry.keyname(),
                              content=message,
                              nick=sender_ref.nick,
                              stream=stream_entry.stream)
Exemple #32
0
    def add_comment(self, from_jid, nick, message):
        jid_ref = api.actor_lookup_im(api.ROOT, from_jid.base())
        if not jid_ref:
            raise exception.ValidationError(
                "You must be signed in to post, please SIGN IN")

        logging.debug("comment: %s %s %s", nick, jid_ref.nick, message)

        nick = clean.nick(nick)
        stream_entry = api.reply_get_cache(sender=nick,
                                           target=jid_ref.nick,
                                           service='im')
        if not stream_entry:
            # Well, or memcache timed it out...  Or we crashed... Or... Or...
            raise exception.ValidationError(
                'The message to which you tried to respond doesn\'t exist')

        api.entry_add_comment(jid_ref,
                              entry=stream_entry.keyname(),
                              content=message,
                              nick=jid_ref.nick,
                              stream=stream_entry.stream)
Exemple #33
0
    def test_photo_upload(self):
        nick = 'popular'
        nick = clean.nick(nick)
        old_avatar = api.actor_get(api.ROOT,
                                   nick).extra.get('icon', 'avatar_default')

        self.login(nick)
        f = open('testdata/test_avatar.jpg')
        r = self.client.post(
            '/welcome/1', {
                'imgfile': f,
                '_nonce': util.create_nonce('popular', 'change_photo'),
            })
        r = self.assertRedirectsPrefix(r, '/welcome/1?')

        new_avatar = api.actor_get(api.ROOT,
                                   nick).extra.get('icon', 'avatar_default')
        self.assertNotEquals(old_avatar, new_avatar)

        self.assertContains(r, 'Avatar uploaded')
        self.assertTemplateUsed(r, 'join/templates/welcome_photo.html')
        self.assertTemplateUsed(r, 'common/templates/flash.html')
Exemple #34
0
    def test_settings_upload_avatar(self):
        nick = 'obligated'
        self.login(nick)

        nick = clean.nick(nick)
        old_contact_avatars = api.actor_get_contacts_avatars_since(
            api.ROOT, nick)
        contacts = api.actor_get_contacts(api.ROOT, nick)
        self.assertEquals(len(old_contact_avatars), len(contacts) + 1)
        old_avatar = api.actor_get(api.ROOT,
                                   nick).extra.get('icon', 'avatar_default')
        start_time = api.utcnow()
        no_contact_avatars = api.actor_get_contacts_avatars_since(
            api.ROOT, nick, since_time=start_time)
        self.assertEquals(len(no_contact_avatars), 0)

        # TODO(teemu): add more tests for different file types (gif and jpg).
        # Alternatively, test those against api.avatar_upload.
        f = open('testdata/test_avatar.jpg')
        r = self.client.post(
            '/user/obligated/settings/photo', {
                'imgfile': f,
                '_nonce': util.create_nonce('obligated', 'change_photo'),
            })
        r = self.assertRedirectsPrefix(r, '/user/obligated/settings/photo')

        actor_ref = api.actor_get(api.ROOT, nick)
        new_avatar = actor_ref.extra.get('icon', 'avatar_default')
        self.assertNotEquals(old_avatar, new_avatar)
        self.assertTrue(actor_ref.avatar_updated_at >= start_time)
        new_contact_avatars = api.actor_get_contacts_avatars_since(
            api.ROOT, nick, since_time=start_time)
        self.assertEquals(len(new_contact_avatars), 1)
        self.assertEquals(new_contact_avatars.pop().nick, nick)

        self.assertContains(r, 'Avatar uploaded')
        self.assertTemplateUsed(r, 'actor/templates/settings_photo.html')
        self.assertTemplateUsed(r, 'common/templates/flash.html')
Exemple #35
0
  def test_settings_upload_avatar(self):
    nick = 'obligated'
    self.login(nick)

    nick = clean.nick(nick)
    old_contact_avatars = api.actor_get_contacts_avatars_since(api.ROOT, nick)
    contacts = api.actor_get_contacts(api.ROOT, nick)
    self.assertEquals(len(old_contact_avatars), len(contacts) + 1)
    old_avatar = api.actor_get(api.ROOT, nick).extra.get('icon',
                                                         'avatar_default')
    start_time = api.utcnow()
    no_contact_avatars = api.actor_get_contacts_avatars_since(api.ROOT, nick,
                                                              since_time=start_time)
    self.assertEquals(len(no_contact_avatars), 0)

    # TODO(teemu): add more tests for different file types (gif and jpg).
    # Alternatively, test those against api.avatar_upload.
    f = open('testdata/test_avatar.jpg')
    r = self.client.post('/user/obligated/settings/photo',
                         {
                           'imgfile': f,
                           '_nonce' :
                              util.create_nonce('obligated', 'change_photo'),
                         })
    r = self.assertRedirectsPrefix(r, '/user/obligated/settings/photo')

    actor_ref = api.actor_get(api.ROOT, nick)
    new_avatar = actor_ref.extra.get('icon', 'avatar_default')
    self.assertNotEquals(old_avatar, new_avatar)
    self.assertTrue(actor_ref.avatar_updated_at >= start_time)
    new_contact_avatars = api.actor_get_contacts_avatars_since(api.ROOT, nick,
                                                               since_time=start_time)
    self.assertEquals(len(new_contact_avatars), 1)
    self.assertEquals(new_contact_avatars.pop().nick, nick)

    self.assertContains(r, 'Avatar uploaded')
    self.assertTemplateUsed(r, 'actor/templates/settings_photo.html')
    self.assertTemplateUsed(r, 'common/templates/flash.html')
Exemple #36
0
  def test_photo_upload(self):
    nick = 'popular'
    nick = clean.nick(nick)
    old_avatar = api.actor_get(api.ROOT, nick).extra.get('icon', 
                                                         'avatar_default')

    self.login(nick)
    f = open('testdata/test_avatar.jpg')
    r = self.client.post('/welcome/1',
                         {
                           'imgfile': f,
                           '_nonce' :
                              util.create_nonce('popular', 'change_photo'),
                         })
    r = self.assertRedirectsPrefix(r, '/welcome/1?')

    new_avatar = api.actor_get(api.ROOT, nick).extra.get('icon', 
                                                         'avatar_default')
    self.assertNotEquals(old_avatar, new_avatar)

    self.assertContains(r, 'Avatar uploaded')
    self.assertTemplateUsed(r, 'join/templates/welcome_photo.html')
    self.assertTemplateUsed(r, 'common/templates/flash.html')
Exemple #37
0
    def test_settings_change_avatar(self):
        nick = 'obligated'
        self.login(nick)

        nick = clean.nick(nick)
        old_avatar = api.actor_get(api.ROOT,
                                   nick).extra.get('icon', 'avatar_default')

        # TODO(teemu): add more tests for different file types (gif and jpg).
        # Alternatively, test those against api.avatar_upload.
        r = self.client.post(
            '/user/obligated/settings/photo', {
                'avatar': 'default/animal_9',
                '_nonce': util.create_nonce('obligated', 'change_photo'),
            })
        r = self.assertRedirectsPrefix(r, '/user/obligated/settings/photo')

        new_avatar = api.actor_get(api.ROOT,
                                   nick).extra.get('icon', 'avatar_default')
        self.assertNotEquals(old_avatar, new_avatar)

        self.assertContains(r, 'Avatar changed')
        self.assertTemplateUsed(r, 'actor/templates/settings_photo.html')
        self.assertTemplateUsed(r, 'common/templates/flash.html')
Exemple #38
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
Exemple #39
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)
Exemple #40
0
def actor_settings(request, nick, page='index'):
  """ just a static page that links to the rest"""
  nick = clean.nick(nick)

  view = api.actor_lookup_nick(api.ROOT, nick)
  if not api.actor_owns_actor(request.user, view):
    raise exception.ApiOwnerRequired(
        'Operation not allowed: %s does not own %s'
        % (request.user and request.user.nick or '(nobody)', view.nick))

  handled = common_views.handle_view_action(
      request,
      {
        'activation_activate_mobile': view.url('/settings/mobile'),
        'activation_request_email': view.url('/settings/email'),
        'activation_request_mobile': view.url('/settings/mobile'),
        'settings_change_notify': view.url('/settings/notifications'),
        'settings_change_privacy': request.path,
        'settings_update_account': view.url('/settings/profile'),
        'actor_remove': '/logout',
        #'oauth_remove_consumer': request.path,
        #'oauth_remove_access_token': request.path
      }
  )
  if handled:
    return handled



  # 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

  # TODO(tyler): Merge this into handle_view_action, if possible
  if 'password' in request.POST:
    try:
      validate.nonce(request, 'change_password')

      password = request.POST.get('password', '')
      confirm = request.POST.get('confirm', '')

      validate.password_and_confirm(password, confirm, field = 'password')

      api.settings_change_password(request.user, view.nick, password)
      response = util.RedirectFlash(view.url() + '/settings/password',
                                    'Password updated')
      request.user.password = util.hash_password(request.user.nick, password)
      # TODO(mikie): change when cookie-auth is changed
      user.set_user_cookie(response, request.user)
      return response
    except:
      exception.handle_exception(request)

  if page == 'feeds':
    try:
      if not settings.FEEDS_ENABLED:
        raise exception.DisabledFeatureError('Feeds are currently disabled')
    except:
      exception.handle_exception(request)

  if page == 'photo':
    redirect_to = view.url() + '/settings/photo'
    handled = common_views.common_photo_upload(request, redirect_to)
    if handled:
      return handled


  area = 'settings'
  full_page = page.capitalize()

  if page == 'mobile':
    full_page = 'Mobile Number'

    mobile = api.mobile_get_actor(request.user, view.nick)
    sms_notify = view.extra.get('sms_notify', False)
    
  elif page == 'im':
    full_page = 'IM Address'
    im_address = api.im_get_actor(request.user, view.nick)
    im_notify = view.extra.get('im_notify', False)
  elif page == 'index':
    email = api.email_get_actor(request.user, view.nick)
    email_notify = view.extra.get('email_notify', False)
    im_address = api.im_get_actor(request.user, view.nick)
    im_notify = view.extra.get('im_notify', False)
  elif page == 'feeds':
    full_page = 'Web Feeds'
  elif page == 'email':
    full_page = 'Email Address'
    email_notify = view.extra.get('email_notify', False)

    # check if we already have an email
    email = api.email_get_actor(request.user, view.nick) 

    # otherwise look for an unconfirmed one
    if not email:
      unconfirmeds = api.activation_get_actor_email(api.ROOT, view.nick)
      if unconfirmeds:
        unconfirmed_email = unconfirmeds[0].content

  elif page == 'design':
    handled = common_views.common_design_update(request, view.nick)
    if handled:
      return handled
    full_page = 'Look and Feel'

  elif page == 'notifications':
    email = api.email_get_actor(request.user, view.nick)
    email_notify = view.extra.get('email_notify', False)
    im_address = api.im_get_actor(request.user, view.nick)
    im_notify = view.extra.get('im_notify', False)
    mobile = api.mobile_get_actor(request.user, request.user.nick)
    sms_notify = view.extra.get('sms_notify', False)

    sms_confirm = sms_notify and not view.extra.get('sms_confirmed', False)
    # TODO(termie): remove this once we can actually receive sms
    sms_confirm = False
  elif page == 'profile':
    # check if we already have an email
    email = api.email_get_actor(request.user, view.nick) 

    # otherwise look for an unconfirmed one
    if not email:
      unconfirmeds = api.activation_get_actor_email(api.ROOT, view.nick)
      if unconfirmeds:
        unconfirmed_email = unconfirmeds[0].content

  elif page == 'photo':
    avatars = display.DEFAULT_AVATARS
    small_photos = api.image_get_all_keys(request.user, view.nick, size='f')

    # TODO(tyler): Fix this avatar nonsense!
    own_photos = [{
        'path' : small_photo.key().name(),
        'name' : small_photo.key().name()[len('image/'):-len('_f.jpg')],
      } for small_photo in small_photos
    ]

  elif page == 'privacy':
    PRIVACY_PUBLIC = api.PRIVACY_PUBLIC
    PRIVACY_CONTACTS = api.PRIVACY_CONTACTS
  elif page == 'jsbadge':
    full_page = 'Javascript Badges'
  elif page == 'badge':
    badges = [{'id': 'badge-stream',
               'width': '200',
               'height': '300',
               'src': '/themes/%s/badge.swf' % settings.DEFAULT_THEME,
               'title': 'Stream',
               },
              {'id': 'badge-map',
               'width': '200',
               'height': '255',
               'src': '/themes/%s/badge-map.swf' % settings.DEFAULT_THEME,
               'title': 'Map',
               },
              {'id': 'badge-simple',
               'width': '200',
               'height': '200',
               'src': '/themes/%s/badge-simple.swf' % settings.DEFAULT_THEME,
               'title': 'Simple',
               },
              ]

  elif page in ['password', 'delete']:
    # Catch for remaining pages before we generate a 404.
    pass

  else:
    return common_views.common_404(request)

  # rendering
  c = template.RequestContext(request, locals())
  t = loader.get_template('actor/templates/settings_%s.html' % page)
  return http.HttpResponse(t.render(c))
Exemple #41
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
Exemple #42
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')
    r = http.HttpResponse(t.render(c))
    r['Content-type'] = 'text/javascript'
    return r
Exemple #43
0
 def sign_in(self, nick, sender=None):
     password = self.passwords[clean.nick(nick)]
     r = self.receive('SIGN IN %s %s' % (nick, password), sender=sender)
     return r
Exemple #44
0
 def login(self, nick, password=None):
   if not password:
     password = self.passwords[clean.nick(nick)]
   r = self.client.post('/login', {'log': nick, 'pwd': password})
   return
Exemple #45
0
 def login(self, nick, password=None):
   if not password:
     password = self.passwords[clean.nick(nick)]
   r = self.client.post('/login', {'log': nick, 'pwd': password})
   return
Exemple #46
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)
Exemple #47
0
  def test_sign_in(self):
    nick = 'popular'
    password = self.passwords[clean.nick(nick)]

    r = self.receive('SIGN IN %s %s' % (nick, password))
    self.assertOutboxContains(r, 'Welcome to %s SMS %s' % (util.get_metadata('SITE_NAME'), nick))
Exemple #48
0
 def login(self, nick, password=None):
     if not password:
         password = self.passwords[clean.nick(nick)]
     r = self.client.post("/login", {"log": nick, "pwd": password})
     return
Exemple #49
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)
Exemple #50
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)
Exemple #51
0
def actor_settings(request, nick, page='index'):
    """ just a static page that links to the rest"""
    nick = clean.nick(nick)

    view = api.actor_lookup_nick(api.ROOT, nick)
    if not api.actor_owns_actor(request.user, view):
        raise exception.ApiOwnerRequired(
            'Operation not allowed: %s does not own %s' %
            (request.user and request.user.nick or '(nobody)', view.nick))

    handled = common_views.handle_view_action(
        request,
        {
            'activation_activate_mobile': view.url('/settings/mobile'),
            'activation_request_email': view.url('/settings/email'),
            'activation_request_mobile': view.url('/settings/mobile'),
            'settings_change_notify': view.url('/settings/notifications'),
            'settings_change_privacy': request.path,
            'settings_update_account': view.url('/settings/profile'),
            'actor_remove': '/logout',
            #'oauth_remove_consumer': request.path,
            #'oauth_remove_access_token': request.path
        })
    if handled:
        return handled

    # 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

    # TODO(tyler): Merge this into handle_view_action, if possible
    if 'password' in request.POST:
        try:
            validate.nonce(request, 'change_password')

            password = request.POST.get('password', '')
            confirm = request.POST.get('confirm', '')

            validate.password_and_confirm(password, confirm, field='password')

            api.settings_change_password(request.user, view.nick, password)
            response = util.RedirectFlash(view.url() + '/settings/password',
                                          'Password updated')
            request.user.password = util.hash_password(request.user.nick,
                                                       password)
            # TODO(mikie): change when cookie-auth is changed
            user.set_user_cookie(response, request.user)
            return response
        except:
            exception.handle_exception(request)

    if page == 'feeds':
        try:
            if not settings.FEEDS_ENABLED:
                raise exception.DisabledFeatureError(
                    'Feeds are currently disabled')
        except:
            exception.handle_exception(request)

    if page == 'photo':
        redirect_to = view.url() + '/settings/photo'
        handled = common_views.common_photo_upload(request, redirect_to)
        if handled:
            return handled

    area = 'settings'
    full_page = page.capitalize()

    if page == 'mobile':
        full_page = 'Mobile Number'

        mobile = api.mobile_get_actor(request.user, view.nick)
        sms_notify = view.extra.get('sms_notify', False)

    elif page == 'im':
        full_page = 'IM Address'
        im_address = api.im_get_actor(request.user, view.nick)
        im_notify = view.extra.get('im_notify', False)
    elif page == 'index':
        email = api.email_get_actor(request.user, view.nick)
        email_notify = view.extra.get('email_notify', False)
        im_address = api.im_get_actor(request.user, view.nick)
        im_notify = view.extra.get('im_notify', False)
    elif page == 'feeds':
        full_page = 'Web Feeds'
    elif page == 'email':
        full_page = 'Email Address'
        email_notify = view.extra.get('email_notify', False)

        # check if we already have an email
        email = api.email_get_actor(request.user, view.nick)

        # otherwise look for an unconfirmed one
        if not email:
            unconfirmeds = api.activation_get_actor_email(api.ROOT, view.nick)
            if unconfirmeds:
                unconfirmed_email = unconfirmeds[0].content

    elif page == 'design':
        handled = common_views.common_design_update(request, view.nick)
        if handled:
            return handled
        full_page = 'Look and Feel'

    elif page == 'notifications':
        email = api.email_get_actor(request.user, view.nick)
        email_notify = view.extra.get('email_notify', False)
        im_address = api.im_get_actor(request.user, view.nick)
        im_notify = view.extra.get('im_notify', False)
        mobile = api.mobile_get_actor(request.user, request.user.nick)
        sms_notify = view.extra.get('sms_notify', False)

        sms_confirm = sms_notify and not view.extra.get('sms_confirmed', False)
        # TODO(termie): remove this once we can actually receive sms
        sms_confirm = False
    elif page == 'profile':
        # check if we already have an email
        email = api.email_get_actor(request.user, view.nick)

        # otherwise look for an unconfirmed one
        if not email:
            unconfirmeds = api.activation_get_actor_email(api.ROOT, view.nick)
            if unconfirmeds:
                unconfirmed_email = unconfirmeds[0].content

    elif page == 'photo':
        avatars = display.DEFAULT_AVATARS
        small_photos = api.image_get_all_keys(request.user,
                                              view.nick,
                                              size='f')

        # TODO(tyler): Fix this avatar nonsense!
        own_photos = [{
            'path':
            small_photo.key().name(),
            'name':
            small_photo.key().name()[len('image/'):-len('_f.jpg')],
        } for small_photo in small_photos]

    elif page == 'privacy':
        PRIVACY_PUBLIC = api.PRIVACY_PUBLIC
        PRIVACY_CONTACTS = api.PRIVACY_CONTACTS
    elif page in ['password', 'delete']:
        # Catch for remaining pages before we generate a 404.
        pass

    else:
        return common_views.common_404(request)

    # rendering
    c = template.RequestContext(request, locals())
    t = loader.get_template('actor/templates/settings_%s.html' % page)
    return http.HttpResponse(t.render(c))
Exemple #52
0
 def sign_in(self, from_jid, nick, password=None):
     if not password:
         password = self.passwords[clean.nick(nick)]
     message = 'SIGN IN %s %s' % (nick, password)
     return self.send(from_jid, message)
Exemple #53
0
 def sign_in(self, nick, sender=None):
   password = self.passwords[clean.nick(nick)]
   r = self.receive('SIGN IN %s %s' % (nick, password), sender=sender)
   return r
Exemple #54
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)
Exemple #55
0
 def sign_in(self, from_jid, nick, password=None):
   if not password:
     password = self.passwords[clean.nick(nick)]
   message = 'SIGN IN %s %s' % (nick, password)
   return self.send(from_jid, message)
Exemple #56
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)