User cannot get duplicate points on same post

This commit is contained in:
Collin R
2021-03-07 23:13:50 -08:00
parent 9ec92a23c7
commit ee7e2cb446
5 changed files with 19 additions and 70 deletions

View File

@@ -4,6 +4,10 @@
* [X] Initial/Basic Logging * [X] Initial/Basic Logging
* Especially when unable to handle a comment * Especially when unable to handle a comment
* [X] Change commands from !solved and /solved to !helped and /helped
* [X] Allow multiple users to be awarded points on a single post
* So just check whether each user is already awarded a point for a given post
## File-Specific ## File-Specific
### bot.py ### bot.py

View File

@@ -4,10 +4,7 @@ File-specific lists are in loose descending order of priority.
## Current ## Current
* [ ] Change commands from !solved and /solved to !helped and /helped N / A
* [ ] Allow multiple users to be awarded points on a single post
* So just check whether each user is already awarded a point for a given post
## Bugs ## Bugs
* [ ] Users can get multiple points for same solution * [ ] Users can get multiple points for same solution

View File

@@ -1,10 +1,8 @@
import logging import logging
from logging.handlers import RotatingFileHandler
import os
import os.path
import re import re
import sys import sys
from collections import namedtuple from collections import namedtuple
from logging.handlers import RotatingFileHandler
import praw import praw
import prawcore import prawcore
@@ -20,6 +18,7 @@ SOLVED_PATTERN = re.compile('![Hh]elped')
MOD_SOLVED_PATTERN = re.compile('/[Hh]elped') MOD_SOLVED_PATTERN = re.compile('/[Hh]elped')
MOD_REMOVE_PATTERN = re.compile('/[Rr]emove[Pp]oint') MOD_REMOVE_PATTERN = re.compile('/[Rr]emove[Pp]oint')
### Main Function ### ### Main Function ###
@@ -102,26 +101,22 @@ def monitor_comments(reddit, subreddit, db, levels, cfg):
logging.info('Comment was submitted by mod') logging.info('Comment was submitted by mod')
elif is_valid_tag(comm, cfg.tags): elif is_valid_tag(comm, cfg.tags):
logging.info('Comment has a valid tag') logging.info('Comment has a valid tag')
# elif is_valid_tag(comm, cfg.tags) and is_valid_flair(comm):
# logging.info('Comment has a valid tag and is not already marked as solved')
# else:
# # Skip this "!solved" comment
# logging.info('Comment is NOT the first to mark the issue as solved')
# continue
if not remove_point:
log_solution_info(comm)
# solver = find_solver(comm)
solver, solution_comment = find_solver_and_comment(comm) solver, solution_comment = find_solver_and_comment(comm)
solver_has_already_solved = db.has_already_solved_once(solution_comment.submission, solver)
if not remove_point and solver_has_already_solved:
logging.info('User "%s" has already solved this submission once', solver.name)
logging.info('No additional points awarded')
continue
if remove_point: if remove_point:
# db.remove_point(solver)
# db.remove_point_for_solution(submission, solver, solution_comment, remover, removed_by_comment)
# db.remove_point_for_solution(comm.submission, )
db.soft_remove_point_for_solution(comm.submission, solver, comm.author, comm) db.soft_remove_point_for_solution(comm.submission, solver, comm.author, comm)
logging.info('Removed point for user "%s"', solver.name) logging.info('Removed point for user "%s"', solver.name)
else: else:
# db.add_point(solver) logging.info('Submission solved')
# db.add_point_for_solution(submission, solver, solution_comment, chooser, chosen_by_comment) logging.debug('Solution comment:')
logging.debug('Author: %s', solution_comment.author.name)
logging.debug('Body: %s', solution_comment.body)
db.add_point_for_solution(comm.submission, solver, solution_comment, comm.author, comm) db.add_point_for_solution(comm.submission, solver, solution_comment, comm.author, comm)
logging.info('Added point for user "%s"', solver.name) logging.info('Added point for user "%s"', solver.name)
@@ -146,11 +141,9 @@ def monitor_comments(reddit, subreddit, db, levels, cfg):
except praw.exceptions.APIException as e: except praw.exceptions.APIException as e:
logging.error('Unable to reply to comment: %s', e) logging.error('Unable to reply to comment: %s', e)
if remove_point: if remove_point:
# db.add_point(solver)
db.add_back_point_for_solution(comm.submission, solver) db.add_back_point_for_solution(comm.submission, solver)
logging.error('Re-added point that was just removed from user "%s"', solver.name) logging.error('Re-added point that was just removed from user "%s"', solver.name)
else: else:
# db.remove_point(solver)
db.remove_point_and_delete_solution(comm.submission, solver) db.remove_point_and_delete_solution(comm.submission, solver)
logging.error('Removed point that was just awarded to user "%s"', solver.name) logging.error('Removed point that was just awarded to user "%s"', solver.name)
logging.error('Skipping comment') logging.error('Skipping comment')
@@ -220,8 +213,7 @@ MOD_RESPONSE_RULES = [
'author is mod', 'author is mod',
'Comment author is a mod', 'Comment author is a mod',
'Comment author is not a mod', 'Comment author is not a mod',
# TODO Initialize rules in a function so that they can include other # TODO Initialize rules in a function so that they can include other functions
# functions
lambda c: is_mod_comment(c), lambda c: is_mod_comment(c),
), ),
] ]
@@ -298,14 +290,6 @@ def is_valid_tag(solved_comment, valid_tags):
return False return False
# def is_valid_flair(solved_comment):
# """Return True if this comment's post doesn't already have the Solved flair, False otherwise."""
# submission = solved_comment.submission
# return submission.link_flair_text.lower() != "solved"
# def find_solver(solved_comment):
def find_solver_and_comment(solved_comment): def find_solver_and_comment(solved_comment):
"""Determine the redditor responsible for solving the question.""" """Determine the redditor responsible for solving the question."""
# TODO plz make this better someday # TODO plz make this better someday
@@ -337,10 +321,3 @@ def print_welcome_message():
"moment, this is what we've got to work with! :)\n") "moment, this is what we've got to work with! :)\n")
print_separator_line() print_separator_line()
def log_solution_info(comm):
logging.info('Submission solved')
logging.debug('Solution comment:')
logging.debug('Author: %s', comm.parent().author.name)
logging.debug('Body: %s', comm.parent().body)

