Allowed mods to comment /solved in any scenario

This commit is contained in:
Collin R
2020-02-07 21:31:52 -08:00
parent 39bf8c2693
commit dc51398492
5 changed files with 77 additions and 63 deletions

5
docs/TESTS.md Normal file
View File

@@ -0,0 +1,5 @@
# TESTS
## End-to-end Testing Scenarios

View File

@@ -20,6 +20,7 @@
- https://developer.github.com/v3/repos/contents/#get-archive-link - https://developer.github.com/v3/repos/contents/#get-archive-link
- https://developer.github.com/v3/repos/commits/ - https://developer.github.com/v3/repos/commits/
- https://developer.github.com/v3/repos/releases/ - https://developer.github.com/v3/repos/releases/
- https://developer.github.com/v3/#timezones
- Webhooks: - Webhooks:
- https://developer.github.com/webhooks/ - https://developer.github.com/webhooks/
- https://developer.github.com/v3/repos/hooks/ - https://developer.github.com/v3/repos/hooks/
@@ -40,6 +41,7 @@
### bot.py ### bot.py
* [ ] Allow mods to use "/[Ss]olved" in any context
* [ ] Allow mods and/or bot owner to add or remove points from specific users * [ ] Allow mods and/or bot owner to add or remove points from specific users
* [ ] Make the algorithm for determining the problem solver more sophisticated * [ ] Make the algorithm for determining the problem solver more sophisticated
- e.g. check entire comment tree instead of just ignoring if the OP also - e.g. check entire comment tree instead of just ignoring if the OP also
@@ -79,18 +81,19 @@
### database.py ### database.py
* [ ] Store date for each "!solved" comment
* [ ] Possibly refactor for a datastore type thing instead of database * [ ] Possibly refactor for a datastore type thing instead of database
- Maybe even make models like Redditor to combine data storage/access with - Maybe even make models like Redditor to combine data storage/access with
logic, e.g. determining current level logic, e.g. determining current level
### reply.py ### reply.py
* [ ] For the footer section of the reply comment regarding the bot, could have the * [X] Fix progress bar
* ~~For the footer section of the reply comment regarding the bot, could have the
bot make a post on its account explaining itself, and link to that (and then bot make a post on its account explaining itself, and link to that (and then
also link to the source code separately, and perhaps in that post, too). also link to the source code separately, and perhaps in that post, too).
Could even have the bot make this post automatically if it doesn't have a Could even have the bot make this post automatically if it doesn't have a
link to the post in its config, and then store the link for future use. link to the post in its config, and then store the link for future use.~~
* [X] Fix progress bar
## Ideas ## Ideas

View File

