Esempio n. 1
0
def show_post(post, string, seen):
    if 'authorUserName' in post:
        user = post['authorUserName']
    elif 'authorSlug' in post:
        user = post['authorSlug']
    else:
        user = post['authorDisplayName']
    result = (
        '''<div style="border: 1px solid #B3B3B3; margin: 10px; padding: 10px; background-color: #ECF5FF;"><a href="./posts.php?id=%s">%s</a>
    by <a href="./users.php?userid=%s">%s</a> · %s · score: %s
    ''' % (post['_id'], util.htmlescape(post['title']), post['userId'], user,
           post['postedAt'], post['baseScore']))
    if 'body' in post and string.lower() in post['body'].lower():
        result += '''<pre style="font-family: Lato, Helvetica, sans-serif; word-wrap: break-word; white-space: pre-wrap; white-space: -moz-pre-wrap;">%s</pre>\n''' % highlighted_search_string(
            util.htmlescape(post['body']), string)
    else:
        if post['_id'] in seen:
            # If we didn't even match inside the body and we've seen this post
            # before, it's a garbage result, so return nothing
            return ""

    seen.add(post['_id'])

    result += "</div>\n"
    return result
Esempio n. 2
0
def show_post(post, string, seen):
    if 'authorUserName' in post:
        user = post['authorUserName']
    elif 'authorSlug' in post:
        user = post['authorSlug']
    else:
        user = post['authorDisplayName']
    url = linkpath.posts(util.safe_get(post, ['_id']),
                         util.safe_get(post, ['slug']))
    result = (
        '''<div style="border: 1px solid #B3B3B3; margin: 10px; padding: 10px; background-color: %s;"><a href="%s">%s</a>
    by %s · %s
    ''' % (config.COMMENT_COLOR, url, util.htmlescape(post['title']),
           util.userlink(slug=util.safe_get(post, ['authorSlug']),
                         display_name=util.safe_get(
                             post, ['authorDisplayName'])), post['postedAt']))
    matched_in_body = False
    if 'body' in post:
        for term in string.split():
            # Check if any of the search terms is in the body
            if term.lower() in util.safe_get(post, 'body', default="").lower():
                matched_in_body = True
    if matched_in_body:
        result += '''<pre style="font-family: Lato, Helvetica, sans-serif; word-wrap: break-word; white-space: pre-wrap; white-space: -moz-pre-wrap;">%s</pre>\n''' % highlighted_search_string(
            util.htmlescape(post['body']), string)
    else:
        if post['_id'] in seen:
            # If we didn't even match inside the body and we've seen this post
            # before, it's a garbage result, so return nothing
            return ""

    seen.add(post['_id'])

    result += "</div>\n"
    return result
Esempio n. 3
0
def feed_for_user(username):
    result = ('''<?xml version="1.0" encoding="UTF-8"?>
    <rss version="2.0">
        <channel>
            <title>%s</title>
            <description>%s</description>
            <language>en-us</language>\n''' %
              (username + " feed - " + config.TITLE, username +
               "’s posts and comments on the Effective Altruism Forum"))

    comments = get_comments_for_user(username)
    posts = get_posts_for_user(username)

    all_content = []
    all_content.extend(comments)
    all_content.extend(posts)
    all_content = sorted(all_content,
                         key=lambda x: x['postedAt'],
                         reverse=True)

    for content in all_content:
        content_type = "post" if "title" in content else "comment"
        result += "<item>\n"
        if content_type == "post":
            result += "    <title>%s</title>\n" % content['title']
        else:
            if content['post'] is None:
                result += "    <title>Comment by %s on [deleted post]</title>\n" % (
                    content['user']['username'])
            else:
                result += "    <title>Comment by %s on %s</title>\n" % (
                    content['user']['username'],
                    util.htmlescape(content['post']['title']))
        result += '''    <link>%s</link>\n''' % util.official_url_to_reader(
            content['pageUrl'])
        content_body = util.htmlescape(util.cleanHtmlBody(content['htmlBody']))
        result += '''    <description>%s</description>\n''' % content_body
        result += '''    <author>%s</author>\n''' % username
        result += '''    <guid>%s</guid>\n''' % content['_id']
        result += '''    <pubDate>%s</pubDate>\n''' % content['postedAt']
        result += "</item>\n"

    result += '''</channel>
    </rss>'''

    return result
