Source code for nkdsu.apps.vote.forms

import re
from random import choice
from typing import Any, Optional, Sequence
from uuid import uuid4

from django import forms
from django.utils.safestring import mark_safe

from .models import Note, Track, Vote
from ..vote import trivia

_disable_autocorrect = {
    "autocomplete": "off",
    "autocorrect": "off",
    "spellcheck": "false",
}

_proper_noun_textinput = forms.TextInput(
    attrs=dict(_disable_autocorrect, autocapitalize="words")
)


[docs] class ClearableFileInput(forms.widgets.ClearableFileInput): """ The stock clearable file widget generates HTML that cannot be easily laid out in a reasonable way with CSS. In particular, the way the 'clear' checkbox is not put in any kind of elements makes intentional layout basically impossible. Here, we aim to fix that. """ template_name = 'widgets/clearable_file_input.html'
[docs] class SearchForm(forms.Form): q = forms.CharField()
[docs] class PronounsInput(forms.TextInput): template_name = 'widgets/pronouns_input.html' def __init__(self, attrs: Optional[dict[str, Any]] = None) -> None: attrs = {} if attrs is None else attrs attrs.update( autocomplete="off", list=str(uuid4()), placeholder='we will use they/them for you if you leave this blank', ) super().__init__(attrs)
[docs] class TriviaForm(forms.Form): """ A form protected by a trivia question. """ trivia_question = forms.CharField(widget=forms.HiddenInput) trivia = forms.CharField(required=False) def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) self.order_fields([k for k in self.fields.keys() if k != 'trivia'] + ['trivia']) self.fields['trivia_question'].initial = self.new_question()
[docs] def new_question(self) -> str: question = choice(list(trivia.questions.keys())) self.fields['trivia'].label = 'Captcha: %s' % question return question
[docs] def clean_trivia(self): human = True if 'trivia' in self.cleaned_data: human = re.match( trivia.questions[self.cleaned_data['trivia_question']] + '$', self.cleaned_data['trivia'], re.I, ) if not human: hint = ( "That's not right, sorry. There are hints <a href='" "https://codeberg.org/very-scary-scenario/nkdsu/src/branch/main/nkdsu/apps/vote/trivia.py" "'>here</a>." ) mutable = self.data._mutable self.data._mutable = True self.data['trivia_question'] = self.new_question() self.data._mutable = mutable raise forms.ValidationError([mark_safe(hint)]) return self.cleaned_data['trivia']
[docs] class BadMetadataForm(forms.Form): details = forms.CharField( widget=forms.Textarea, label="What needs fixing?", required=False ) track: Track def __init__(self, *args, track: Track, **kwargs) -> None: self.track = track super().__init__(*args, **kwargs)
[docs] class RequestForm(forms.Form): """ A form for requesting that a track be added to the library. """ title = forms.CharField(widget=_proper_noun_textinput, required=False) artist = forms.CharField(widget=_proper_noun_textinput, required=False) show = forms.CharField( label="Source Anime", required=False, widget=_proper_noun_textinput ) role = forms.CharField(label="Role (OP/ED/Insert/Character/etc.)", required=False) details = forms.CharField( widget=forms.Textarea(attrs=_disable_autocorrect), label="Additional Details", required=False, )
[docs] def clean(self) -> Optional[dict[str, Any]]: cleaned_data = super().clean() if cleaned_data is None: return None filled = [cleaned_data[f] for f in cleaned_data if cleaned_data[f]] if len(filled) < 1: raise forms.ValidationError( 'please provide at least some information to work with' ) return cleaned_data
[docs] class VoteForm(forms.ModelForm): """ A form for creating a :class:`.models.Vote`. """ tracks: Sequence[Track]
[docs] class Meta: model = Vote fields = ['text'] widgets = { 'text': forms.TextInput(), }
def __init__(self, *args, tracks: Sequence[Track], **kwargs): self.tracks = tracks super().__init__(*args, **kwargs)
[docs] def clean(self) -> None: super().clean() if len(self.tracks) == 0: raise forms.ValidationError('No tracks were selected')
[docs] class CheckMetadataForm(forms.Form): id3_title = forms.CharField(required=False, widget=forms.Textarea()) id3_artist = forms.CharField(required=False, widget=forms.Textarea()) composer = forms.CharField(required=False, widget=forms.Textarea()) year = forms.IntegerField(required=False)
[docs] class LibraryUploadForm(forms.Form): library_xml = forms.FileField(label='Library XML') inudesu = forms.BooleanField(label='Inu Desu', required=False)
[docs] class MyriadExportUploadForm(forms.Form): myriad_csv = forms.FileField(label='Myriad library export CSV')
[docs] class NoteForm(forms.ModelForm): just_for_current_show = forms.BooleanField(required=False)
[docs] class Meta: model = Note fields = ['content', 'public']
[docs] class DarkModeForm(forms.Form): mode = forms.ChoiceField( choices=[ ('light', 'light'), ('dark', 'dark'), ('system', 'system'), ] )