From 6cac5fbab8c3ddaddf7d1409c694dd1088fa307a Mon Sep 17 00:00:00 2001 From: user12986714 <65436504+user12986714@users.noreply.github.com> Date: Tue, 26 May 2020 14:42:05 -0400 Subject: [PATCH] Minor fixes --- chatcommands.py | 55 ++++++++++++++++++++++++++++----------- test/test_chatcommands.py | 24 ++++++++++------- 2 files changed, 55 insertions(+), 24 deletions(-) diff --git a/chatcommands.py b/chatcommands.py index 8382d6fd13e..a958faac180 100644 --- a/chatcommands.py +++ b/chatcommands.py @@ -1705,7 +1705,7 @@ def allspam(msg, url, alias_used="allspam"): if 'items' not in res or len(res['items']) == 0: raise CmdException("The specified user does not appear to exist.") if res['has_more']: - # Too many posts + # Too many accounts raise CmdException("The specified user has an abnormally high number of accounts. Please consider flagging " "for moderator attention, otherwise use !!/report on the user's posts individually.") # Add accounts with posts @@ -1714,7 +1714,6 @@ def allspam(msg, url, alias_used="allspam"): user_sites.append((site['user_id'], get_api_sitename_from_url(site['site_url']))) else: user_sites.append((user[0], get_api_sitename_from_url(user[1]))) - total_posts = 0 # Tracking total amount of posts by that user # Fetch posts for u_id, u_site in user_sites: # Respect backoffs etc @@ -1764,14 +1763,42 @@ def allspam(msg, url, alias_used="allspam"): post_data.score = post['score'] post_data.up_vote_count = post['up_vote_count'] post_data.down_vote_count = post['down_vote_count'] - # Report that post - current_output = report_post(post_data, msg.owner, msg.room.name, message_url, operation, custom_reason) - if current_output: - output.append(current_output) - total_posts += 1 - if total_posts == 0: + if post_data.post_type == "answer": + # Annoyingly we have to make another request to get the question ID, since it is only returned by the + # /answers route + # Respect backoffs etc + GlobalVars.api_request_lock.acquire() + if GlobalVars.api_backoff_time > time.time(): + time.sleep(GlobalVars.api_backoff_time - time.time() + 2) + # Fetch posts + req_url = "https://api.stackexchange.com/2.2/answers/{}".format(post['post_id']) + params = { + 'filter': '!*Jxb9s5EOrE51WK*', + 'key': api_key, + 'site': u_site + } + answer_res = requests.get(req_url, params=params).json() + if "backoff" in answer_res: + if GlobalVars.api_backoff_time < time.time() + answer_res["backoff"]: + GlobalVars.api_backoff_time = time.time() + answer_res["backoff"] + GlobalVars.api_request_lock.release() + # Finally, set the attribute + post_data.question_id = answer_res['items'][0]['question_id'] + post_data.is_answer = True + # Add the post to report queue + user_posts.append(post_data) + if len(user_posts) == 0: raise CmdException("The user has no post yet.") - if total_posts > 2: + if len(user_posts) > 15: + raise CmdException("The specified user has an abnormally high number of spam posts. Please consider flagging " + "for moderator attention, otherwise use !!/report on the posts individually.") + # Report posts + for current_post_data in user_posts: + # Report that post + current_output = report_post(current_post_data, msg.owner, msg.room.name, message_url, operation, custom_reason) + if current_output: + output.append(current_output) + if len(user_posts) > 2: add_or_update_multiple_reporter(msg.owner.id, msg._client.host, time.time()) if len(output): return "\n".join(output) @@ -1806,7 +1833,7 @@ def report_post(post_data, reported_by, reported_in=None, blacklist_by=None, ope abs_url = post_data.post_url url = to_protocol_relative(abs_url) - if have_already_been_posted(post_data.site, post_data.post_id, post_data.title) and not is_forced: + if has_already_been_posted(post_data.site, post_data.post_id, post_data.title) and not is_forced: # Recently reported and is not forced if GlobalVars.metasmoke_key is not None: ms_link = resolve_ms_link(url) or to_metasmoke_link(url) @@ -1859,7 +1886,7 @@ def report_post(post_data, reported_by, reported_in=None, blacklist_by=None, ope else: processed_why = report_info + "This post would not have been caught otherwise." handle_spam(post=post, # Reported posts are always treated as spam. - reasons=["Manually reported" + post_data.post_type], + reasons=["Manually reported " + post_data.post_type], why=processed_why) if custom_reason: Tasks.later(Metasmoke.post_auto_comment, custom_reason, reported_by, url=url, after=15) @@ -1870,12 +1897,10 @@ def report_post(post_data, reported_by, reported_in=None, blacklist_by=None, ope # Also the operation must be either "scan" or "scan-force" if scan_why: # Post is ignored - output.append("[Post]({}): Looks like spam but is ignored.".format(abs_url)) - return None + return "[Post]({}): Looks like spam but is ignored.".format(abs_url) else: # Is not spam - output.append("[Post]({}): Does not look like spam.".format(abs_url)) - return None + return "[Post]({}): Does not look like spam.".format(abs_url) @command(str, str, privileged=True, whole_msg=True) diff --git a/test/test_chatcommands.py b/test/test_chatcommands.py index 2f51ded9104..dfbfcb17caa 100644 --- a/test/test_chatcommands.py +++ b/test/test_chatcommands.py @@ -289,7 +289,7 @@ def test_report(handle_spam): "id": 1337 }) - assert chatcommands.report("test", original_msg=msg, alias_used="report") == "Post 1: That does not look like a valid post URL." + assert chatcommands.report("test", original_msg=msg, alias_used="report") == "[Post](test): Invalid url." assert chatcommands.report("one two three four five plus-an-extra", original_msg=msg, alias_used="report") == ( "To avoid SmokeDetector reporting posts too slowly, you can report at most 5 posts at a time. This is to avoid " @@ -300,11 +300,11 @@ def test_report(handle_spam): # .startswith("You cannot provide multiple custom report reasons.") assert chatcommands.report('https://stackoverflow.com/q/1', original_msg=msg) == \ - "Post 1: Could not find data for this post in the API. It may already have been deleted." + "[Post](https://stackoverflow.com/q/1): No data fetched from API. It may have been deleted." # Valid post assert chatcommands.report('https://stackoverflow.com/a/1732454', original_msg=msg, alias_used="scan") == \ - "Post 1: This does not look like spam" + "[Post](https://stackoverflow.com/a/1732454): Does not look like spam." assert chatcommands.report('https://stackoverflow.com/a/1732454 "~o.O~"', original_msg=msg, alias_used="report") is None _, call = handle_spam.call_args_list[-1] @@ -338,7 +338,7 @@ def test_report(handle_spam): # Don't re-report GlobalVars.latest_questions = [('stackoverflow.com', '1732454', 'RegEx match open tags except XHTML self-contained tags')] - assert chatcommands.report('https://stackoverflow.com/a/1732454', original_msg=msg).startswith("Post 1: Already recently reported") + assert chatcommands.report('https://stackoverflow.com/a/1732454', original_msg=msg).startswith("[Post](https://stackoverflow.com/a/1732454): Already recently reported") # Can use report command multiple times in 30s if only one URL was used assert chatcommands.report('https://stackoverflow.com/q/1732348', original_msg=msg, alias_used="report") is None @@ -369,7 +369,7 @@ def test_allspam(handle_spam): "id": 1337 }) - assert chatcommands.allspam("test", original_msg=msg) == "That doesn't look like a valid user URL." + assert chatcommands.allspam("test", original_msg=msg) == "[User](test): Invalid url." # If this code lasts long enough to fail, I'll be happy assert chatcommands.allspam("https://stackexchange.com/users/10000000000", original_msg=msg) == \ @@ -391,10 +391,10 @@ def test_allspam(handle_spam): ) assert chatcommands.allspam("https://stackexchange.com/users/12108751", original_msg=msg) == \ - "The specified user hasn't posted anything." + "The user has no post yet." assert chatcommands.allspam("https://stackoverflow.com/users/8846458", original_msg=msg) == \ - "The specified user has no posts on this site." + "The user has no post yet." # This test is for users with <100rep but >15 posts # If this breaks in the future because the below user eventually gets 100 rep (highly unlikely), use the following @@ -412,7 +412,10 @@ def test_allspam(handle_spam): _, call = handle_spam.call_args_list[0] assert isinstance(call["post"], Post) assert call["reasons"] == ["Manually reported answer"] - assert call["why"] == "User manually reported by *ArtOfCode* in room *Charcoal HQ*.\n" + assert call["why"].startswith( + "Post manually reported by user *ArtOfCode* in room *Charcoal HQ*." + "\n\nThis post would not have been caught otherwise." + ) handle_spam.reset_mock() assert chatcommands.allspam("https://meta.stackexchange.com/users/373807", original_msg=msg) is None @@ -421,7 +424,10 @@ def test_allspam(handle_spam): _, call = handle_spam.call_args_list[0] assert isinstance(call["post"], Post) assert call["reasons"] == ["Manually reported answer"] - assert call["why"] == "User manually reported by *ArtOfCode* in room *Charcoal HQ*.\n" + assert call["why"].startswith( + "Post manually reported by user *ArtOfCode* in room *Charcoal HQ*." + "\n\nThis post would not have been caught otherwise." + ) finally: GlobalVars.blacklisted_users.clear()