Volunteer Janitor: Record accepted tasks.

This commit is contained in:
Ben Rog-Wilhelm 2022-11-19 05:02:12 -06:00 committed by Ben Rog-Wilhelm
parent 03b323c7a1
commit 0a8bbae290
6 changed files with 113 additions and 22 deletions

View file

@ -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['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['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) r=redis.Redis(host=environ.get("REDIS_URL", "redis://localhost"), decode_responses=True, ssl_cert_reqs=None)
def get_remote_addr(): def get_remote_addr():

View file

@ -82,6 +82,7 @@ from .userblock import UserBlock
from .usernotes import UserTag, UserNote from .usernotes import UserTag, UserNote
from .views import ViewerRelationship from .views import ViewerRelationship
from .votes import Vote, CommentVote from .votes import Vote, CommentVote
from .volunteer_janitor import VolunteerJanitorRecord
# Then the import * from files.* # Then the import * from files.*
from files.helpers.const import * from files.helpers.const import *

View file

@ -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")

View file

@ -20,8 +20,9 @@ def volunteer_get_duty(u: Optional[User]) -> Optional[VolunteerDuty]:
return None return None
# check to make sure it's at least 20h since the last volunteer # 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): if not app.config['DBG_VOLUNTEER_PERMISSIVE']:
return None 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 # TODO: clever code that figures out the most important duty available
janitor = files.routes.volunteer_janitor.get_duty(u) janitor = files.routes.volunteer_janitor.get_duty(u)
@ -38,7 +39,7 @@ def volunteer(v: User):
duty = volunteer_get_duty(v) duty = volunteer_get_duty(v)
if duty is not None: if duty is not None:
duty.accept() duty.accept(v)
v.volunteer_last_started_utc = sqlalchemy.func.now() v.volunteer_last_started_utc = sqlalchemy.func.now()
g.db.add(v) g.db.add(v)
g.db.commit() g.db.commit()

View file

@ -1,24 +1,35 @@
from files.__main__ import app
from files.classes.comment import Comment from files.classes.comment import Comment
from files.classes.flags import CommentFlag from files.classes.flags import CommentFlag
from files.classes.user import User from files.classes.user import User
from files.classes.volunteer_janitor import VolunteerJanitorRecord, VolunteerJanitorResult
from files.routes.volunteer_common import VolunteerDuty from files.routes.volunteer_common import VolunteerDuty
from flask import g from flask import g
import pprint import pprint
import random import random
import sqlalchemy
class VolunteerDutyJanitor(VolunteerDuty): class VolunteerDutyJanitor(VolunteerDuty):
def __init__(self, choices): def __init__(self, choices):
self.choices = choices self.choices = choices
def accept(self) -> None: def accept(self, v) -> None:
pprint.pprint(self.choices) for item in self.choices:
pass 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: def embed_template(self) -> str:
return "volunteer_janitor.html" return "volunteer_janitor.html"
def get_duty(u: User) -> VolunteerDutyJanitor: def get_duty(u: User) -> VolunteerDutyJanitor:
# these could probably be combined into one query somehow # 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] reported_ids = [reported.id for reported in reported_comments]
# find distinguished children of those reported comments if not app.config['DBG_VOLUNTEER_PERMISSIVE']:
distinguished_children = g.db.query(Comment) \ # find distinguished children of those reported comments
.where(Comment.parent_comment_id.in_(reported_ids)) \ distinguished_children = g.db.query(Comment) \
.where(Comment.distinguish_level > 0) \ .where(Comment.parent_comment_id.in_(reported_ids)) \
.with_entities(Comment.parent_comment_id) .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 # filter
# we're doing this because we don't want to give people hints as to the "right" result # 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 # 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) 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 # also, let's make sure it has a report that isn't made by this user
nonuser_reports = g.db.query(CommentFlag) \ nonuser_reports = g.db.query(CommentFlag) \
.where(CommentFlag.comment_id.in_(clean_reported)) \ .where(CommentFlag.comment_id.in_(clean_reported)) \
.where(CommentFlag.user_id != u.id) \ .where(CommentFlag.user_id != u.id) \
.with_entities(CommentFlag.comment_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: if len(final_reported) <= 0:
return None return None

View file

@ -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 ###