Orders - Require alt text setting

This commit is contained in:
Johnny Gear 2026-03-30 16:18:30 -05:00
parent 87ddc4b998
commit ff7f59e8b0
8 changed files with 84 additions and 4 deletions

View file

@ -36,6 +36,7 @@ class User(BaseModel):
mastodon_attn_list = TextField(null=True)
mastodon_post_public = BooleanField(null=True, default=False)
verify_mastodon_alt_text = BooleanField(null=False, default=False)
verify_mastodon_favorite = BooleanField(null=False, default=False)
verify_delay = IntegerField(null=True)

View file

@ -0,0 +1,49 @@
"""Peewee migrations -- 028_add_verify_mastodon_alt_text.py.
Some examples (model - class or model name)::
> Model = migrator.orm['table_name'] # Return model in current state by name
> Model = migrator.ModelClass # Return model in current state by name
> migrator.sql(sql) # Run custom SQL
> migrator.run(func, *args, **kwargs) # Run python function with the given args
> migrator.create_model(Model) # Create a model (could be used as decorator)
> migrator.remove_model(model, cascade=True) # Remove a model
> migrator.add_fields(model, **fields) # Add fields to a model
> migrator.change_fields(model, **fields) # Change fields
> migrator.remove_fields(model, *field_names, cascade=True)
> migrator.rename_field(model, old_field_name, new_field_name)
> migrator.rename_table(model, new_table_name)
> migrator.add_index(model, *col_names, unique=False)
> migrator.add_not_null(model, *field_names)
> migrator.add_default(model, field_name, default)
> migrator.add_constraint(model, name, sql)
> migrator.drop_index(model, *col_names)
> migrator.drop_not_null(model, *field_names)
> migrator.drop_constraints(model, *constraints)
"""
from contextlib import suppress
import peewee as pw
from peewee_migrate import Migrator
with suppress(ImportError):
import playhouse.postgres_ext as pw_pext
def migrate(migrator: Migrator, database: pw.Database, *, fake=False):
"""Write your migrations here."""
migrator.add_fields(
'user',
verify_mastodon_alt_text=pw.BooleanField(default=False))
def rollback(migrator: Migrator, database: pw.Database, *, fake=False):
"""Write your rollback migrations here."""
migrator.remove_fields('user', 'verify_mastodon_alt_text')

View file

@ -226,6 +226,7 @@ async def order_check(order_status_id):
confirmed_at = None
had_replies = False
had_reply_on_time = False
had_alt_text = False
had_media_attachment = False
had_favorites = False
for d in context['descendants']:
@ -234,6 +235,10 @@ async def order_check(order_status_id):
d['account']['acct'] == order_status.user.mastodon_account()
):
had_replies = True
had_reply_on_time = False
had_alt_text = False
had_media_attachment = False
had_favorites = False
if (datetime.datetime.fromisoformat(d['created_at']) <
datetime.datetime.fromisoformat(order_status.due_at)):
@ -246,6 +251,14 @@ async def order_check(order_status_id):
else:
continue
if user.verify_mastodon_alt_text:
if all([(
'description' in a and a['description'] is not None
) for a in d['media_attachments']]):
had_alt_text = True
else:
continue
if user.verify_mastodon_favorite:
if await status_has_favorites(m, d['id'], order_status.user):
had_favorites = True
@ -279,7 +292,9 @@ async def order_check(order_status_id):
reason = "Reply was after due date"
elif had_media_attachment is False:
reason = "No replies had a media attachment"
elif had_favorites is False:
elif user.verify_mastodon_alt_text and had_alt_text is False:
reason = "Not all media attachments had alt text"
elif user.verify_mastodon_favorite and had_favorites is False:
reason = "No replies had a favorite from a dom or tagged account"
logger.info('Time to issue a punishment for %s' % order_status.id)

View file

