Exemple #1
0
def common_design_update(request, nick):
    view = api.actor_get(api.ROOT, nick)
    if request.POST:
        try:
            validate.nonce(request, 'update_design')

            color = request.POST.get('bg_color')
            repeat = request.POST.get('bg_repeat', 'no-repeat')
            if not repeat:
                repeat = ''

            img = request.FILES.get('bg_image')
            img_url = None
            if img:
                img_url = api.background_upload(request.user, nick, img.read())
            api.background_set_actor(request.user, nick, img_url, color,
                                     repeat)
            return util.RedirectFlash(view.url() + '/settings/design',
                                      'design updated')
        except:
            exception.handle_exception(request)

    if request.GET and 'restore' in request.GET:
        api.background_clear_actor(request.user, nick)
        return util.RedirectFlash(view.url() + '/settings/design',
                                  'design updated')

    return None
Exemple #2
0
def api_keys(request):

    # special case this because we want to redirect to the edit page
    if 'oauth_generate_consumer' in request.POST:
        action = 'oauth_generate_consumer'
        (called, rv) = common_views.call_api_from_request(request, action)
        return util.RedirectFlash(rv.url(), messages.flash(action))

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

    # Get list of consumer tokenss for this actor
    consumer_tokens = api.oauth_get_actor_consumers(request.user,
                                                    request.user.nick)

    # TODO(termie): Get list of access tokens this actor has given others
    access_tokens = []

    # for templates
    full_page = 'Keys'
    page = 'keys'
    area = 'api'

    c = template.RequestContext(request, locals())
    t = loader.get_template('api/templates/keys.html')
    return http.HttpResponse(t.render(c))
Exemple #3
0
def install_rootuser(request):
    # requires an admin
    user = users.get_current_user()
    if not user:
        return http.HttpResponseRedirect(users.create_login_url('/install'))
    else:
        if not users.is_current_user_admin():
            return http.HttpResponseRedirect('/')

    try:
        root_user = api.actor_get(api.ROOT, settings.ROOT_NICK)
    except:
        root_user = None

    if request.POST:
        try:
            logging.warning('Making root user: %s', settings.ROOT_NICK)
            validate.nonce(request, 'create_root')
            root_user = api.user_create_root(api.ROOT)
            return util.RedirectFlash('/install', 'Root user created')
        except:
            exception.handle_exception(request)

    redirect_to = '/'

    c = template.RequestContext(request, locals())
    t = loader.get_template('install/templates/rootuser.html')
    return http.HttpResponse(t.render(c))
Exemple #4
0
def handle_view_action(request, actions):
    """Call an API function based on the request parameters if there is a match
  to the keys in 'actions'. Redirect to the corresponding value in 'actions'
  after the call.
  """
    for action in actions.keys():
        called, ret = call_api_from_request(request, action)
        if called:
            redirect = actions[action]
            return util.RedirectFlash(redirect, messages.flash(action))
    return None
Exemple #5
0
def common_photo_upload(request, success="/", nick=None):
    if not nick:
        nick = request.user.nick
    if request.FILES:
        try:
            # we're going to handle a file upload, wee
            validate.nonce(request, 'change_photo')
            img = request.FILES.get('imgfile')

            if not img:
                raise exception.ValidationError('imgfile must be set')
            validate.avatar_photo_size(img)

            img_url = api.avatar_upload(request.user, nick, img.read())
            api.avatar_set_actor(request.user, nick, img_url)
            return util.RedirectFlash(success, "Avatar uploaded")
        except:
            exception.handle_exception(request)

    elif 'avatar' in request.POST:
        try:
            validate.nonce(request, 'change_photo')
            avatar_path = request.POST.get('avatar')
            if not avatar_path:
                raise exception.ValidationError('avatar must be set')

            rv = api.avatar_set_actor(request.user, nick, avatar_path)
            if not rv:
                raise exception.ValidationError('failed to set avatar')
            return util.RedirectFlash(success, "Avatar changed")
        except:
            exception.handle_exception(request)

    if 'delete' in request.REQUEST:
        try:
            validate.nonce(request, 'delete_photo')
            validate.confirm_dangerous(request, 'Delete your photo?')
            rv = api.avatar_clear_actor(request.user, nick)
            return util.RedirectFlash(success, "Avatar deleted")
        except:
            exception.handle_exception(request)