@@ -13,8 +13,6 @@ USER_AGENT = 'PointsBot (by u/GlipGlorp7)'
SOLVED_PAT = re.compile('![Ss]olved') SOLVED_PAT = re.compile('![Ss]olved')
MOD_SOLVED_PAT = re.compile('/[Ss]olved') MOD_SOLVED_PAT = re.compile('/[Ss]olved')
TEST_COMMENTS = False
### Main Function ### ### Main Function ###
@@ -35,10 +33,6 @@ def run():
is_mod = bool(subreddit.moderator(redditor=reddit.user.me())) is_mod = bool(subreddit.moderator(redditor=reddit.user.me()))
print_level(1, f'Is mod? {is_mod}') print_level(1, f'Is mod? {is_mod}')
if TEST_COMMENTS:
make_comments(subreddit, levels)
return
db = database.Database(cfg.database_path) db = database.Database(cfg.database_path)
# Monitor new comments for confirmed solutions # Monitor new comments for confirmed solutions
@@ -51,43 +45,46 @@ def run():
print_level(0, '\nFound comment') print_level(0, '\nFound comment')
print_level(1, f'Comment text: "{comm.body}"') print_level(1, f'Comment text: "{comm.body}"')
if marks_as_solved(comm): if not marks_as_solved(comm):
if not is_first_solution(comm): print_level(1, 'Not a "![Ss]olved" comment')
# Skip this "!solved" comment and wait for the next continue
print_level(1, 'Not the first solution')
continue
print_level(1, 'This is the first solution') if is_mod_comment(comm):
print_solution_info(comm) print_level(1, 'Mod comment')
elif not is_first_solution(comm):
# Skip this "!solved" comment and wait for the next
print_level(1, 'Not the first solution')
continue
solver = comm.parent().author print_level(1, 'This is the first solution found')
print_level(1, f'Adding point for {solver.name}') print_solution_info(comm)
db.add_point(solver)
points = db.get_points(solver)
print_level(1, f'Points for {solver.name}: {points}')
level_info = level.user_level_info(points, levels) solver = find_solver(comm)
db.add_point(solver)
print_level(1, f'Added point for {solver.name}')
# Reply to the comment marking the submission as solved points = db.get_points(solver)
reply_body = reply.make(solver, points, level_info) print_level(1, f'Total points for {solver.name}: {points}')
print_level(1, f'Replying with: "{reply_body}"') level_info = level.user_level_info(points, levels)
comm.reply(reply_body)
# Check if (non-mod) user flair should be updated to new level # Reply to the comment marking the submission as solved
lvl = level_info.current reply_body = reply.make(solver, points, level_info)
if lvl and lvl.points == points: comm.reply(reply_body)
print_level(1, f'User reached level: {lvl.name}') print_level(1, f'Replied to comment with: "{reply_body}"')
if not subreddit.moderator(redditor=solver):
print_level(2, 'Setting flair') # Check if (non-mod) user flair should be updated to new level
print_level(3, f'Flair text: {lvl.name}') lvl = level_info.current
print_level(3, f'Flair template ID: {lvl.flair_template_id}') if lvl and lvl.points == points:
subreddit.flair.set(solver, print_level(1, f'User reached level: {lvl.name}')
text=lvl.name, if not subreddit.moderator(redditor=solver):
flair_template_id=lvl.flair_template_id) print_level(2, 'Setting flair')
else: print_level(3, f'Flair text: {lvl.name}')
print_level(2, 'Solver is mod; don\'t alter flair') print_level(3, f'Flair template ID: {lvl.flair_template_id}')
else: subreddit.flair.set(solver,
print_level(1, 'Not a "!solved" comment') text=lvl.name,
flair_template_id=lvl.flair_template_id)
else:
print_level(2, 'Solver is mod; don\'t alter flair')
### Reddit Comment Functions ### ### Reddit Comment Functions ###
@@ -110,9 +107,13 @@ def marks_as_solved(comment):
return op_resp_to_solver or mod_resp_to_solver return op_resp_to_solver or mod_resp_to_solver
def is_mod_comment(comment):
return comment.subreddit.moderator(redditor=comment.author)
def is_first_solution(solved_comment): def is_first_solution(solved_comment):
# Retrieve any comments hidden by "more comments" '''Return True if this solved comment is the first, False otherwise.'''
# Passing limit=0 will replace all "more comments" # Retrieve any comments hidden by "more comments" by passing limit=0
submission = solved_comment.submission submission = solved_comment.submission
submission.comments.replace_more(limit=0) submission.comments.replace_more(limit=0)
@@ -127,6 +128,10 @@ def is_first_solution(solved_comment):
return True return True
def find_solver(solved_comment):
return solved_comment.parent().author
### Debugging & Logging ### ### Debugging & Logging ###
@@ -144,22 +149,3 @@ def print_solution_info(comm):
print_level(3, f'Body: {comm.body}') print_level(3, f'Body: {comm.body}')
def make_comments(subreddit, levels):
testpoints = [1, 3, 5, 10, 15, 30, 45, 75] + list(range(100, 551, 50))
for sub in subreddit.new():
if sub.title == 'Testing comment scenarios':
redditor = sub.author
for points in testpoints:
body = f'Solver: {redditor}\n\nTotal points after solving: {points}'
print_level(0, body)
comm = sub.reply(body)
if comm:
level_info = level.user_level_info(points, levels)
body = reply.make(redditor, points, level_info)
comm.reply(body)
else:
print_level(1, 'ERROR: Unable to comment')
break

View File

@@ -1,5 +1,6 @@
from os.path import abspath, dirname, join
import sys import sys
from os.path import abspath, dirname, join
sys.path.insert(0, abspath(join(dirname(__file__), '..'))) sys.path.insert(0, abspath(join(dirname(__file__), '..')))
import pointsbot import pointsbot

View File

@@ -13,6 +13,25 @@ def leftpad(msg, num_indents=1):
return '\n'.join([('\t' * num_indents + l) for l in msg.split('\n')]) return '\n'.join([('\t' * num_indents + l) for l in msg.split('\n')])
def make_comments(subreddit, levels):
testpoints = [1, 3, 5, 10, 15, 30, 45, 75] + list(range(100, 551, 50))
for sub in subreddit.new():
if sub.title == 'Testing comment scenarios':
redditor = sub.author
for points in testpoints:
body = f'Solver: {redditor}\n\nTotal points after solving: {points}'
print_level(0, body)
comm = sub.reply(body)
if comm:
level_info = level.user_level_info(points, levels)
body = reply.make(redditor, points, level_info)
comm.reply(body)
else:
print_level(1, 'ERROR: Unable to comment')
break
### Tests ### ### Tests ###
levels = [ levels = [