Esempio n. 4
0
def highlighted_search_string(body, string):
    # body is already html escaped, so we need string to be on the same level
    esc_str = util.htmlescape(string)

    highlighted = r'''<span style="background-color: #ffff00;">\1</span>'''
    return re.sub("(" + re.escape(esc_str) + ")",
                  highlighted,
                  body,
                  flags=re.IGNORECASE)
Esempio n. 5
0
def show_comment(comment, string):
    if 'authorUserName' in comment:
        user = util.safe_get(comment, 'authorUserName')
    elif 'authorSlug' in comment:
        user = util.safe_get(comment, 'authorSlug')
    else:
        user = util.safe_get(comment, 'authorDisplayName')
    result = (
        '''<div style="border: 1px solid #B3B3B3; margin: 10px; padding: 10px; background-color: %s;">comment by <a href="./users.php?userid=%s">%s</a>
        on <a href="./posts.php?id=%s">%s</a>
        · <a href="./posts.php?id=%s#%s">%s</a>
        ''' % (config.COMMENT_COLOR, comment['userId'], user,
               comment['postId'], util.htmlescape(comment['postTitle']),
               comment['postId'], comment['_id'], comment['postedAt']))

    result += '''<pre style="font-family: Lato, Helvetica, sans-serif; word-wrap: break-word; white-space: pre-wrap; white-space: -moz-pre-wrap;">%s</pre>\n''' % highlighted_search_string(
        util.htmlescape(comment['body']), string)
    result += "</div>"

    return result
Esempio n. 6
0
def show_tag(tagslug, display_format):
    print("""<!DOCTYPE html>
    <html>
    """)
    run_query = False if display_format == "queries" else True
    tag_content = get_content_for_tag(tagslug, run_query=run_query)
    if display_format == "queries":
        result = "<pre>"
        result += tag_content + "\n"
        result += "</pre>\n"
        return result

    result = util.show_head(
        title=tagslug,
        author="",
        date="",
        publisher="LessWrong 2.0"
        if "lesswrong" in config.GRAPHQL_URL else "Effective Altruism Forum",
        widepage=True)
    result += "<body>\n"
    result += util.show_navbar(navlinks=[
        '''<a href="%s" title="Show all the GraphQL queries used to generate this page">Queries</a>'''
        % "TODO"
    ])
    result += '''<div id="wrapper">'''
    result += '''<div id="content">'''
    result += "<h1>" + util.htmlescape(tagslug) + "</h1>\n"
    result += " ·\n"
    result += util.cleanHtmlBody(
        util.substitute_alt_links(
            util.safe_get(tag_content, ['description', 'html'])))
    result += ("""
    </div>
    </div>
        </body>
        </html>
    """)

    return result
