Пример #1
0
def show_answer(answer):
    result = ("""
    <div id="%s" style="border: 1px solid #B3B3B3; padding-left: 15px; padding-right: 0px; padding-bottom: 10px; padding-top: 10px; margin-left: 0px; margin-right: -1px; margin-bottom: 0px; margin-top: 10px;">
        answer by %s · <a href="#%s">%s</a> · %s
        <br>
        %s
    """ % (
        answer["_id"],
        util.userlink(slug=util.safe_get(answer, ["user", "slug"]),
                      username=answer["author"],
                      display_name=util.safe_get(answer,
                                                 ["user", "displayName"]),
                      bio=util.safe_get(answer, ["user", "bio"])),
        answer["_id"],
        answer["postedAt"],
        util.grouped_links(
            util.alt_urls(util.safe_get(answer, "pageUrl"), is_answer=True)),
        util.cleanHtmlBody(util.substitute_alt_links(answer["htmlBody"])),
    ))
    replies = query_replies_to_answer(util.safe_get(answer, "_id"))
    root = build_comment_thread(replies)
    result += show_comment(root)
    result += "</div>"

    return result
Пример #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
Пример #3
0
def show_comment(comment_node):
    result = ""
    comment = comment_node.data
    color = config.COMMENT_COLOR if comment_node.parity == "odd" else "#FFFFFF"

    # If this is the root node, comment is {} so skip it
    if comment:
        commentid = comment['_id']
        result += (
            '''<div id="%s" style="border: 1px solid #B3B3B3; padding-left: 15px; padding-right: 0px; padding-bottom: 10px; padding-top: 10px; margin-left: 0px; margin-right: -1px; margin-bottom: 0px; margin-top: 10px; background-color: %s">'''
            % (commentid, color))
        result += "<details open>"
        result += "<summary>"
        if util.safe_get(comment, 'parentCommentId'):
            result += '''<a href="#%s" title="Go to parent comment">↑</a> ''' % util.safe_get(
                comment, 'parentCommentId')
        result += "comment by "
        result += util.userlink(slug=util.safe_get(comment, ['user', 'slug']),
                                username=util.safe_get(comment,
                                                       ['user', 'username']),
                                display_name=util.safe_get(
                                    comment, ['user', 'displayName']),
                                bio=util.safe_get(comment, ['user', 'bio']))
        result += " ·\n"
        result += (('''<a href="#%s">''' % commentid) + comment['postedAt'] +
                   "</a> · ")
        result += util.grouped_links(util.alt_urls(comment['pageUrl']))
        result += "</summary>"
        result += util.cleanHtmlBody(
            util.substitute_alt_links(comment['htmlBody']))
        if comment_node.children:
            result += '<span style="font-size: 14px;">Replies from: '
            replies = [
                '<a href="#%s">%s</a>' %
                (child.commentid,
                 util.safe_get(child.data, ['user', 'username']))
                for child in comment_node.children
            ]
            result += ", ".join(replies)
            result += '</span>'

    if comment_node.children:
        for child in comment_node.children:
            result += show_comment(child)

    if comment:
        result += "</details>"
        result += "</div>"

    return result
Пример #4
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
Пример #5
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">'''

    result += '''
        <ul>
            <li><a href="#posts">Posts</a></li>
            <li><a href="#comments">Comments</a></li>
        </ul>
    '''

    result += '''<h2 id="posts">Posts</h2>'''
    for post in posts:
        result += '''<div style="border: 1px solid #B3B3B3; margin-bottom: 15px; padding: 10px; background-color: %s;">\n''' % config.COMMENT_COLOR
        result += '''    <a href="%s">%s</a>\n''' % (linkpath.posts(
            postid=util.safe_get(post, '_id'),
            postslug=util.safe_get(
                post, 'slug')), util.htmlescape(util.safe_get(post, 'title')))
        result += '''    %s\n''' % (util.safe_get(post, 'postedAt'))
        result += "</div>\n"

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

    result += '''
        </div>
        </div>
        </body>
        </html>
    '''
    return result
Пример #6
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