@ -32,6 +32,7 @@ def me():
if not has_doms:
result["verify_mastodon_alt_text"] = user.verify_mastodon_alt_text
result["verify_mastodon_favorite"] = user.verify_mastodon_favorite
result["verify_delay"] = user.verify_delay
@ -168,6 +169,7 @@ def sub(username, sub):
if request.method == "POST":
sub.verify_mastodon_favorite = bool(request.json['verify_mastodon_favorite'])
sub.verify_mastodon_alt_text = bool(request.json['verify_mastodon_alt_text'])
if request.json['verify_delay'] is not None:
sub.verify_delay = int(request.json["verify_delay"])
@ -179,6 +181,7 @@ def sub(username, sub):
"username": sub.telegram_username,
"mastodon_server": sub.mastodon_server.name if sub.mastodon_server is not None else None,
"mastodon_username": sub.mastodon_username,
"verify_mastodon_alt_text": sub.verify_mastodon_alt_text,
"verify_mastodon_favorite": sub.verify_mastodon_favorite,
"verify_delay": sub.verify_delay
})

View file

@ -68,6 +68,7 @@ export const Profile: React.FC = () => {
has_doms,
mastodon_attn_list,
mastodon_post_public,
verify_mastodon_alt_text,
verify_mastodon_favorite,
verify_delay,
} = useLoaderData<UserProfile>();
@ -162,6 +163,7 @@ export const Profile: React.FC = () => {
{!has_doms ? (
<ProfileVerification
username={username}
verify_mastodon_alt_text={verify_mastodon_alt_text}
verify_mastodon_favorite={verify_mastodon_favorite}
verify_delay={verify_delay}
/>

View file

@ -13,16 +13,17 @@ import React from "react";
type ProfileVerificationProps = Pick<
UserProfile,
"verify_mastodon_favorite" | "verify_delay"
"verify_mastodon_alt_text" | "verify_mastodon_favorite" | "verify_delay"
> & { username: string };
type OrderVerificationForm = Pick<
UserProfile,
"verify_mastodon_favorite" | "verify_delay"
"verify_mastodon_alt_text" | "verify_mastodon_favorite" | "verify_delay"
>;
export const ProfileVerification: React.FC<ProfileVerificationProps> = ({
username,
verify_mastodon_alt_text,
verify_mastodon_favorite,
verify_delay,
}) => {
@ -30,12 +31,12 @@ export const ProfileVerification: React.FC<ProfileVerificationProps> = ({
const form = useForm<OrderVerificationForm>({
mode: "uncontrolled",
initialValues: {
verify_mastodon_alt_text,
verify_mastodon_favorite,
verify_delay,
},
validate: {
verify_delay: (value: number, values: OrderVerificationForm) => {
console.log("oh boy", values.verify_mastodon_favorite, value);
return !values.verify_mastodon_favorite || value
? null
: "You must set a verification delay";
@ -79,6 +80,13 @@ export const ProfileVerification: React.FC<ProfileVerificationProps> = ({
<Title order={4} mb="md">
Order Verification
</Title>
<Checkbox
{...form.getInputProps("verify_mastodon_alt_text", {
type: "checkbox",
})}
label="Media on posts must have alt text"
mb="md"
/>
<Checkbox
{...form.getInputProps("verify_mastodon_favorite", {
type: "checkbox",

View file

@ -35,6 +35,7 @@ export const SubOrderSets: React.FC = () => {
</Title>
<ProfileVerification
username={sub_username}
verify_mastodon_alt_text={profile.verify_mastodon_alt_text}
verify_mastodon_favorite={profile.verify_mastodon_favorite}
verify_delay={profile.verify_delay}
/>

View file

@ -6,6 +6,7 @@ type UserProfile = {
mastodon_attn_list?: string;
mastodon_post_public: boolean;
has_doms: boolean;
verify_mastodon_alt_text?: boolean;
verify_mastodon_favorite?: boolean;
verify_delay?: number;
}