Comment cleanup with proper RFC numbers.
This commit is contained in:
parent
4c7c2e0dc3
commit
c48f848bba
1 changed files with 63 additions and 14 deletions
|
@ -1,25 +1,42 @@
|
||||||
|
'''
|
||||||
|
Various utlity functions that are independant of any Django app or
|
||||||
|
model.
|
||||||
|
'''
|
||||||
|
|
||||||
|
from nturl2path import pathname2url as ntpathname2url
|
||||||
|
from nturl2path import url2pathname as url2ntpathname
|
||||||
import random
|
import random
|
||||||
import re
|
import re
|
||||||
import string
|
import string
|
||||||
from unicodedata import normalize
|
from unicodedata import normalize
|
||||||
|
from urllib.parse import urljoin, urlparse
|
||||||
|
from urllib.request import pathname2url, url2pathname
|
||||||
|
|
||||||
from django.core.exceptions import ObjectDoesNotExist
|
from django.core.exceptions import ObjectDoesNotExist
|
||||||
from django.db import connection
|
from django.db import connection
|
||||||
|
from django.utils.encoding import iri_to_uri, uri_to_iri
|
||||||
|
|
||||||
from .models import Setting
|
from .models import Setting
|
||||||
|
|
||||||
|
|
||||||
def generate_password(length=32):
|
def generate_password(length=32):
|
||||||
|
'''
|
||||||
|
Quick and dirty random password generator.
|
||||||
|
|
||||||
|
***WARNING*** - Although this is likely "good enough" to create a secure
|
||||||
|
password, there are no validations (suitible entropy, dictionary words,
|
||||||
|
etc.) and should not be completely trusted. YOU HAVE BEEN WARNED.
|
||||||
|
'''
|
||||||
chars = string.ascii_letters + string.digits + string.punctuation
|
chars = string.ascii_letters + string.digits + string.punctuation
|
||||||
rng = random.SystemRandom()
|
rng = random.SystemRandom()
|
||||||
return ''.join([rng.choice(chars) for i in range(length)])
|
return ''.join([rng.choice(chars) for i in range(length)])
|
||||||
|
|
||||||
|
|
||||||
def get_len(rawqueryset):
|
def get_len(rawqueryset):
|
||||||
"""
|
'''
|
||||||
Adds/Overrides a dynamic implementation of the length protocol to the
|
Adds/Overrides a dynamic implementation of the length protocol to the
|
||||||
definition of RawQuerySet.
|
definition of RawQuerySet.
|
||||||
"""
|
'''
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
params = ['{}'.format(p) for p in self.params]
|
params = ['{}'.format(p) for p in self.params]
|
||||||
sql = ''.join(('SELECT COUNT(*) FROM (',
|
sql = ''.join(('SELECT COUNT(*) FROM (',
|
||||||
|
@ -33,11 +50,13 @@ def get_len(rawqueryset):
|
||||||
|
|
||||||
|
|
||||||
def get_setting(name):
|
def get_setting(name):
|
||||||
|
'''Helper function to get dynamic settings from the database.'''
|
||||||
setting = Setting.objects.get(name=name)
|
setting = Setting.objects.get(name=name)
|
||||||
return setting.get()
|
return setting.get()
|
||||||
|
|
||||||
|
|
||||||
def set_setting(name, value, setting_type=None):
|
def set_setting(name, value, setting_type=None):
|
||||||
|
'''Helper function to set dynamic settings from the database.'''
|
||||||
setting_types = {'Integer': 0, 'Float': 1, 'String': 2, 'Bool': 3}
|
setting_types = {'Integer': 0, 'Float': 1, 'String': 2, 'Bool': 3}
|
||||||
try:
|
try:
|
||||||
setting = Setting.objects.get(name=name)
|
setting = Setting.objects.get(name=name)
|
||||||
|
@ -57,13 +76,13 @@ def set_setting(name, value, setting_type=None):
|
||||||
|
|
||||||
|
|
||||||
def naturalize(text):
|
def naturalize(text):
|
||||||
"""
|
'''
|
||||||
Return a normalized unicode string, with removed starting articles, for use
|
Return a normalized unicode string, with removed starting articles, for use
|
||||||
in natural sorting.
|
in natural sorting.
|
||||||
|
|
||||||
Code was inspired by 'django-naturalsortfield' from Nathan Reynolds:
|
Code was inspired by 'django-naturalsortfield' from Nathan Reynolds:
|
||||||
https://github.com/nathforge/django-naturalsortfield
|
https://github.com/nathforge/django-naturalsortfield
|
||||||
"""
|
'''
|
||||||
def naturalize_int_match(match):
|
def naturalize_int_match(match):
|
||||||
return '{:08d}'.format(int(match.group(0)))
|
return '{:08d}'.format(int(match.group(0)))
|
||||||
|
|
||||||
|
@ -79,9 +98,9 @@ def naturalize(text):
|
||||||
|
|
||||||
|
|
||||||
def quantify(quantity, model):
|
def quantify(quantity, model):
|
||||||
"""
|
'''
|
||||||
A message based on the quantity and singular/plural name of the model.
|
A message based on the quantity and singular/plural name of the model.
|
||||||
"""
|
'''
|
||||||
if quantity == 1:
|
if quantity == 1:
|
||||||
message = '1 {}'.format(model._meta.verbose_name)
|
message = '1 {}'.format(model._meta.verbose_name)
|
||||||
else:
|
else:
|
||||||
|
@ -92,21 +111,20 @@ def quantify(quantity, model):
|
||||||
|
|
||||||
def create_success_message(parent_model, parent_quantity, child_model,
|
def create_success_message(parent_model, parent_quantity, child_model,
|
||||||
child_quantity, remove=False):
|
child_quantity, remove=False):
|
||||||
"""
|
'''
|
||||||
Creates a message for displaying the success of model modification.
|
Creates a message for displaying the success of model modification.
|
||||||
"""
|
'''
|
||||||
p_message = quantify(parent_quantity, parent_model)
|
p_message = quantify(parent_quantity, parent_model)
|
||||||
c_message = quantify(child_quantity, child_model)
|
c_message = quantify(child_quantity, child_model)
|
||||||
if remove:
|
if remove:
|
||||||
return '{} successfully removed from {}'.format(c_message, p_message)
|
return '{} successfully removed from {}'.format(c_message, p_message)
|
||||||
else:
|
return '{} successfully added to {}.'.format(c_message, p_message)
|
||||||
return '{} successfully added to {}.'.format(c_message, p_message)
|
|
||||||
|
|
||||||
|
|
||||||
def get_pretty_time(seconds):
|
def get_pretty_time(seconds):
|
||||||
"""
|
'''
|
||||||
Displays a human-readable representation of time.
|
Displays a human-readable representation of time.
|
||||||
"""
|
'''
|
||||||
if seconds > 0:
|
if seconds > 0:
|
||||||
periods = [
|
periods = [
|
||||||
('year', 60*60*24*365.25),
|
('year', 60*60*24*365.25),
|
||||||
|
@ -123,5 +141,36 @@ def get_pretty_time(seconds):
|
||||||
period_name,
|
period_name,
|
||||||
('s', '')[period_value == 1]))
|
('s', '')[period_value == 1]))
|
||||||
return ', '.join(strings)
|
return ', '.join(strings)
|
||||||
else:
|
return 'Now'
|
||||||
return 'Now'
|
|
||||||
|
|
||||||
|
def path_to_iri(path):
|
||||||
|
'''
|
||||||
|
OS-independant attempt at converting any OS absolute path to an
|
||||||
|
RFC3987-defined IRI along with the file scheme from RFC8089.
|
||||||
|
'''
|
||||||
|
# Looking to see if the path starts with a drive letter or UNC path
|
||||||
|
# (eg. 'D:\' or '\\')
|
||||||
|
windows = re.match(r'^(?:[A-Za-z]:|\\)\\', path)
|
||||||
|
if windows:
|
||||||
|
return uri_to_iri(urljoin('file:', ntpathname2url(path)))
|
||||||
|
return uri_to_iri(urljoin('file:', pathname2url(path)))
|
||||||
|
|
||||||
|
|
||||||
|
def iri_to_path(iri):
|
||||||
|
'''
|
||||||
|
OS-independant attempt at converting an RFC3987-defined IRI with a file
|
||||||
|
scheme from RFC8089 to an OS-specific absolute path.
|
||||||
|
'''
|
||||||
|
# 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!@#$%^&\'\)\(\.\-_{}~]+/)'
|
||||||
|
windows = re.match(patt, uri)
|
||||||
|
if windows:
|
||||||
|
parse = urlparse(uri)
|
||||||
|
# UNC path URIs put the server name in the 'netloc' parameter.
|
||||||
|
if parse.netloc:
|
||||||
|
return '\\' + url2ntpathname('/' + parse.netloc + parse.path)
|
||||||
|
return url2ntpathname(parse.path)
|
||||||
|
return url2pathname(urlparse(uri).path)
|
||||||
|
|
Loading…
Reference in a new issue