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
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))
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))
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
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)
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)
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))
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)
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
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)))
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))