Skip to content

Commit

Permalink
Add feature to track askhistorians reminders
Browse files Browse the repository at this point in the history
  • Loading branch information
Watchful1 committed Aug 16, 2024
1 parent 42945b4 commit 007b1ff
Show file tree
Hide file tree
Showing 9 changed files with 278 additions and 3 deletions.
40 changes: 40 additions & 0 deletions scripts/database_sandbox.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import discord_logging
import sqlalchemy
from datetime import datetime, timedelta
import os

log = discord_logging.init_logging()

from database import Database
from classes.comment import DbComment
from classes.reminder import Reminder
from classes.subreddit import Subreddit
from classes.user import User
import utils

if __name__ == "__main__":
backup_folder = r"D:\backup\RemindMeBot"
date_str = "24-05-15 00:00"
backup_before = datetime.strptime(date_str, "%y-%m-%d %H:%M")

found = False
for subdir, dirs, files in os.walk(backup_folder):
for filename in reversed(files):
if filename.endswith(".db"):
input_path = os.path.join(subdir, filename)
try:
backup_date = datetime.strptime(filename[:-3], "%Y-%m-%d_%H-%M")
if backup_date > backup_before:
continue

database = Database(override_location=input_path, readonly=True, quiet=True)
user = database.get_or_add_user("SilynJaguar")
reminders = database.session.query(Reminder).filter_by(user=user).all()
#log.info(f"{backup_date}: {banned_count}")
database.close()
found = True
break
except (ValueError, sqlalchemy.exc.OperationalError):
continue
if found:
break
4 changes: 2 additions & 2 deletions scripts/explain_parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@

cal = parsedatetime.Calendar()

input_string = '''RemindMe! 1 April 2033 /r/baseball/comments/111fdk1/rogers_breaking_mlbs_joint_competition_committee/j8g3jfu/'''
base_time_string = "2023-02-14 03:40:19 -0000"
input_string = '''!remindme 30th of February, 2024.'''
base_time_string = "2023-04-27 02:45:19 -0700"
timezone_string = None # "America/New_York"

if base_time_string:
Expand Down
30 changes: 30 additions & 0 deletions scripts/iterate_backups_longest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import discord_logging
import sqlalchemy
from datetime import datetime, timedelta
import os

log = discord_logging.init_logging()

from database import Database
from classes.comment import DbComment
from classes.reminder import Reminder
from classes.subreddit import Subreddit
from classes.user import User
import utils

if __name__ == "__main__":
backup_folder = r"D:\backup\RemindMeBot"

for subdir, dirs, files in os.walk(backup_folder):
for filename in files:
if filename.endswith(".db"):
input_path = os.path.join(subdir, filename)
try:
backup_date = datetime.strptime(filename[:-3], "%Y-%m-%d_%H-%M")

database = Database(override_location=input_path, readonly=True, quiet=True)
banned_count = database.session.query(Subreddit).filter_by(banned=True).count()
log.info(f"{backup_date}: {banned_count}")
database.close()
except (ValueError, sqlalchemy.exc.OperationalError):
continue
13 changes: 13 additions & 0 deletions src/classes/reminder.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
from datetime import timedelta
from sqlalchemy import Column, Integer, String, Boolean, ForeignKey
from sqlalchemy.orm import relationship
import re

import static
from praw_wrapper.reddit import ReturnType
from database import Base
from database.UtcDateTime import UtcDateTime
from classes.stat import DbStat


log = discord_logging.get_logger()
Expand Down Expand Up @@ -137,6 +139,17 @@ def is_cakeday(self):
return self.message is not None and self.message == static.CAKEDAY_MESSAGE and \
self.recurrence is not None and self.recurrence == "1 year"

def get_target_ids(self):
if self.message is None:
return None, None, None
match = re.search(r"r/(\w+)/comments/(\w+)/\w*/?(\w+)?", self.message)
if match is None:
return None, None, None
subreddit = match.group(1)
thread_id = match.group(2)
comment_id = match.group(3)
return subreddit, thread_id, comment_id

def render_message_confirmation(self, result_message, comment_return=None, comment_age_seconds=0):
bldr = utils.str_bldr()
if comment_age_seconds > (60 * 60):
Expand Down
29 changes: 29 additions & 0 deletions src/classes/stat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from sqlalchemy import Column, ForeignKey, Integer, String
from database import Base
from database.UtcDateTime import UtcDateTime

