Example #1
0
def view_gallery(thread_id):
    posts = ThreadPosts().retrieve(thread_id)
    thread = db.session.query(Thread).filter(Thread.id == thread_id).one()
    board_id = thread.board
    return render_template("gallery.html",
                           thread_id=thread_id,
                           board_id=board_id,
                           posts=posts)
Example #2
0
def delete(thread_id):
    if not get_slip() or not (get_slip().is_admin or get_slip().is_mod):
        flash("Only moderators and admins can delete threads!")
        return redirect(url_for("threads.view", thread_id=thread_id))
    thread = db.session.query(Thread).filter(Thread.id == thread_id).one()
    board_id = thread.board
    ThreadPosts().delete(thread_id)
    flash("Thread deleted!")
    return redirect(url_for("boards.catalog", board_id=board_id))
Example #3
0
def render_post(post_id):
    raw_post = db.session.query(Post).get(post_id)
    thread_id = raw_post.thread
    thread = db.session.query(Thread).get(thread_id)
    dummy_array = ThreadPosts()._json_friendly([raw_post], thread)
    render_for_threads(dummy_array)
    post = dummy_array[0]
    reply_urls = _get_reply_urls([post])
    # TODO: properly set is_op, will be False most times, so set to that for now
    is_op = False
    return render_template("post-view-single.html", post=post, thread_id=thread_id, is_op=is_op, reply_urls=reply_urls)
Example #4
0
def view_gallery(thread_id):
    posts = ThreadPosts().retrieve(thread_id)
    for post in posts:
        # TODO: either streamline what gets sent to the frontend
        # or automatically serialize datetimes so the below isn't necessary
        del post["datetime"]
        post["thumb_url"] = storage.get_thumb_url(post["media"])
        post["media_url"] = storage.get_media_url(post["media"],
                                                  post["media_ext"])
    thread = db.session.query(Thread).filter(Thread.id == thread_id).one()
    board = db.session.query(Board).get(thread.board)
    return renderer.render_thread_gallery(board, thread_id, posts)
Example #5
0
 def get(self, post_id):
     post = Post.query.get(post_id)
     thread = post.thread
     # TODO: consider fetching only a single post instead of going through ThreadPosts
     # 999 times out of 1000 this will hit cache and be pretty fast, but it's somewhat ugly
     all_posts = ThreadPosts().retrieve(thread)
     post_json = None
     for p in all_posts:
         if p["id"] == post_id:
             post_json = p
             break
     render_individual(post_json)
     return jsonify(post_json)
Example #6
0
def view(thread_id):
    thread = db.session.query(Thread).filter(Thread.id == thread_id).one()
    thread.views += 1
    db.session.add(thread)
    db.session.commit()
    current_theme = session.get("theme") or app.config.get("DEFAULT_THEME") or "stock"
    response_cache_key = "thread-%d-%d-%s-render" % (thread_id, get_slip_bitmask(), current_theme)
    cache_connection = cache.Cache()
    view_key = "thread-%d-views" % thread_id
    cached_views = cache_connection.get(view_key)
    fetch_from_cache = True
    if cached_views is None:
        fetch_from_cache = False
    else:
        cached_views = int(cached_views)
    if fetch_from_cache and (thread.views / cached_views) >= app.config.get("CACHE_VIEW_RATIO", 0):
        fetch_from_cache = False
    etag_value = "%s-%f" % (response_cache_key, time.time())
    etag_cache_key = "%s-etag" % response_cache_key
    if fetch_from_cache:
        etag_header = request.headers.get("If-None-Match")
        current_etag = cache_connection.get(etag_cache_key)
        if etag_header:
            parsed_etag = parse_etags(etag_header)
            if parsed_etag.contains_weak(current_etag):
                 return make_response("", 304)
        cache_response_body = cache_connection.get(response_cache_key)
        if cache_response_body is not None:
            cached_response = make_response(cache_response_body)
            cached_response.set_etag(current_etag, weak=True)
            cached_response.headers["Cache-Control"] = "public,must-revalidate"
            return cached_response
    posts = ThreadPosts().retrieve(thread_id)
    render_for_threads(posts)
    board = db.session.query(Board).get(thread.board)
    num_posters = db.session.query(Poster).filter(Poster.thread == thread_id).count()
    num_media = thread.num_media()
    reply_urls = _get_reply_urls(posts)
    template = render_template("thread.html", thread_id=thread_id, board=board, posts=posts, num_views=thread.views,
                               num_media=num_media, num_posters=num_posters, reply_urls=reply_urls)
    uncached_response = make_response(template)
    uncached_response.set_etag(etag_value, weak=True)
    uncached_response.headers["Cache-Control"] = "public,must-revalidate"
    cache_connection.set(view_key, str(thread.views))
    cache_connection.set(response_cache_key, template)
    cache_connection.set(etag_cache_key, etag_value)
    return uncached_response
