diff --git a/files/__main__.py b/files/__main__.py index e76d36703..c77f44186 100644 --- a/files/__main__.py +++ b/files/__main__.py @@ -128,6 +128,8 @@ app.config['RESULTS_PER_PAGE_COMMENTS'] = int(environ.get('RESULTS_PER_PAGE_COMM app.config['SCORE_HIDING_TIME_HOURS'] = int(environ.get('SCORE_HIDING_TIME_HOURS')) app.config['ENABLE_SERVICES'] = bool_from_string(environ.get('ENABLE_SERVICES', False)) +app.config['DBG_VOLUNTEER_PERMISSIVE'] = bool(environ.get('DBG_VOLUNTEER_PERMISSIVE', False)) + r=redis.Redis(host=environ.get("REDIS_URL", "redis://localhost"), decode_responses=True, ssl_cert_reqs=None) def get_remote_addr(): diff --git a/files/classes/__init__.py b/files/classes/__init__.py index 603843864..b182c6840 100644 --- a/files/classes/__init__.py +++ b/files/classes/__init__.py @@ -82,6 +82,7 @@ from .userblock import UserBlock from .usernotes import UserTag, UserNote from .views import ViewerRelationship from .votes import Vote, CommentVote +from .volunteer_janitor import VolunteerJanitorRecord # Then the import * from files.* from files.helpers.const import * diff --git a/files/classes/volunteer_janitor.py b/files/classes/volunteer_janitor.py new file mode 100644 index 000000000..2c984d470 --- /dev/null +++ b/files/classes/volunteer_janitor.py @@ -0,0 +1,29 @@ + +import enum +from files.__main__ import Base +from sqlalchemy import * +from sqlalchemy.orm import relationship + +class VolunteerJanitorResult(enum.Enum): + Pending = 0 + TopQuality = 1 + Good = 2 + Neutral = 3 + Bad = 4 + Warning = 5 + Ban = 6 + +class VolunteerJanitorRecord(Base): + + __tablename__ = "volunteer_janitor" + + id = Column(Integer, primary_key=True) + user_id = Column(Integer, ForeignKey("users.id"), nullable=False) + comment_id = Column(Integer, ForeignKey("comments.id"), nullable=False) + edited_utc = Column(DateTime, default=0, nullable=False) + result = Column(Enum(VolunteerJanitorResult), default=VolunteerJanitorResult.Pending, nullable=False) + + Index('volunteer_comment_index', user_id, comment_id) + + user = relationship("User") + comment = relationship("Comment") diff --git a/files/routes/volunteer.py b/files/routes/volunteer.py index c3ff3e452..d7fedcd4f 100644 --- a/files/routes/volunteer.py +++ b/files/routes/volunteer.py @@ -20,8 +20,9 @@ def volunteer_get_duty(u: Optional[User]) -> Optional[VolunteerDuty]: return None # check to make sure it's at least 20h since the last volunteer - if (u.volunteer_last_started_utc is not None) and (datetime.now() - u.volunteer_last_started_utc) < timedelta(hours = 20): - return None + if not app.config['DBG_VOLUNTEER_PERMISSIVE']: + if (u.volunteer_last_started_utc is not None) and (datetime.now() - u.volunteer_last_started_utc) < timedelta(hours = 20): + return None # TODO: clever code that figures out the most important duty available janitor = files.routes.volunteer_janitor.get_duty(u) @@ -38,7 +39,7 @@ def volunteer(v: User): duty = volunteer_get_duty(v) if duty is not None: - duty.accept() + duty.accept(v) v.volunteer_last_started_utc = sqlalchemy.func.now() g.db.add(v) g.db.commit() diff --git a/files/routes/volunteer_janitor.py b/files/routes/volunteer_janitor.py index c7fae62ec..3ef080703 100644 --- a/files/routes/volunteer_janitor.py +++ b/files/routes/volunteer_janitor.py @@ -1,24 +1,35 @@ +from files.__main__ import app from files.classes.comment import Comment from files.classes.flags import CommentFlag from files.classes.user import User +from files.classes.volunteer_janitor import VolunteerJanitorRecord, VolunteerJanitorResult from files.routes.volunteer_common import VolunteerDuty from flask import g import pprint import random +import sqlalchemy class VolunteerDutyJanitor(VolunteerDuty): def __init__(self, choices): self.choices = choices - def accept(self) -> None: - pprint.pprint(self.choices) - pass + def accept(self, v) -> None: + for item in self.choices: + record = VolunteerJanitorRecord() + record.user_id = v.id + record.comment_id = item + record.edited_utc = sqlalchemy.func.now() + record.result = VolunteerJanitorResult.Pending + g.db.add(record) + + g.db.commit() def embed_template(self) -> str: return "volunteer_janitor.html" + def get_duty(u: User) -> VolunteerDutyJanitor: # these could probably be combined into one query somehow @@ -31,26 +42,34 @@ def get_duty(u: User) -> VolunteerDutyJanitor: reported_ids = [reported.id for reported in reported_comments] - # find distinguished children of those reported comments - distinguished_children = g.db.query(Comment) \ - .where(Comment.parent_comment_id.in_(reported_ids)) \ - .where(Comment.distinguish_level > 0) \ - .with_entities(Comment.parent_comment_id) + if not app.config['DBG_VOLUNTEER_PERMISSIVE']: + # find distinguished children of those reported comments + distinguished_children = g.db.query(Comment) \ + .where(Comment.parent_comment_id.in_(reported_ids)) \ + .where(Comment.distinguish_level > 0) \ + .with_entities(Comment.parent_comment_id) - distinguished_children_ids = [child.parent_comment_id for child in distinguished_children] + distinguished_children_ids = [child.parent_comment_id for child in distinguished_children] - # filter - # we're doing this because we don't want to give people hints as to the "right" result - # once a modhat hits, that's it, doesn't show up in the volunteer system anymore - clean_reported = set(reported_ids) - set(distinguished_children_ids) + # filter + # we're doing this because we don't want to give people hints as to the "right" result + # once a modhat hits, that's it, doesn't show up in the volunteer system anymore + clean_reported = set(reported_ids) - set(distinguished_children_ids) - # also, let's make sure it has a report that isn't made by this user - nonuser_reports = g.db.query(CommentFlag) \ - .where(CommentFlag.comment_id.in_(clean_reported)) \ - .where(CommentFlag.user_id != u.id) \ - .with_entities(CommentFlag.comment_id) + # also, let's make sure it has a report that isn't made by this user + nonuser_reports = g.db.query(CommentFlag) \ + .where(CommentFlag.comment_id.in_(clean_reported)) \ + .where(CommentFlag.user_id != u.id) \ + .with_entities(CommentFlag.comment_id) - final_reported = [report.comment_id for report in nonuser_reports] + # also, let's make sure it hasn't already been looked at by this user + seen_records = g.db.query(VolunteerJanitorRecord) \ + .where(VolunteerJanitorRecord.user_id == u.id) \ + .with_entities(CommentFlag.comment_id) + + final_reported = list({report.comment_id for report in nonuser_reports} - {record.comment_id for record in seen_records}) + else: + final_reported = reported_ids if len(final_reported) <= 0: return None diff --git a/migrations/versions/2022_11_19_10_21_36_65ce80ffc30e_add_volunteer_janitor_tracking.py b/migrations/versions/2022_11_19_10_21_36_65ce80ffc30e_add_volunteer_janitor_tracking.py new file mode 100644 index 000000000..950243e91 --- /dev/null +++ b/migrations/versions/2022_11_19_10_21_36_65ce80ffc30e_add_volunteer_janitor_tracking.py @@ -0,0 +1,39 @@ +"""Add volunteer janitor tracking. + +Revision ID: 65ce80ffc30e +Revises: d7a4a6723411 +Create Date: 2022-11-19 10:21:36.385505+00:00 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '65ce80ffc30e' +down_revision = 'd7a4a6723411' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('volunteer_janitor', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('user_id', sa.Integer(), nullable=False), + sa.Column('comment_id', sa.Integer(), nullable=False), + sa.Column('edited_utc', sa.DateTime(), nullable=False), + sa.Column('result', sa.Enum('Pending', 'TopQuality', 'Good', 'Neutral', 'Bad', 'Warning', 'Ban', name='volunteerjanitorresult'), nullable=False), + sa.ForeignKeyConstraint(['comment_id'], ['comments.id'], ), + sa.ForeignKeyConstraint(['user_id'], ['users.id'], ), + sa.PrimaryKeyConstraint('id') + ) + op.create_index('volunteer_comment_index', 'volunteer_janitor', ['user_id', 'comment_id'], unique=False) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_index('volunteer_comment_index', table_name='volunteer_janitor') + op.drop_table('volunteer_janitor') + # ### end Alembic commands ###