Esempio n. 7
0
def show_post_and_comment_thread(postid, display_format):
    print("""<!DOCTYPE html>
    <html>
    """)
    run_query = False if display_format == "queries" else True
    post = posts.get_content_for_post(postid, run_query=run_query)
    comments = posts.get_comments_for_post(postid,
                                           view="postCommentsOld",
                                           run_query=run_query)
    if (not run_query) or util.safe_get(post, "question"):
        answers = query_question_answers(postid, run_query=run_query)

    print("""
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
        <style type="text/css">
            body {
                font-family: arial,helvetica,sans-serif;
                font-size: 10pt;
            }
            blockquote {
                color: #789922;
                padding: 0;
                margin: 0;
            }
            blockquote:before {
                content: ">";
            }
            a.reply-parent {
                color: #d00;
            }
        </style>
    </head>
    """)

    result = "<body>\n"
    result += util.show_navbar()
    result += '''<div id="wrapper">'''
    result += '''<div id="content">'''
    result += "<h1>" + util.htmlescape(post['title']) + "</h1>\n"
    result += " ·\n"
    result += '''%s ·\n''' % post['postedAt']
    result += util.official_link(post['pageUrl']) + ' ·\n'
    result += util.gw_link(post['pageUrl']) + ' ·\n'

    if util.safe_get(post, "question") and util.safe_get(
            post, ["tableOfContents", "sections"]):
        result += '''<a href="#comments">''' + util.safe_get(
            post, ["tableOfContents", "sections"])[-1]["title"] + '</a>\n'
    else:
        result += '''<a href="#comments">''' + str(
            post['commentCount']) + ' comments</a>\n'

    if post['url'] is not None:
        result += ('''
            <p>This is a link post for <a href="%s">%s</a></p>
        ''' % (post['url'], post['url']))
    if "question" in post and post["question"]:
        result += "<p>This is a question post.</p>"
    if "tableOfContents" in post and post[
            "tableOfContents"] and "sections" in post["tableOfContents"]:
        if post["tableOfContents"]["sections"]:
            result += '''<h2>Contents</h2>\n'''
            result += '<pre style="font-size: 12px;">\n'
            for section in post["tableOfContents"]["sections"]:
                indent = " " * (2 * section["level"])
                result += '''%s<a href="#%s">%s</a>\n''' % (
                    indent, section["anchor"], util.safe_get(section, "title"))
            result += '</pre>\n'
            # post['htmlBody'] is HTML without the table of contents anchors added
            # in, so we have to use a separate HTML provided by the
            # tableOfContents JSON
            result += util.cleanHtmlBody(
                util.substitute_alt_links(
                    util.safe_get(post, ['tableOfContents', 'html'])))
    else:
        result += util.cleanHtmlBody(
            util.substitute_alt_links(post['htmlBody']))

    if util.safe_get(post, "question"):
        result += '<h2 id="answers">Answers</h2>'
        for answer in answers:
            result += show_answer(answer)

    if util.safe_get(post, "question") and util.safe_get(
            post, ["tableOfContents", "sections"]):
        result += '''<h2 id="comments">''' + util.safe_get(
            post, ["tableOfContents", "sections"])[-1]["title"] + '</h2>\n'
    else:
        result += '''<h2 id="comments">''' + str(
            post['commentCount']) + ' comments</h2>'

    # map of commentId -> list of commentIds that have replied
    reply_graph = {}
    for comment in comments:
        commentid = util.safe_get(comment, ['_id'])
        parentid = util.safe_get(comment, ['parentCommentId'])
        if parentid:
            if parentid in reply_graph:
                reply_graph[parentid].append(commentid)
            else:
                reply_graph[parentid] = [commentid]

    for comment in comments:
        color = config.COMMENT_COLOR
        commentid = comment['_id']
        result += "<div>"  # this extra outer div will ensure that two very short comments aren't displayed side-by-side
        result += (
            '''<div id="%s" style="border: 1px solid #B3B3B3; padding-left: 15px; padding-right: 15px; padding-bottom: 10px; padding-top: 10px; margin-left: 0px; margin-right: -1px; margin-bottom: 0px; margin-top: 10px; background-color: %s; display: inline-block;">'''
            % (commentid, color))
        result += '<span style="color: #117743; font-weight: 700;">Anonymous</span> '
        result += " ·\n"
        result += (('''<a href="#%s">''' % commentid) + comment['postedAt'] +
                   "</a> · ")
        if "lesswrong" in config.GRAPHQL_URL:
            result += ('<a title="Official LessWrong 2.0 link" href="' +
                       comment['pageUrl'] + '">LW</a> · ')
        else:
            result += ('<a title="Official EA Forum link" href="' +
                       comment['pageUrl'] + '">EA</a> · ')
        result += '<a title="GreaterWrong link" href="' + util.official_url_to_gw(
            comment['pageUrl']) + '">GW</a>'
        # This comment has replies, so show their IDs
        if commentid in reply_graph:
            for reply in reply_graph[commentid]:
                result += ''' <a href="#%s" onmouseover="showComment(this, '%s')" onmouseout="removeComment('%s')">&gt;&gt;%s</a>''' % (
                    reply, reply, reply, reply)
        result += '<br/>'
        if util.safe_get(comment, ['parentCommentId']):
            result += '''<br/><a href="#%s" id="%s" class="reply-parent" onmouseover="showComment(this, '%s')" onmouseout="removeComment('%s')">&gt;&gt;%s</a><br/>''' % (
                util.safe_get(comment, ['parentCommentId']),
                util.safe_get(comment, ['parentCommentId']),
                util.safe_get(comment, ['parentCommentId']),
                util.safe_get(comment, ['parentCommentId']),
                util.safe_get(comment, ['parentCommentId']))
        result += util.cleanHtmlBody(
            util.substitute_alt_links(comment['htmlBody']))
        result += "</div></div>"

    result += ("""
    </div>
    </div>

        <script>
            function showComment(pointer, commentid) {
                var comment = document.getElementById(commentid);
                var clone = comment.cloneNode(true);
                var rect = pointer.getBoundingClientRect();

                clone.id = "cloned-" + commentid;
                clone.style.position = 'absolute';
                clone.style.top = (window.pageYOffset + rect.top) + 'px';
                if (window.innerWidth - rect.right < 100) {
                    clone.style.right = rect.left + 'px';
                } else {
                    clone.style.left = rect.right + 'px';
                }
                document.body.appendChild(clone);
            }
            function removeComment(commentid) {
                var clone = document.getElementById("cloned-" + commentid);
                clone.parentNode.removeChild(clone);
            }
        </script>

        </body>
        </html>
    """)

    return result
