User cannot get duplicate points on same post
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
|
||||||
|
|
||||||
|
|||||||
@@ -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})
|
||||||
|
|||||||
@@ -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))')
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user