Exemple #6
0
def confirm_email(request, code):
    rel_ref = api.activation_activate_email(request.user, request.user.nick,
                                            code)
    return util.RedirectFlash(request.user.url() + "/overview",
                              "Email address '%s' confirmed." % rel_ref.target)
Exemple #7
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 #8
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 #9
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 #10
0
def common_listings(request, nick, listings, template_name):
    view = api.actor_get(api.ROOT, nick)
    if request.POST:
        logging.info("Post Request: %s" % request.POST)
        try:
            # Add Listing Action
            logging.info("Action: %s" % request.POST.get("action"))
            if request.POST.get("action") == "add_listing":
                author = view.nick
                logging.info(
                    "Calling Create Listing - Params: %s, Author: %s" %
                    (request.POST, author))
                address = request.POST.get("address")
                price = request.POST.get("price")
                baths = request.POST.get("baths")
                beds = request.POST.get("beds")
                size = request.POST.get("size")
                description = request.POST.get("description")
                property_type = request.POST.get("property_type")
                amenities = request.POST.get("amenities")
                tag = request.POST.get("tag")
                galleryUrl = request.POST.get("galleryUrl")
                handled = api.add_listing(address, price, baths, beds, size,
                                          description, property_type,
                                          amenities, author, tag, galleryUrl)

        # Edit Listings Page
            if request.POST.get("action") == "edit_listing":
                author = view.nick
                logging.info(
                    "Calling Edit Listing - Params: %s, Author: %s, Key: %s" %
                    (request.POST, author, request.POST.get("id")))
                id = request.POST.get("id")
                address = request.POST.get("address")
                price = request.POST.get("price")
                baths = request.POST.get("baths")
                beds = request.POST.get("beds")
                size = request.POST.get("size")
                description = request.POST.get("description")
                property_type = request.POST.get("property_type")
                amenities = request.POST.get("amenities")
                tag = request.POST.get("tag")
                galleryUrl = request.POST.get("galleryUrl")
                handled = api.edit_listing(id, address, price, baths, beds,
                                           size, description, property_type,
                                           amenities, author, tag, galleryUrl)

            return util.RedirectFlash(view.url() + '/settings/listings',
                                      'listings updated')
        except:
            exception.handle_exception(request)

    if request.GET and 'restore' in request.GET:
        api.background_clear_actor(request.user, nick)
        return util.RedirectFlash(view.url() + '/settings/listings',
                                  'listings updated')

    model = {}

    if request.GET.get("action") == "edit" and request.GET.get("id"):
        editListingId = request.GET.get("id")
        if editListingId:
            key = Key(editListingId)
            logging.info("ID: %s" % key)
            obj = db.get(key)
            model['edit'] = obj

    model['listings'] = listings
    logging.info("Model: %s" % model)
    t = loader.get_template(template_name)
    return http.HttpResponse(t.render(template.RequestContext(request, model)))