Esempio n. 8
0
def html_page_for_user(username, display_format):
    run_query = False if display_format == "queries" else True
    comments = get_comments_for_user(username, run_query=run_query)
    posts = get_posts_for_user(username, run_query=run_query)
    user_info = query_user_info(username, run_query=run_query)

    if display_format == "queries":
        result = "<pre>"
        result += comments + "\n"
        result += posts + "\n"
        result += user_info + "\n"
        result += "</pre>\n"
        return result

    result = """<!DOCTYPE html>
    <html>
    """
    result += util.show_head(username)
    result += "<body>"
    feed_link = '''<a href="%s">Feed</a>''' % linkpath.users(
        userslug=username, display_format="rss")
    result += util.show_navbar(navlinks=[
        feed_link,
        '''<a href="%s" title="Show all the GraphQL queries used to generate this page">Queries</a>'''
        % linkpath.users(userslug=util.htmlescape(username),
                         display_format="queries")
    ])
    result += '''<div id="wrapper">'''

    result += '''<div id="sidebar">'''
    result += '<p>'
    if "lesswrong" in config.GRAPHQL_URL:
        result += (
            '<a title="Official LessWrong 2.0 link" href="https://www.lesswrong.com/users/'
            + username + '">LW</a> · ')
        result += (
            '<a title="GreaterWrong link" href="https://www.greaterwrong.com/users/'
            + username + '">GW</a>')
    else:
        result += (
            '<a title="Official EA Forum link" href="https://forum.effectivealtruism.org/users/'
            + username + '">EA</a> · ')
        result += (
            '<a title="GreaterWrong link" href="https://ea.greaterwrong.com/users/'
            + username + '">GW</a>')
    result += '</p>'
    result += '''<h2>User info</h2>'''
    result += '''  <dl>'''
    if "displayName" in user_info and user_info["displayName"]:
        result += '''    <dt>Display name</dt>'''
        result += '''    <dd>%s</dd>''' % user_info["displayName"]
    if "karma" in user_info and user_info["karma"]:
        result += '''    <dt>Karma</dt>'''
        result += '''    <dd>%s</dd>''' % user_info["karma"]
    if "location" in user_info and user_info["location"]:
        result += '''    <dt>Location</dt>'''
        result += '''    <dd>%s</dd>''' % user_info["location"]
    if "htmlBio" in user_info and user_info["htmlBio"]:
        result += '''    <dt>Biography</dt>'''
        result += '''    <dd>%s</dd>''' % user_info["htmlBio"]
    if "postCount" in user_info and user_info["postCount"]:
        result += '''    <dt>Post count</dt>'''
        result += '''    <dd>%s</dd>''' % user_info["postCount"]
    if "commentCount" in user_info and user_info["commentCount"]:
        result += '''    <dt>Comment count</dt>'''
        result += '''    <dd>%s</dd>''' % user_info["commentCount"]
    if "website" in user_info and user_info["website"]:
        result += '''    <dt>Website</dt>'''
        result += '''    <dd><a href="%s">%s</a></dd>''' % (
            user_info["website"], user_info["website"])
    result += '''  </dl>'''
    result += '''</div>'''  # closes sidebar

    result += '''<div id="content">'''

    all_content = []
    all_content.extend(comments)
    all_content.extend(posts)
    all_content = sorted(all_content,
                         key=lambda x: x['postedAt'],
                         reverse=True)

    for content in all_content:
        content_type = "post" if "title" in content else "comment"
        result += '''<div style="border: 1px solid #B3B3B3; margin-bottom: 15px; padding: 10px; background-color: %s;">\n''' % config.COMMENT_COLOR
        if content_type == "post":
            result += '''    <h2><a href="%s">%s</a></h2>\n''' % (
                linkpath.posts(postid=content['_id'],
                               postslug=content['slug']),
                util.htmlescape(content['title']))
            result += '''    %s · score: %s (%s votes)\n''' % (
                content['postedAt'], content['baseScore'],
                content['voteCount'])
        else:
            if content['post'] is None:
                postslug = content['pageUrl'].split('/')[-1].split('#')[0]
                result += '''    <a href="%s#%s">Comment</a> by <b>%s</b> on [deleted post]</b>\n''' % (
                    linkpath.posts(postid=content['postId'],
                                   postslug=postslug), content['_id'],
                    content['user']['username'])
                result += '''    %s\n''' % content['postedAt']
            else:
                if "lesswrong" in config.GRAPHQL_URL:
                    official_link = '''<a href="%s" title="Official LessWrong 2.0 link">LW</a>''' % content[
                        'pageUrl']
                else:
                    official_link = '''<a href="%s" title="Official EA Forum link">EA</a>''' % content[
                        'pageUrl']
                result += (
                    '''    Comment by
                    <b>%s</b> on
                    <a href="%s">%s</a></b> ·
                    <a href="%s#%s">%s</a> ·
                    score: %s (%s votes) ·
                    %s ·
                    <a href="%s" title="GreaterWrong link">GW</a>''' %
                    (username,
                     linkpath.posts(postid=content['postId'],
                                    postslug=content['post']['slug']),
                     util.htmlescape(content['post']['title']),
                     linkpath.posts(postid=content['postId'],
                                    postslug=content['post']['slug']),
                     content['_id'], content['postedAt'], content['baseScore'],
                     content['voteCount'], official_link,
                     util.official_url_to_gw(content['pageUrl'])))
            content_body = util.cleanHtmlBody(content['htmlBody'])
            result += '''    %s\n''' % content_body
        result += "</div>\n"

    result += '''
        </div>
        </div>
        </body>
        </html>
    '''
    return result