Example #7
0
def view(thread_id):
    posts = ThreadPosts().retrieve(thread_id)
    render_for_threads(posts)
    thread = db.session.query(Thread).filter(Thread.id == thread_id).one()
    thread.views += 1
    db.session.add(thread)
    db.session.commit()
    board_id = thread.board
    num_posters = db.session.query(Poster).filter(
        Poster.thread == thread_id).count()
    num_media = thread.num_media()
    return render_template("thread.html",
                           thread_id=thread_id,
                           board_id=board_id,
                           posts=posts,
                           num_views=thread.views,
                           num_media=num_media,
                           num_posters=num_posters)
Example #8
0
def view(thread_id):
    thread = db.session.query(Thread).filter(Thread.id == thread_id).one()
    thread.views += 1
    db.session.add(thread)
    db.session.commit()
    current_theme = session.get("theme") or app.config.get(
        "DEFAULT_THEME") or "stock"
    response_cache_key = "thread-%d-%d-%s-render" % (
        thread_id, get_slip_bitmask(), current_theme)
    cache_connection = cache.Cache()
    view_key = "thread-%d-views" % thread_id
    cached_views = cache_connection.get(view_key)
    fetch_from_cache = True
    if cached_views is None:
        fetch_from_cache = False
    else:
        cached_views = int(cached_views)
    if fetch_from_cache and (thread.views / cached_views) >= app.config.get(
            "CACHE_VIEW_RATIO", 0):
        fetch_from_cache = False
    etag_value = "%s-%f" % (response_cache_key, time.time())
    etag_cache_key = "%s-etag" % response_cache_key
    if fetch_from_cache:
        etag_header = request.headers.get("If-None-Match")
        current_etag = cache_connection.get(etag_cache_key)
        if etag_header:
            parsed_etag = parse_etags(etag_header)
            if parsed_etag.contains_weak(current_etag):
                return make_response("", 304)
        cache_response_body = cache_connection.get(response_cache_key)
        if cache_response_body is not None:
            cached_response = make_response(cache_response_body)
            cached_response.set_etag(current_etag, weak=True)
            cached_response.headers["Cache-Control"] = "public,must-revalidate"
            return cached_response
    posts = ThreadPosts().retrieve(thread_id)
    render_for_threads(posts)
    board = db.session.query(Board).get(thread.board)
    num_posters = db.session.query(Poster).filter(
        Poster.thread == thread_id).count()
    num_media = thread.num_media()
    reply_urls = _get_reply_urls(posts)
    thread_data = {}
    for post in posts:
        post["datetime"] = post["datetime"].strftime(
            "%a, %d %b %Y %H:%M:%S UTC")
        if post["media"]:
            post["media_url"] = storage.get_media_url(post["media"],
                                                      post["media_ext"])
            post["thumb_url"] = storage.get_thumb_url(post["media"])
    thread_data["posts"] = posts
    extra_data = {}
    if app.config.get("CAPTCHA_METHOD") == "CAPTCHOULI":
        extra_data = renderer.captchouli_to_json(captchouli.request_captcha())
    template = renderer.render_thread(thread_data, thread_id, extra_data)
    uncached_response = make_response(template)
    uncached_response.set_etag(etag_value, weak=True)
    uncached_response.headers["Cache-Control"] = "public,must-revalidate"
    cache_connection.set(view_key, str(thread.views))
    cache_connection.set(response_cache_key, template)
    cache_connection.set(etag_cache_key, etag_value)
    return uncached_response