-
Notifications
You must be signed in to change notification settings - Fork 210
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] brainstorming for /vote fast + prototype [WILL NOT BE UN-WIP-ED] #493
Changes from 14 commits
dd4c8bf
fd3f872
48e9fd1
a7b0e27
accf700
6cde8da
eef11e0
8b3c316
965ac7d
9872097
95659ee
20c7c08
c655b91
f5c39db
e520f3f
740a780
1c65501
c7933a5
d48f779
d147db4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,14 @@ | ||
import logging | ||
import arrow | ||
import re | ||
import json | ||
from requests.exceptions import HTTPError | ||
|
||
import settings | ||
import github_api as gh | ||
|
||
from lib.db.models import Comment, User, ActiveIssueCommands, Issue | ||
from lib.db.models import RunTimes, InactiveIssueCommands | ||
from lib.db.models import RunTimes, InactiveIssueCommands, MeritocracyMentioned | ||
|
||
''' | ||
Command Syntax | ||
|
@@ -21,7 +22,7 @@ | |
|
||
# If no subcommands, map cmd: None | ||
COMMAND_LIST = { | ||
"/vote": ("close", "reopen") | ||
"/vote": ("close", "reopen", "fast") | ||
} | ||
|
||
__log = logging.getLogger("read_issue_comments") | ||
|
@@ -35,13 +36,31 @@ def get_seconds_remaining(api, comment_id): | |
return seconds_remaining | ||
|
||
|
||
def insert_or_update_issue(api, issue_id, number): | ||
# get more info on the issue | ||
gh_issue = gh.issue.open_issue(api, settings.URN, number) | ||
|
||
# get user from db | ||
user, _ = User.get_or_create(user_id=gh_issue["user"]["id"], | ||
defaults={"login": gh_issue["user"]["login"]}) | ||
|
||
# db insert | ||
issue, _ = Issue.get_or_create(issue_id=issue_id, | ||
number=number, | ||
user=user, | ||
created_at=gh_issue["created_at"], | ||
expedited=False, | ||
is_pr="pull_request" in gh_issue) | ||
|
||
return issue | ||
|
||
|
||
def insert_or_update(api, cmd_obj): | ||
# Find the comment, or create it if it doesn't exit | ||
comment_id = cmd_obj["global_comment_id"] | ||
issue, _ = Issue.get_or_create(issue_id=cmd_obj["issue_id"]) | ||
user, _ = User.get_or_create(user_id=cmd_obj["user"]["id"], | ||
defaults={"login": cmd_obj["user"]["login"]}) | ||
|
||
issue = insert_or_update_issue(api, cmd_obj["issue_id"], cmd_obj["number"]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. where are you getting There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it ought to be just returned from github, right: https://developer.github.com/v3/issues/#list-issues-for-a-repository? Am I missing something? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep. Read comments.py / get_all_issue_comments. It doesn't return the entire structure. You might need to change that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, good catch. Fixed |
||
comment, _ = Comment.get_or_create(comment_id=comment_id, | ||
defaults={ | ||
"user": user, "text": cmd_obj["comment_text"], | ||
|
@@ -135,7 +154,21 @@ def get_command_votes(api, urn, comment_id): | |
return votes | ||
|
||
|
||
def handle_vote_command(api, command, issue_id, comment_id, votes): | ||
def get_meritocracy(): | ||
# FIXME: update when this is done by the db | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure the meritocracy will ever be stored in the DB. Instead, put this code in the function. |
||
meritocracy = {} | ||
with open('server/meritocracy.json', 'r') as mfp: | ||
fs = fp.read() | ||
if fs: | ||
meritocracy = json.loads(fs) | ||
|
||
return meritocracy | ||
|
||
|
||
def handle_vote_command(api, command, cmdmeta, votes): | ||
issue_id = cmdmeta.issue.issue_id | ||
comment_id = cmdmeta.comment.comment_id | ||
|
||
orig_command = command[:] | ||
# Check for correct command syntax, ie, subcommands | ||
log_warning = False | ||
|
@@ -145,6 +178,48 @@ def handle_vote_command(api, command, issue_id, comment_id, votes): | |
gh.issues.close_issue(api, settings.URN, issue_id) | ||
elif sub_command == "reopen": | ||
gh.issues.open_issue(api, settings.URN, issue_id) | ||
elif sub_command == "fast": | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe pull this out into it's own function? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
comment_updated_at = cmdmeta.comment.updated_at | ||
comment_created_at = cmdmeta.comment.created_at | ||
comment_poster = cmdmeta.comment.user | ||
issue_poster = cmdmeta.issue.user | ||
issue_created_at = cmdmeta.issue.created_at | ||
|
||
# This must be a PR | ||
if not cmdmeta.issue.is_pr: | ||
return | ||
|
||
# The post should not have been updated | ||
if updated_at != created_at: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe leave some kind of response indicating why the command didn't run? Makes debugging easier There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm... yes, I see your point... but would this be prone to inducing spam? |
||
return | ||
|
||
# The comment poster must be in the meritocracy | ||
meritocracy = get_meritocracy() | ||
|
||
if comment_poster not in meritocracy: | ||
return | ||
|
||
# The comment must posted within 5 min of the issue | ||
if (arrow.get(comment_created) - arrow.get(issue_created_at)).total_seconds() > 5*60: | ||
return | ||
|
||
# Leave a note on the issue that it is expedited | ||
Issue.update(expedited=True).where(Issue.issue_id == cmdmeta.issue.issue_id).execute() | ||
|
||
# mention the meritocracy immediately | ||
try: | ||
pr = gh.prs.get_pr(api, settings.URN, issue.number) | ||
commit = pr["head"]["sha"] | ||
|
||
mm, created = MeritocracyMentioned.get_or_create(commit_hash=commit) | ||
if created: | ||
meritocracy_mentions = meritocracy - {pr["user"]["login"].lower(), | ||
"chaosbot"} | ||
gh.comments.leave_expedite_comment(api, settings.URN, pr["number"], | ||
meritocracy_mentions) | ||
except: | ||
__log.exception("Failed to process meritocracy mention") | ||
|
||
else: | ||
# Implement other commands | ||
pass | ||
|
@@ -176,7 +251,7 @@ def handle_comment(api, cmd): | |
comment=comment_text)) | ||
|
||
if command == "/vote": | ||
handle_vote_command(api, parsed_comment, issue_id, comment_id, votes) | ||
handle_vote_command(api, parsed_comment, cmd, votes) | ||
|
||
update_command_ran(api, comment_id, "Command Ran") | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,6 +28,11 @@ class Comment(BaseModel): | |
|
||
class Issue(BaseModel): | ||
issue_id = pw.IntegerField(primary_key=True) | ||
number = pw.IntegerField() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what is this number? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The PR number as oppose to PR id? The thing is when github returns a PR, it returns a value called "id" which is not the PR number we see on github, and it returns a "number" which is the number we see on github. TBH, I am really confused about which to use where. I think we want to use issue/PR numbers, rather than ids, but the db models appear to use the ids. Any help/auditing on this point would be appreciated. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The ids are used when making api calls. I think that's why we store them There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm... interesting. Most of the API I saw for issues and PRs take the issue/PR number, though? |
||
created_at = pw.DateField() | ||
user = pw.ForeignKeyField(User, related_name='poster') | ||
is_pr = pw.BooleanField() | ||
expedited = pw.BooleanField() | ||
|
||
|
||
class ActiveIssueCommands(BaseModel): | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does anyone know what the difference between these is? Can I drop one of them?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would recommend using the
defaults
param here for anything not in the primary key. We were having issues using this syntax beforeThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better?