# Path: weechat/common/decorators.py
# def disable_for_loaddata(signal_handler):
#     """
#     Decorator that turns off signal handlers when loading fixture data.
#     """
#     @wraps(signal_handler)
#     def wrapper(*args, **kwargs):
#         if kwargs.get('raw'):
#             return
#         signal_handler(*args, **kwargs)
#     return wrapper
# 
# Path: weechat/common/forms.py
# class CharField(forms.CharField):
#     """Char field in new script form."""
# 
#     def get_bound_field(self, form, field_name):
#         return BootstrapBoundField(form, self, field_name)
# 
# class ChoiceField(forms.ChoiceField):
#     """Choice field in new script form."""
# 
#     def get_bound_field(self, form, field_name):
#         return BootstrapBoundField(form, self, field_name)
# 
# class EmailField(forms.EmailField):
#     """E-mail field in new script form."""
# 
#     def get_bound_field(self, form, field_name):
#         return BootstrapBoundField(form, self, field_name)
# 
# class FileField(forms.FileField):
#     """File field in new script form."""
# 
#     def get_bound_field(self, form, field_name):
#         return BootstrapBoundField(form, self, field_name)
# 
# class TestField(forms.CharField):
#     """Anti-spam field in forms."""
# 
#     def clean(self, value):
#         if not value:
#             raise forms.ValidationError(gettext('This field is required.'))
#         if value.lower() != 'no':
#             raise forms.ValidationError(gettext('This field is required.'))
#         return value
# 
#     def get_bound_field(self, form, field_name):
#         return BootstrapBoundField(form, self, field_name)
# 
# class Html5EmailInput(forms.widgets.Input):
#     """E-mail field (with HTML5 validator)."""
#     input_type = 'email'
# 
# class Form(forms.Form):
#     """Form with "as_div" method."""
# 
#     def as_div(self):
#         "Return this form rendered as HTML <div>s."
#         return self._html_output(
#             normal_row=('<div%(html_class_attr)s class="form-group row">'
#                         '%(label)s'
#                         '<div class="col-12 col-md-9 col-lg-10">'
#                         '%(field)s%(help_text)s'
#                         '</div>'
#                         '</div>'),
#             error_row='%s',
#             row_ender='</p>',
#             help_text_html=' <span class="helptext">%s</span>',
#             errors_on_separate_row=True)
# 
# Path: weechat/common/path.py
# def files_path_join(*args):
#     """Join multiple paths after settings.FILES_ROOT."""
#     return __path_join(settings.FILES_ROOT, *args)
# 
# Path: weechat/download/models.py
# class Release(models.Model):
#     """A WeeChat release."""
#     version = models.CharField(max_length=64, primary_key=True)
#     description = models.CharField(max_length=64, blank=True)
#     date = models.DateField(blank=True, null=True)
#     security_issues_fixed = models.IntegerField(default=0)
#     securityfix = models.CharField(max_length=256, blank=True)
# 
#     def __str__(self):
#         security_fix = (f', {self.security_issues_fixed} SECURITY FIX'
#                         if self.security_issues_fixed > 0 else '')
#         fixed_in = (f', fix in: {", ".join(self.securityfix.split(","))}'
#                     if self.securityfix else '')
#         return f'{self.version} ({self.date}){security_fix}{fixed_in}'
# 
#     def date_l10n(self):
#         """Return the release date formatted with localized date format."""
#         return localdate(self.date)
# 
#     def security_fixed_versions(self):
#         """Return the list of versions fixing security issues."""
#         return self.securityfix.split(',')
# 
#     @property
#     def is_released(self):
#         """Return True if the version is released."""
#         stable_version = Release.objects.get(version='stable').description
#         stable_version_tuple = version_to_tuple(stable_version)
#         return version_to_tuple(self.version) <= stable_version_tuple
# 
#     class Meta:
#         ordering = ['-date']


import gzip
import hashlib
import json
import os
import re
import tarfile
from collections import OrderedDict
from io import open
from xml.sax.saxutils import escape
from django import forms
from django.conf import settings
from django.db import models
from django.db.models.signals import pre_save, post_save, post_delete
from django.utils.safestring import mark_safe
from django.utils.translation import gettext, gettext_lazy
from weechat.common.decorators import disable_for_loaddata
from weechat.common.forms import (
    CharField,
    ChoiceField,
    EmailField,
    FileField,
    TestField,
    Html5EmailInput,
    Form,
)
from weechat.common.path import files_path_join
from weechat.download.models import Release
        if props['weechat'] not in (release_stable.description,
                                    re.sub('-.*', '',
                                           release_devel.description)):
            raise forms.ValidationError(
                gettext('Invalid WeeChat version, too old!'))
        _file.seek(0)
        return _file


def get_theme_choices():
    """Get list of themes for update form."""
    try:
        theme_list = Theme.objects.filter(visible=1).order_by('name')
        theme_choices = []
        theme_choices.append(('', gettext('Choose…')))
        for theme in theme_list:
            theme_choices.append((theme.id, f'{theme.name} ({theme.version})'))
        return theme_choices
    except:  # noqa: E722  pylint: disable=bare-except
        return []


class ThemeFormUpdate(Form):
    """Form to update a theme."""
    required_css_class = 'required'
    theme = ChoiceField(
        choices=[],
        label=gettext_lazy('Theme'),
        widget=forms.Select(attrs={'autofocus': True}),
    )