Esempio n. 9
0
def show_daily_posts(offset, view, before, after, display_format):
    posts = posts_list_query(offset=offset, view=view, before=before, after=after,
                             run_query=(False if display_format == "queries" else True))
    recent_comments = recent_comments_query(run_query=(False if display_format == "queries" else True))

    if display_format == "queries":
        result = "<pre>"
        result += posts + "\n"  # this is just the query string
        result += recent_comments + "\n"
        result += "</pre>\n"

        return result


    result = """<!DOCTYPE html>
    <html>
    """
    result += util.show_head(config.TITLE)
    result += "<body>\n"
    result += util.show_navbar(navlinks=[
        '''<a href="/?view=%s&amp;offset=%s&amp;before=%s&amp;after=%s&amp;format=queries" title="Show all the GraphQL queries used to generate this page">Queries</a>''' % (view, offset, before, after)
        ])
    result += '''<div id="wrapper">'''
    result += '''
        <div id="sidebar">
            <h2>Archive</h2>
            <ul>
    '''
    start_year = 2006 if "lesswrong" in config.GRAPHQL_URL else 2011
    for year in range(start_year, datetime.datetime.utcnow().year + 1):
        result += "<li>\n"
        result += '''<a href="/?view=%s&amp;before=%s&amp;after=%s">%s</a>''' % (
            view,
            str(year) + "-12-31",
            str(year) + "-01-01",
            year
        )
        if str(year) == after[:4] and str(year) == before[:4]:
            # If we are here, it means we are viewing the "archive" for this
            # year (or a month within this year), so show the months in the
            # sidebar so that we can go inside the months.
            result += "<ul>"
            for month in range(1, 12 + 1):
                if month == 12:
                    last_day = datetime.date(year + 1, 1, 1) - datetime.timedelta(days=1)
                else:
                    last_day = datetime.date(year, month + 1, 1) - datetime.timedelta(days=1)
                result += '''<li><a href="/?view=%s&amp;before=%s&amp;after=%s">%s</a></li>''' % (
                    view,
                    last_day.strftime("%Y-%m-%d"),
                    str(year) + "-" + str(month).zfill(2) + "-01",
                    datetime.date(2000, month, 1).strftime("%B")
                )
            result += "</ul>"
        result += "</li>\n"
    result += "</ul>"

    result += '''<h2>Recent comments</h2>'''
    for comment in recent_comments:
        post = comment['post']
        if post is None:
            post = {'slug': comment['pageUrl'].split('/')[-1].split('#')[0], 'title': '[deleted]'}
        result += ('''
            <a href="%s">%s</a> on <a href="%s#%s">%s</a><br/>
            <span style="font-size: 14px;">
            %s
            </span>
        ''' % (
                linkpath.users(userslug=util.strong_multiget(comment, ['user', 'slug'], "")),
                util.strong_multiget(comment, ['user', 'slug'], ""),
                linkpath.posts(postid=comment['postId'], postslug=post['slug']),
                comment['_id'],
                util.htmlescape(post['title']),
                comment['htmlBody']
            )
        )

    result += "</div>"  # sidebar
    result += '''<div id="content">'''
    result += """<h1><a href="/">%s</a></h1>""" % config.TITLE

    result += '''
        View:
        <a href="/?view=new">New</a> ·
        <a href="/?view=old">Old</a> ·
        <a href="/?view=top">Top</a>
        <br /><br />
    '''

    if view == "top":
        result += ('''
            Restrict date range:
            <a href="/?view=top&amp;after=%s">Today</a> ·
            <a href="/?view=top&amp;after=%s">This week</a> ·
            <a href="/?view=top&amp;after=%s">This month</a> ·
            <a href="/?view=top&amp;after=%s">Last three months</a> ·
            <a href="/?view=top&amp;after=%s">This year</a> ·
            <a href="/?view=top">All time</a>
            <br />
            <br />
        ''' % (
                # Today's posts are all posts after yesterday's date
                (datetime.datetime.utcnow() - datetime.timedelta(days=1)).strftime("%Y-%m-%d"),
                # This week
                (datetime.datetime.utcnow() - datetime.timedelta(days=7)).strftime("%Y-%m-%d"),
                # This month
                (datetime.datetime.utcnow() - datetime.timedelta(days=30)).strftime("%Y-%m-%d"),
                # Last three months
                (datetime.datetime.utcnow() - datetime.timedelta(days=90)).strftime("%Y-%m-%d"),
                # This year
                (datetime.datetime.utcnow() - datetime.timedelta(days=365)).strftime("%Y-%m-%d"),
            )
        )

    date_range_params = ""
    if before:
        date_range_params += "&amp;before=%s" % before
    if after:
        date_range_params += "&amp;after=%s" % after

    if offset - 50 >= 0:
        result += '''<a href="/?view=%s&amp;offset=%s%s">← previous page (newer posts)</a> · ''' % (view, offset - 50, date_range_params)

    result += '''<a href="/?view=%s&amp;offset=%s%s">next page (older posts) →</a>''' % (view, offset + 50, date_range_params)
    result += '''<br/><br/>\n'''

    for post in posts:
        post_url = linkpath.posts(postid=post['_id'], postslug=post['slug'])
        result += ('''<div style="margin-bottom: 15px;">\n''')

        if "lesswrong" in config.GRAPHQL_URL:
            result += "[meta] " if post['meta'] else ""
        else:
            result += "[community] " if post['meta'] else ""
        if "question" in post and post["question"]:
            result += "[question] "
        if "url" in post and post["url"]:
            result += '''[<a href="%s">link</a>] ''' % post["url"]

        result += (('''    <a href="%s">''' % post_url) +
                   util.htmlescape(post['title']) + "</a><br />\n")

        result += util.userlink(slug=util.strong_multiget(post, ['user', 'slug']),
                                username=util.strong_multiget(post, ['user', 'username']),
                                display_name=util.strong_multiget(post, ['user', 'displayName']))
        result += " ·\n"
        result += post['postedAt'] + " ·\n"
        result += '''score: %s (%s votes) ·\n''' % (post['baseScore'], post['voteCount'])
        result += ('''    <a href="%s#comments">comments (%s)</a>\n''' % (post_url, post['commentsCount']))
        result += ("</div>")

    if offset - 50 >= 0:
        result += '''<a href="/?view=%s&amp;offset=%s%s">← previous page (newer posts)</a> · ''' % (view, offset - 50, date_range_params)

    result += '''<a href="/?view=%s&amp;offset=%s%s">next page (older posts) →</a>''' % (view, offset + 50, date_range_params)

    result += """
    </div>
    </div>
        </body>
    </html>
    """

    return result