Exemple #11
0
def join_welcome_contacts(request):
    """
  if we have an access token for this user attempt to fetch the contacts
  else if we have a request token attempt to get an access token
  if we have neither
    if we are trying to authorize, grab a request token and redirect to authorize page
    else
      show the page
  """
    redirect_to = get_clean_redirect(request)
    next = '/welcome/done'

    # these are for the find more contacts bits
    start_index = int(request.REQUEST.get('index', 1))
    max = 100
    token = request.REQUEST.get('token')
    contacts_more = int(request.REQUEST.get('contacts_more', 0))
    # this won't be seen unless contacts_more is positive,
    # so no worries about the possible negative value
    contacts_so_far = contacts_more - 1

    try:
        if not settings.GOOGLE_CONTACTS_IMPORT_ENABLED:
            raise exception.FeatureDisabledError(
                'Google Contacts import is currently disabled')

        if 'lookup_remote_contacts' in request.POST:
            validate.nonce(request, 'lookup_remote_contacts')

            next_url = util.qsa(
                util.here(request), {
                    'redirect_to':
                    redirect_to,
                    'upgrade_auth_token':
                    '',
                    '_nonce':
                    util.create_nonce(request.user, 'upgrade_auth_token'),
                })
            auth_url = google_contacts.auth_sub_url(next_url)
            return http.HttpResponseRedirect(auth_url)
        elif 'actor_add_contacts' in request.POST:
            validate.nonce(request, 'actor_add_contacts')

            targets = request.POST.getlist('targets')
            owner = request.POST.get('owner', '')

            rv = api.actor_add_contacts(request.user, owner, targets)

            next_url = util.qsa(
                util.here(request), {
                    'redirect_to': redirect_to,
                    'contacts_more': contacts_more,
                    'index': start_index,
                    'token': token,
                })

            return util.RedirectFlash(next_url, 'Contacts added.')

        elif 'upgrade_auth_token' in request.GET:
            validate.nonce(request, 'upgrade_auth_token')

            auth_token = google_contacts.auth_sub_token_from_request(request)
            session_token = google_contacts.upgrade_to_session_token(
                auth_token)

            next_url = util.qsa(
                util.here(request), {
                    'redirect_to': redirect_to,
                    'fetch_contacts': '',
                    'token': session_token.get_token_string(),
                    '_nonce': util.create_nonce(request.user,
                                                'fetch_contacts'),
                })

            return http.HttpResponseRedirect(next_url)

        elif 'fetch_contacts' in request.REQUEST:
            validate.nonce(request, 'fetch_contacts')

            # start_index and max are gathered above
            session_token = google_contacts.auth_sub_token_from_request(
                request)

            # check for the "My Contacts" group, otherwise, fetch it
            my_contacts = memcache.client.get('%s/my_contacts' % token)
            if not my_contacts:
                my_contacts = google_contacts.get_system_group(
                    session_token, 'Contacts')
                memcache.client.set('%s/my_contacts' % token, my_contacts)

            rv, more = google_contacts.get_contacts_emails(session_token,
                                                           group=my_contacts,
                                                           index=start_index,
                                                           max=max)

            contacts = []

            for name, email in rv:
                logging.info('looking up "%s" %s', name, email)
                contacts.append(api.actor_lookup_email(request.user, email))

            contacts = [x for x in contacts if x]

            # for the template
            contacts_found = True
            contacts_more = more
            contacts_so_far = contacts_more - 1
            token = session_token.get_token_string()
            contacts_emails = rv

            # if no contacts were found and more are available, try some more
            if not contacts and contacts_more:
                next_url = util.qsa(
                    util.here(request), {
                        'fetch_contacts': '',
                        'contacts_more': contacts_more,
                        'index': contacts_more,
                        'token': token,
                        '_nonce': util.create_nonce(request.user,
                                                    'fetch_contacts'),
                        'redirect_to': redirect_to,
                    })
                # TODO(termie): this can take a really long time, probably not really
                #               viable until we can do it with javascript
                #return util.MetaRefresh(next_url, message='Still working...', second=1)
                #return http.HttpResponseRedirect(next_url)

    except:
        exception.handle_exception(request)

    # set the progress
    welcome_photo = True
    welcome_mobile = True

    view = request.user
    page = 'contacts'

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

    t = loader.get_template('join/templates/welcome_%s.html' % page)
    return http.HttpResponse(t.render(c))