# Path: weechat/common/decorators.py
# def disable_for_loaddata(signal_handler):
#     """
#     Decorator that turns off signal handlers when loading fixture data.
#     """
#     @wraps(signal_handler)
#     def wrapper(*args, **kwargs):
#         if kwargs.get('raw'):
#             return
#         signal_handler(*args, **kwargs)
#     return wrapper
# 
# Path: weechat/common/forms.py
# class CharField(forms.CharField):
#     """Char field in new script form."""
# 
#     def get_bound_field(self, form, field_name):
#         return BootstrapBoundField(form, self, field_name)
# 
# class ChoiceField(forms.ChoiceField):
#     """Choice field in new script form."""
# 
#     def get_bound_field(self, form, field_name):
#         return BootstrapBoundField(form, self, field_name)
# 
# class EmailField(forms.EmailField):
#     """E-mail field in new script form."""
# 
#     def get_bound_field(self, form, field_name):
#         return BootstrapBoundField(form, self, field_name)
# 
# class FileField(forms.FileField):
#     """File field in new script form."""
# 
#     def get_bound_field(self, form, field_name):
#         return BootstrapBoundField(form, self, field_name)
# 
# class TestField(forms.CharField):
#     """Anti-spam field in forms."""
# 
#     def clean(self, value):
#         if not value:
#             raise forms.ValidationError(gettext('This field is required.'))
#         if value.lower() != 'no':
#             raise forms.ValidationError(gettext('This field is required.'))
#         return value
# 
#     def get_bound_field(self, form, field_name):
#         return BootstrapBoundField(form, self, field_name)
# 
# class Html5EmailInput(forms.widgets.Input):
#     """E-mail field (with HTML5 validator)."""
#     input_type = 'email'
# 
# class Form(forms.Form):
#     """Form with "as_div" method."""
# 
#     def as_div(self):
#         "Return this form rendered as HTML <div>s."
#         return self._html_output(
#             normal_row=('<div%(html_class_attr)s class="form-group row">'
#                         '%(label)s'
#                         '<div class="col-12 col-md-9 col-lg-10">'
#                         '%(field)s%(help_text)s'
#                         '</div>'
#                         '</div>'),
#             error_row='%s',
#             row_ender='</p>',
#             help_text_html=' <span class="helptext">%s</span>',
#             errors_on_separate_row=True)
# 
# Path: weechat/common/path.py
# def files_path_join(*args):
#     """Join multiple paths after settings.FILES_ROOT."""
#     return __path_join(settings.FILES_ROOT, *args)
# 
# Path: weechat/download/models.py
# class Release(models.Model):
#     """A WeeChat release."""
#     version = models.CharField(max_length=64, primary_key=True)
#     description = models.CharField(max_length=64, blank=True)
#     date = models.DateField(blank=True, null=True)
#     security_issues_fixed = models.IntegerField(default=0)
#     securityfix = models.CharField(max_length=256, blank=True)
# 
#     def __str__(self):
#         security_fix = (f', {self.security_issues_fixed} SECURITY FIX'
#                         if self.security_issues_fixed > 0 else '')
#         fixed_in = (f', fix in: {", ".join(self.securityfix.split(","))}'
#                     if self.securityfix else '')
#         return f'{self.version} ({self.date}){security_fix}{fixed_in}'
# 
#     def date_l10n(self):
#         """Return the release date formatted with localized date format."""
#         return localdate(self.date)
# 
#     def security_fixed_versions(self):
#         """Return the list of versions fixing security issues."""
#         return self.securityfix.split(',')
# 
#     @property
#     def is_released(self):
#         """Return True if the version is released."""
#         stable_version = Release.objects.get(version='stable').description
#         stable_version_tuple = version_to_tuple(stable_version)
#         return version_to_tuple(self.version) <= stable_version_tuple
# 
#     class Meta:
#         ordering = ['-date']


# Path: weechat/themes/models.py
import gzip
import hashlib
import json
import os
import re
import tarfile
from collections import OrderedDict
from io import open
from xml.sax.saxutils import escape
from django import forms
from django.conf import settings
from django.db import models
from django.db.models.signals import pre_save, post_save, post_delete
from django.utils.safestring import mark_safe
from django.utils.translation import gettext, gettext_lazy
from weechat.common.decorators import disable_for_loaddata
from weechat.common.forms import (
    CharField,
    ChoiceField,
    EmailField,
    FileField,
    TestField,
    Html5EmailInput,
    Form,
)
from weechat.common.path import files_path_join
from weechat.download.models import Release

        if props['weechat'] not in (release_stable.description,
                                    re.sub('-.*', '',
                                           release_devel.description)):
            raise forms.ValidationError(
                gettext('Invalid WeeChat version, too old!'))
        _file.seek(0)
        return _file


def get_theme_choices():
    """Get list of themes for update form."""
    try:
        theme_list = Theme.objects.filter(visible=1).order_by('name')
        theme_choices = []
        theme_choices.append(('', gettext('Choose…')))
        for theme in theme_list:
            theme_choices.append((theme.id, f'{theme.name} ({theme.version})'))
        return theme_choices
    except:  # noqa: E722  pylint: disable=bare-except
        return []


class ThemeFormUpdate(Form):
    """Form to update a theme."""
    required_css_class = 'required'
    theme = ChoiceField(
        choices=[],
        label=gettext_lazy('Theme'),
        widget=forms.Select(attrs={'autofocus': True}),
    )

    themefile = FileField(