import utils


class DbStat(Base):
__tablename__ = 'stats'

id = Column(Integer, primary_key=True)
subreddit = Column(String(80), nullable=False)
thread_id = Column(String(12), nullable=False)
comment_id = Column(String(12))
initial_date = Column(UtcDateTime, nullable=False)
count_reminders = Column(Integer, nullable=False)

def __init__(
self,
subreddit,
thread_id,
comment_id,
count_reminders=1
):
self.subreddit = subreddit
self.thread_id = thread_id
self.comment_id = comment_id
self.count_reminders = count_reminders
self.initial_date = utils.datetime_now()
4 changes: 3 additions & 1 deletion src/database/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from ._comments import _DatabaseComments
from ._subreddits import _DatabaseSubreddit
from ._users import _DatabaseUsers
from ._stats import _DatabaseStats

log = discord_logging.get_logger()

Expand All @@ -22,7 +23,7 @@ def abort_ro(*args,**kwargs):
return


class Database(_DatabaseReminders, _DatabaseComments, _DatabaseKeystore, _DatabaseSubreddit, _DatabaseUsers):
class Database(_DatabaseReminders, _DatabaseComments, _DatabaseKeystore, _DatabaseSubreddit, _DatabaseUsers, _DatabaseStats):
def __init__(self, debug=False, publish=False, override_location=None, readonly=False, quiet=False):
if not quiet:
log.info(f"Initializing database class: debug={debug} publish={publish}")
Expand All @@ -35,6 +36,7 @@ def __init__(self, debug=False, publish=False, override_location=None, readonly=
_DatabaseKeystore.__init__(self)
_DatabaseSubreddit.__init__(self)
_DatabaseUsers.__init__(self)
_DatabaseStats.__init__(self)

def init(self, debug, publish, override_location=None, readonly=False):
if debug:
Expand Down
3 changes: 3 additions & 0 deletions src/database/_reminders.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ def add_reminder(self, reminder):
log.debug("Saving new reminder")
self.session.add(reminder)

subreddit, thread_id, comment_id = reminder.get_target_ids()
self.add_increment_stat(subreddit, thread_id, comment_id)

def get_count_pending_reminders(self, timestamp):
log.debug("Fetching count of pending reminders")

Expand Down
65 changes: 65 additions & 0 deletions src/database/_stats.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import discord_logging
from sqlalchemy.orm import joinedload

import static
from classes.stat import DbStat

log = discord_logging.get_logger()


class _DatabaseStats:
def __init__(self):
self.session = self.session # for pycharm linting

def add_increment_stat(self, subreddit, thread_id, comment_id):
log.debug(f"Adding or incrementing new stat")
if subreddit is None or thread_id is None:
log.debug(f"Empty arguments, returning")
return

if subreddit.lower() != "askhistorians":
log.debug(f"Subreddit doesn't match filter, returning")
return

existing_stat = self.session.query(DbStat)\
.filter(DbStat.subreddit == subreddit)\
.filter(DbStat.thread_id == thread_id)\
.filter(DbStat.comment_id == comment_id)\
.first()

if existing_stat is not None:
log.debug(f"Stat exists, incrementing")
existing_stat.count_reminders += 1
else:
log.debug(f"Stat doesn't exist, creating")
new_stat = DbStat(subreddit, thread_id, comment_id)
self.session.add(new_stat)

def get_stats_for_ids(self, subreddit, thread_id, comment_id=None):
log.debug("Fetching stat")

stat = self.session.query(DbStat)\
.filter(DbStat.subreddit == subreddit)\
.filter(DbStat.thread_id == thread_id)\
.filter(DbStat.comment_id == comment_id)\
.first()

if stat is None:
log.debug("No stat found")
else:
log.debug(f"Stat found with: {stat.count_reminders}")

return stat

def get_stats_for_subreddit(self, subreddit, earliest_date):
log.debug("Fetching stats for subreddit")

stats = self.session.query(DbStat)\
.filter(DbStat.subreddit == subreddit)\
.filter(DbStat.initial_date > earliest_date)\
.order_by(DbStat.initial_date.asc())\
.all()

log.debug(f"{len(stats)} stats found")
return stats

93 changes: 93 additions & 0 deletions test/stat_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import utils
import notifications
import static
from praw_wrapper import reddit_test
import messages
from datetime import timedelta
from classes.reminder import Reminder


def test_add_stat(database, reddit):
utils.debug_time = utils.parse_datetime_string("2019-01-05 12:00:00")
reminder = Reminder(
source="https://www.reddit.com/message/messages/XXXXX",
message="""[https://www.reddit.com/r/AskHistorians/comments/1emshj8/___/]
RemindMe! 2 days""",
user=database.get_or_add_user("Watchful1"),
requested_date=utils.parse_datetime_string("2019-01-01 04:00:00"),
target_date=utils.parse_datetime_string("2019-01-05 05:00:00")
)
database.add_reminder(reminder)

stat = database.get_stats_for_ids("AskHistorians", "1emshj8")
assert stat.count_reminders == 1
assert stat.initial_date == utils.debug_time

reminder = Reminder(
source="https://www.reddit.com/message/messages/YYYYY",
message="""[https://www.reddit.com/r/AskHistorians/comments/1emshj8/___/]
RemindMe! 2 days""",
user=database.get_or_add_user("Watchful1"),
requested_date=utils.parse_datetime_string("2019-01-01 04:00:00"),
target_date=utils.parse_datetime_string("2019-01-05 05:00:00")
)
database.add_reminder(reminder)

stat = database.get_stats_for_ids("AskHistorians", "1emshj8")
assert stat.count_reminders == 2
assert stat.initial_date == utils.debug_time


def test_add_stats(database, reddit):
utils.debug_time = utils.parse_datetime_string("2019-01-05 12:00:00")
reminders = [
Reminder(
source="https://www.reddit.com/message/messages/XXXXX",
message="[https://www.reddit.com/r/AskHistorians/comments/1emshj8/___/]",
user=database.get_or_add_user("Watchful1"),
requested_date=utils.parse_datetime_string("2019-01-01 04:00:00"),
target_date=utils.parse_datetime_string("2019-01-05 05:00:00")
),
Reminder(
source="https://www.reddit.com/message/messages/XXXXX",
message="[https://www.reddit.com/r/AskHistorians/comments/1emshk6/___/]",
user=database.get_or_add_user("Watchful1"),
requested_date=utils.parse_datetime_string("2019-01-01 04:00:00"),
target_date=utils.parse_datetime_string("2019-01-06 05:00:00")
),
Reminder(
source="https://www.reddit.com/message/messages/XXXXX",
message="[https://www.reddit.com/r/AskHistorians/comments/1emshk6/___/]",
user=database.get_or_add_user("Watchful1"),
requested_date=utils.parse_datetime_string("2019-01-01 04:00:00"),
target_date=utils.parse_datetime_string("2019-01-07 05:00:00")
),
Reminder(
source="https://www.reddit.com/message/messages/XXXXX",
message="[https://www.reddit.com/r/AskHistorians/comments/1emshk6/___/]",
user=database.get_or_add_user("Watchful1"),
requested_date=utils.parse_datetime_string("2019-01-01 04:00:00"),
target_date=utils.parse_datetime_string("2019-01-07 05:00:00")
),
Reminder(
source="https://www.reddit.com/message/messages/XXXXX",
message="[https://www.reddit.com/r/history/comments/1emshf5/___/]",
user=database.get_or_add_user("Watchful1"),
requested_date=utils.parse_datetime_string("2019-01-01 04:00:00"),
target_date=utils.parse_datetime_string("2019-01-08 05:00:00")
),
Reminder(
source="https://www.reddit.com/message/messages/XXXXX",
message="[https://www.reddit.com/r/AskHistorians/comments/1emshj8/___/]",
user=database.get_or_add_user("Watchful1"),
requested_date=utils.parse_datetime_string("2019-01-01 04:00:00"),
target_date=utils.parse_datetime_string("2019-01-09 05:00:00")
)
]
for reminder in reminders:
database.add_reminder(reminder)

stats = database.get_stats_for_subreddit("AskHistorians", utils.debug_time - timedelta(days=1))
assert len(stats) == 2
assert stats[0].count_reminders == 2
assert stats[1].count_reminders == 3

0 comments on commit 007b1ff

Please sign in to comment.