Esempio n. 10
0
def show_post_and_comment_thread(postid, display_format):
    print("""<!DOCTYPE html>
    <html>
    """)
    run_query = False if display_format == "queries" else True
    post = get_content_for_post(postid, run_query=run_query)
    if run_query:
        post_date = util.safe_get(post, 'postedAt', default="2018-01-01")
    else:
        post_date = "2018-01-01"
    # Apparently post_date is sometimes the empty string, so we have to check again
    if not post_date:
        post_date = "2018-01-01"
    if (run_query and "lesswrong" in config.GRAPHQL_URL
            and datetime.datetime.strptime(post_date[:len("2018-01-01")],
                                           "%Y-%m-%d") < datetime.datetime(
                                               2009, 2, 27)):
        comments = get_comments_for_post(postid,
                                         view="postCommentsOld",
                                         run_query=run_query)
        sorting_text = "oldest first, as this post is from before comment nesting was available (around 2009-02-27)."
    else:
        comments = get_comments_for_post(postid, run_query=run_query)
        sorting_text = "top scores."
    if (not run_query) or util.safe_get(post, "question"):
        answers = query_question_answers(postid, run_query=run_query)

    if display_format == "queries":
        result = "<pre>"
        result += post + "\n"
        result += comments + "\n"
        result += answers + "\n"
        result += "</pre>\n"
        return result

    if "user" in post and post["user"] and "slug" in post["user"] and post[
            "user"]["slug"]:
        author = post['user']['slug']
    else:
        author = None
    canonical_url = util.safe_get(post, 'pageUrl')
    if util.safe_get(post, 'canonicalSource'):
        canonical_url = util.safe_get(post, 'canonicalSource')
    result = util.show_head(
        title=post['title'],
        canonical_url=canonical_url,
        author=author if author is not None else "[deleted]",
        date=post['postedAt'],
        publisher="LessWrong 2.0"
        if "lesswrong" in config.GRAPHQL_URL else "Effective Altruism Forum")
    result += "<body>\n"
    result += util.show_navbar(navlinks=[
        '''<a href="%s" title="Show all the GraphQL queries used to generate this page">Queries</a>'''
        % linkpath.posts(postid=util.htmlescape(postid),
                         postslug=post['slug'],
                         display_format="queries")
    ])
    result += '''<div id="wrapper">'''
    result += '''<div id="content">'''
    result += "<h1>" + util.htmlescape(post['title']) + "</h1>\n"
    result += "post by "
    result += util.userlink(slug=post.get("user", {}).get("slug", None),
                            username=post.get("user",
                                              {}).get("username", None),
                            display_name=post.get("user",
                                                  {}).get("displayName", None),
                            bio=util.safe_get(post, ['user', 'bio']))
    for coauthor in util.safe_get(post, "coauthors", []):
        result += ", " + util.userlink(
            slug=util.safe_get(coauthor, "slug"),
            username=util.safe_get(coauthor, "username"),
            display_name=util.safe_get(coauthor, "displayName"))
    result += " ·\n"
    result += '''%s ·\n''' % post['postedAt']
    result += util.grouped_links(util.alt_urls(post['pageUrl'])) + " ·\n"
    if post['legacyId'] is not None:
        result += '''<a href="%s" title="Legacy link">Legacy</a> ·\n''' % util.legacy_link(
            post['legacyId'])

    if util.safe_get(post, "question") and util.safe_get(
            post, ["tableOfContents", "sections"]):
        result += '''<a href="#comments">''' + util.safe_get(
            post, ["tableOfContents", "sections"])[-1]["title"] + '</a>\n'
    else:
        result += '''<a href="#comments">''' + str(
            post['commentCount']) + ' comments</a>\n'

    if post['url'] is not None:
        result += ('''
            <p>This is a link post for <a href="%s">%s</a></p>
        ''' % (post['url'], post['url']))
    if "question" in post and post["question"]:
        result += "<p>This is a question post.</p>"
    if "tableOfContents" in post and post[
            "tableOfContents"] and "sections" in post["tableOfContents"]:
        if post["tableOfContents"]["sections"]:
            result += '''<h2>Contents</h2>\n'''
            result += '<pre style="font-size: 12px;">\n'
            for section in post["tableOfContents"]["sections"]:
                # I think I was using this to get rid of the score (which
                # always appeared as the first word of level 2 headings on
                # question posts). But doing so without checking that a post is
                # a question post results in erroneously removing the first
                # word of standard level 2 headings. As I write this
                # (2021-11-21), question posts don't even seem to come with
                # answer TOCs anymore, so this is kind of useless.
                ans_title = util.safe_get(section, "title")
                # if ans_title and section["level"] == 2:
                #     ans_title = " ".join(ans_title.split()[1:])
                indent = " " * (2 * section["level"])
                result += '''%s<a href="#%s">%s</a>\n''' % (
                    indent, section["anchor"], ans_title)
            result += '</pre>\n'
            # post['htmlBody'] is HTML without the table of contents anchors added
            # in, so we have to use a separate HTML provided by the
            # tableOfContents JSON
            result += util.cleanHtmlBody(
                util.substitute_alt_links(
                    util.safe_get(post, ['tableOfContents', 'html'])))
    else:
        result += util.cleanHtmlBody(
            util.substitute_alt_links(post['htmlBody']))

    if util.safe_get(post, "question"):
        result += '<h2 id="answers">Answers</h2>'
        for answer in answers:
            result += show_answer(answer)

    if util.safe_get(post, "question") and util.safe_get(
            post, ["tableOfContents", "sections"]):
        result += '''<h2 id="comments">''' + util.safe_get(
            post, ["tableOfContents", "sections"])[-1]["title"] + '</h2>\n'
    else:
        result += '''<h2 id="comments">''' + str(
            post['commentCount']) + ' comments</h2>'
    result += "<p>Comments sorted by %s</p>" % sorting_text

    root = build_comment_thread(comments)
    result += show_comment(root)

    result += ("""
    </div>
    </div>
        </body>
        </html>
    """)

    return result