View File

@@ -49,7 +49,6 @@ def transaction(func):
### Classes ### ### Classes ###
# @functools.total_ordering
class DatabaseVersion: class DatabaseVersion:
PRE_RELEASE_NAME_ORDER_NUMBER = { PRE_RELEASE_NAME_ORDER_NUMBER = {
@@ -67,17 +66,12 @@ class DatabaseVersion:
self.pre_release_number = pre_release_number self.pre_release_number = pre_release_number
def __lt__(self, other): def __lt__(self, other):
# self_tuple = (self.major, self.minor, self.patch, self.PRE_RELEASE_NAME_ORDER_NUMBER[self.pre_release_name], self.pre_release_number)
# other_tuple = (other.major, other.minor, other.patch, self.PRE_RELEASE_NAME_ORDER_NUMBER[other.pre_release_name], other.pre_release_number)
return self._to_tuple() < other._to_tuple() return self._to_tuple() < other._to_tuple()
def __eq__(self, other): def __eq__(self, other):
# self_tuple = (self.major, self.minor, self.patch, self.PRE_RELEASE_NAME_ORDER_NUMBER[self.pre_release_name], self.pre_release_number)
# other_tuple = (other.major, other.minor, other.patch, self.PRE_RELEASE_NAME_ORDER_NUMBER[other.pre_release_name], other.pre_release_number)
return self._to_tuple() == other._to_tuple() return self._to_tuple() == other._to_tuple()
def __hash__(self): def __hash__(self):
# self_tuple = (self.major, self.minor, self.patch, self.PRE_RELEASE_NAME_ORDER_NUMBER[self.pre_release_name], self.pre_release_number)
return hash(self._to_tuple()) return hash(self._to_tuple())
def _to_tuple(self): def _to_tuple(self):
@@ -209,9 +203,6 @@ class Database:
@transaction @transaction
def _get_current_version(self): def _get_current_version(self):
# self.cursor.execute('select * from sqlite_master')
# for row in self.cursor.fetchmany():
# logging.info(tuple(row))
self.cursor.execute("SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'bot_version'") self.cursor.execute("SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'bot_version'")
has_version_table = self.cursor.fetchone() has_version_table = self.cursor.fetchone()
if not has_version_table: if not has_version_table:
@@ -283,8 +274,6 @@ class Database:
@transaction @transaction
def add_back_point_for_solution(self, submission, solver): def add_back_point_for_solution(self, submission, solver):
self._update_points(solver, 1) self._update_points(solver, 1)
# submission_rowid = self._get_rowid_from_reddit_id('submission', submission)
# author_rowid = self._get_rowid_from_reddit_id('redditor', solver)
submission_rowid = self._get_submission_rowid(submission) submission_rowid = self._get_submission_rowid(submission)
author_rowid = self._get_redditor_rowid(solver) author_rowid = self._get_redditor_rowid(solver)
params = {'submission_rowid': submission_rowid, 'author_rowid': author_rowid} params = {'submission_rowid': submission_rowid, 'author_rowid': author_rowid}
@@ -299,8 +288,6 @@ class Database:
@transaction @transaction
def remove_point_and_delete_solution(self, submission, solver): def remove_point_and_delete_solution(self, submission, solver):
params = { params = {
# 'submission_rowid': self._get_rowid_from_reddit_id('submission', submission),
# 'author_rowid': self._get_rowid_from_reddit_id('redditor', solver)
'submission_rowid': self._get_submission_rowid(submission), 'submission_rowid': self._get_submission_rowid(submission),
'author_rowid': self._get_redditor_rowid(solver) 'author_rowid': self._get_redditor_rowid(solver)
} }
@@ -332,19 +319,8 @@ class Database:
### Private Methods ### ### Private Methods ###
# @transaction
# def _get_rowid_from_reddit_id(self, table_name, reddit_object):
# params = {'table_name': table_name, 'reddit_id': reddit_object.id}
# self.cursor.execute('SELECT rowid FROM :table_name WHERE id = :reddit_id', params)
# row = self.cursor.fetchone()
# return row['rowid'] if row else None
# @transaction
def _get_submission_rowid(self, submission): def _get_submission_rowid(self, submission):
return self._get_rowid_from_reddit_id('SELECT rowid FROM submission WHERE id = :reddit_id', {'reddit_id': submission.id}) return self._get_rowid_from_reddit_id('SELECT rowid FROM submission WHERE id = :reddit_id', {'reddit_id': submission.id})
# self.cursor.execute('SELECT rowid FROM submission WHERE id = :reddit_id', {'reddit_id': submission.id})
# row = self.cursor.fetchone()
# return row['rowid'] if row else None
def _get_comment_rowid(self, comment): def _get_comment_rowid(self, comment):
return self._get_rowid_from_reddit_id('SELECT rowid FROM comment WHERE id = :reddit_id', {'reddit_id': comment.id}) return self._get_rowid_from_reddit_id('SELECT rowid FROM comment WHERE id = :reddit_id', {'reddit_id': comment.id})

View File

@@ -158,12 +158,7 @@ def footer(feedback_url=None, scoreboard_url=None):
if feedback_url: if feedback_url:
# https://forms.gle/m94aGjFQwGopqQ836 # https://forms.gle/m94aGjFQwGopqQ836
footer_sections.append(f'[^Feedback]({feedback_url})') footer_sections.append(f'[^Feedback]({feedback_url})')
footer_sections.append('[^Source ^Code](https://github.com/cur33/PointsBot)') footer_sections.append('[^Source Code](https://github.com/cur33/PointsBot)')
return ' ^| '.join(footer_sections) return ' ^| '.join(footer_sections)
# return ('^(Bot maintained by GlipGlorp7 '
# '| [Scoreboard](https://points.minecrafthelp.co.uk) '
# '| [Feedback](https://forms.gle/m94aGjFQwGopqQ836) '
# '| [Source Code](https://github.com/cur33/PointsBot))')