def post_android(request): """ post from an android phone. thanks to some omissions on the platform (like an easy way to serialize up a MIME document)*, we do this a little differently: the params are HTTP headers and the image (if there is one) is the request body. * there probably is one; I didn't look too hard """ #ctx = get_basic_context(request, is_mobile = True) reply_to = default_int(request.META.get(REPLY_TO_HTTP_HEADER, None), -1) has_image = request.META.get(HAS_IMAGE_HTTP_HEADER, None) == YES raw_content = request.META.get(CONTENT_HTTP_HEADER, None) owner_token = request.META.get(OWNER_TOKEN_HTTP_HEADER, None) #assert owner_token # FIXME: don't require this ; some ppl have older clients content = urllib.unquote(raw_content.replace("+"," "))\ .decode('utf8', 'replace') if raw_content else None # FIXME: in the dev version of django, we can use a file-like # iface and skip the stringio imagedata = request.raw_post_data image = None if imagedata: image = save_image(StringIO.StringIO(imagedata)) assert image or not has_image reply_to_post = Post.objects.get(id=reply_to, censored=False) \ if reply_to != -1 else None newpost = make_real_post(request, owner_token, get_current_loc(request), content, get_current_rounding(request), reply_to_post, picture = image, source=ANDROID) return HttpResponse(content=str(newpost.id), status=200)
def get_single_post_ajax(request): """ get just the postbox for a single post """ ctx = get_basic_context(request) assert ctx['loc'] postid = request.REQUEST.get('postid', None) if str(request.REQUEST.get("is_mobile", "0")) == "1": ctx['is_mobile'] = True # force it to be true truncate = default_int(request.REQUEST.get('truncate', 0), 0) if not postid: return Http404("No post id supplied.") # update_onepost_context(ctx, postid, define_single_post = True, # truncate = truncate) found = Post.objects.filter(id=postid, censored=False) assert len(found) == 1 ctx['posts'] = found ctx['onepostmode'] = True ctx['post'] = found[0] ctx['threadmap'] = build_thread_map(ctx['posts'], truncate) if ctx['posts']: if request.REQUEST.get('json', False): return HttpResponse(wrap_json_posts(ctx['loc'], \ serialize_posts_to_list(ctx['posts'], ctx['threadmap'], get_owner_token(request)))) else: return render_to_response('postbox.html', ctx) else: return Http404("No post with that id.")
def post_ajax(request): """ actually make a post via ajax. note that this kind of post can't have an image unless it's uploaded separately. """ parsedpost = urlparse.parse_qs(str(request.POST['form'])) # FIXME: is the csrf stuff needed? csrftoken = request.COOKIES.get('csrftoken', None) if not csrftoken: return HttpResponse(json.dumps(['fail', 'csrf token missing'])) if csrftoken != parsedpost.get('csrfmiddlewaretoken', [None])[0]: return HttpResponse(json.dumps(\ ['fail', 'csrf token mismatch %s %s' \ % (csrftoken, parsedpost['csrfmiddlewaretoken'])])) owner_token = parsedpost.get('owner_token', [None])[0] if not owner_token: owner_token = get_owner_token(request, cookie_only=True) #if not owner_token: # fixme: shouldn not require this... # return HttpResponse(json.dumps(['fail', 'owner_token missing'])) #rounding = default_int(parsedpost.get('round', [None])[0], c.DEFAULT_ROUNDING) # FIXME: if rounding-editing is re-enabled, we should use the above not this rounding = get_current_rounding(request) loc = string_to_location(parsedpost.get('loc', [None])[0]) if not loc: return HttpResponse(json.dumps(['fail', 'location invalid'])) content = parsedpost.get('content', [None])[0] if not content: return HttpResponse(json.dumps(['fail', 'post was blank'])) if len(content) > MAX_POST_LEN: return HttpResponse(json.dumps(['fail', 'post must be under %d characters' % MAX_POST_LEN])) # content = raw_extract(content) content = content.decode('utf-8', 'ignore') antidupetoken = parsedpost.get('antidupetoken', None) if not antidupetoken: return HttpResponse(json.dumps(['fail', 'antidupetoken missing'])) if antidupetoken == request.session.get('antidupetoken',''): return HttpResponse(json.dumps(['fail', 'duplicate post ignored'])) reply_to = default_int(parsedpost.get('reply_to', [None])[0], -1) reply_to = reply_to if reply_to and reply_to != -1 else None if reply_to == None: return HttpResponse(json.dumps(['fail', 'All thread-creating posts' ' must contain an image.'])) else: found = Post.objects.filter(id=reply_to, censored=False) if len(found) == 1: reply_to = found[0] else: return HttpResponse(\ json.dumps(['fail', 'internal error: invalid reply_to id.'])) make_real_post(request, owner_token, loc, content, rounding, reply_to, source=MOBILE_WEB if use_mobile(request) else WEB) request.session['antidupetoken'] = antidupetoken return HttpResponse(json.dumps(['ok', '']))
def get_latest_ajax(request): """ get the latest via ajax """ ctx = get_basic_context(request) if str(request.REQUEST.get("is_mobile", "0")) == "1": ctx['is_mobile'] = True # force it to be true skip = [default_int(item, None) for item in \ request.REQUEST.get("skip", "").split(",")] postids = [default_int(item, None) for item in \ request.REQUEST.get("postids", "").split(",")] use_only_these = not not request.REQUEST.get("only_these_postids", False) skip = [item for item in skip if item] # fixme: check loc cookie! # FIXME: radius!! ctx['posts'] = get_latest(ctx['loc'], radius=get_current_radius(request), skiplist = skip, includelist=postids, only_these_postids = use_only_these) if request.REQUEST.get('return_empty_if_none', False) and not ctx['posts']: return HttpResponse(status=204, content="") truncate_to = 0 if request.REQUEST.get('show_all_replies', False) \ else SHOW_REPLY_COUNT ctx['threadmap'] = build_thread_map(ctx['posts'], truncate=truncate_to) if request.REQUEST.get('json', False): # note that remote_owner_token is *ignored* in the multipost view remote_owner_token = get_owner_token(request) return HttpResponse(\ wrap_json_posts(ctx['loc'], serialize_posts_to_list(\ ctx['posts'], ctx['threadmap'], remote_owner_token))) else: return render_to_response('posts_div_contents.html', ctx)
def conventional_post(request): """ handle a conventional post (used to handle a file upload) -> take the post and redirect the user to the main page """ postform = forms.PostForm(request.POST, request.FILES) if not postform.is_valid(): # FIXME: this is incredibly user-unfriendly, but all errors # should be caught by the javascript before we get # here. anything that gets this far is a serious problem with # the site, not a user-input error. return HttpResponse(content="Error: %s. Please click the back" " button to correct it." % postform.errors) # this is also bad, but it's the consequence of the redirect to # /conventional-post. we could do a second redirect back to / and # save the form state so we could show the user an error message, # but, quite frankly, I think errors of this sort will be rare. if request.FILES['picture_file'].size > MAXFILESIZE: return HttpResponse(content=("Error: file too large (%d bytes)."\ " Maximum permitted is %d bytes. "\ "Please click the back button " "and submit a smaller file.")\ % (request.FILES['picture_file'].size, MAXFILESIZE)) picture = save_image(request.FILES['picture_file']) if not picture: return HttpResponse(content=("Error: could not save picture. " "It might be invalid. " " Please click the back button and" " submit a different image.")) owner_token = get_owner_token(request) # FIXME; we shouldn't _require_ this # if not owner_token: # return HttpResponse(content=("Post error: owner_token missing." # " Are cookies disabled? " # "Try enabling cookies, reloading the page," # " and reposting.")) reply_to = default_int(request.POST.get('reply_to', None), -1) reply_to = reply_to if reply_to and reply_to != -1 else None if reply_to != None: found = Post.objects.filter(id=reply_to, censored=False) if len(found) == 1: reply_to = found[0] else: # FIXME: log these return HttpResponse(content=("Internal error: invalid reply_to id." " Try pressing the back button," " reloading the page, and reposting.")) newpost = make_real_post(request, owner_token, get_current_loc(request), request.POST.get('content'), get_current_rounding(request), reply_to, picture = picture, source=MOBILE_WEB if use_mobile(request) else WEB) response = HttpResponse(content="Post successful! Redirecting...", status=303) # note that in_thread_view means *single* thread view. in_thread_view = request.REQUEST.get('in_thread_view', None)=="1" response["Location"] = ("/m/" if use_mobile(request) else "/") \ + (("thread/"+str(reply_to.id)) if in_thread_view else "") \ + "#postchildbox_" + str(newpost.id) return response