Create a custom validator for the radio IRI.
This commit is contained in:
parent
6f76b7c611
commit
f3ec6a1ae3
2 changed files with 60 additions and 1 deletions
|
@ -17,6 +17,7 @@ from django.db import connection
|
|||
from django.utils.encoding import iri_to_uri, uri_to_iri
|
||||
|
||||
from .models import Setting
|
||||
from .validators import GROUP_NT_DRIVE_LETTER, GROUP_NT_UNC
|
||||
|
||||
|
||||
def generate_password(length=32):
|
||||
|
@ -165,7 +166,7 @@ def iri_to_path(iri):
|
|||
# Drive letter IRI will have three slashes followed by the drive letter
|
||||
# UNC path IRI will have two slashes followed by the UNC path
|
||||
uri = iri_to_uri(iri)
|
||||
patt = r'^(?:file:///[A-Za-z]:/|file://[A-Za-z0-9!@#$%^&\'\)\(\.\-_{}~]+/)'
|
||||
patt = r'^(?:' + GROUP_NT_DRIVE_LETTER + r'|' + GROUP_NT_UNC + r')'
|
||||
windows = re.match(patt, uri)
|
||||
if windows:
|
||||
parse = urlparse(uri)
|
||||
|
|
58
savepointradio/core/validators.py
Normal file
58
savepointradio/core/validators.py
Normal file
|
@ -0,0 +1,58 @@
|
|||
'''
|
||||
Custom Django model/form field validators for the Save Point Radio project.
|
||||
'''
|
||||
|
||||
import re
|
||||
|
||||
from django.core import validators
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
GROUP_NT_UNC = r'file://[A-Za-z0-9!@#$%^&\'\)\(\.\-_{}~]+/'
|
||||
|
||||
GROUP_NT_DRIVE_LETTER = r'file:///[A-Za-z](?:\:|\|)/'
|
||||
|
||||
GROUP_NON_AUTH = r'file:///[A-Za-z0-9!@#$%^&\'\)\(\.\-_{}~]+'
|
||||
|
||||
FILE_IRI_PATTERN = (
|
||||
r'^(?P<unc>' +
|
||||
GROUP_NT_UNC +
|
||||
r')|(?P<driveletter>' +
|
||||
GROUP_NT_DRIVE_LETTER +
|
||||
r')|(?P<nonauth>' +
|
||||
GROUP_NON_AUTH +
|
||||
r')'
|
||||
)
|
||||
|
||||
|
||||
class RadioIRIValidator(validators.URLValidator):
|
||||
'''
|
||||
Validates an RFC3987-defined IRI along with RFC8089 for file:// and other
|
||||
custom schemes.
|
||||
'''
|
||||
|
||||
message = _('Enter a valid IRI.')
|
||||
schemes = ['http', 'https', 'file', 'ftp', 'ftps', 's3']
|
||||
|
||||
def __init__(self, schemes=None, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
if schemes is not None:
|
||||
self.schemes = schemes
|
||||
|
||||
def __call__(self, value):
|
||||
# Check the schemes first
|
||||
scheme = value.split('://')[0].lower()
|
||||
if scheme not in self.schemes:
|
||||
raise ValidationError(self.message, code=self.code)
|
||||
|
||||
# Ignore the non-standard IRI
|
||||
if scheme == 'file':
|
||||
pattern = re.compile(FILE_IRI_PATTERN)
|
||||
if not pattern.match(value):
|
||||
raise ValidationError(self.message, code=self.code)
|
||||
elif scheme == 's3':
|
||||
# Nothing to validate, really. . .
|
||||
return
|
||||
else:
|
||||
super().__call__(value)
|
Loading…
Reference in a new issue