Projet

Général

Profil

0001-template-filter-for-Luhn-algorithm-35013.patch

Benjamin Dauvergne, 23 juillet 2019 17:42

Télécharger (3,9 ko)

Voir les différences:

Subject: [PATCH] template filter for Luhn algorithm (#35013)

 tests/test_templates.py           | 19 +++++++++++++++++++
 wcs/qommon/templatetags/qommon.py | 30 ++++++++++++++++++++++++++----
 2 files changed, 45 insertions(+), 4 deletions(-)
tests/test_templates.py
522 522
    lazy_formdata = LazyFormData(MockFormData())
523 523
    tmpl = Template('{% with form_geoloc_base|reproj:"EPSG:3946" as c %}{{c.0}}/{{c.1}}{% endwith %}')
524 524
    assert tmpl.render(CompatibilityNamesDict({'form': lazy_formdata})) == '1625337.15483/5422836.71627'
525

  
526
def test_luhn():
527
    # EO Siret
528
    tmpl = Template('{% if  "44317013900036"|luhn %}yes{% endif %}')
529
    assert tmpl.render() == 'yes'
530
    for i in range(10):
531
        if i == 6:
532
            continue
533
        tmpl = Template('{% if  "4431701390003' + str(i) + '"|luhn %}yes{% endif %}')
534
        assert tmpl.render() == ''
535

  
536
    # EO Siren
537
    tmpl = Template('{% if  "443170139"|luhn %}yes{% endif %}')
538
    assert tmpl.render() == 'yes'
539
    for i in range(10):
540
        if i == 9:
541
            continue
542
        tmpl = Template('{% if  "44317013' + str(i) + '"|luhn %}yes{% endif %}')
543
        assert tmpl.render() == ''
wcs/qommon/templatetags/qommon.py
20 20
from decimal import DivisionByZero as DecimalDivisionByZero
21 21
import hashlib
22 22
import math
23
import re
23 24
import string
24 25
import random
25 26

  
......
28 29

  
29 30
from django import template
30 31
from django.template import defaultfilters
31
from django.utils import dateparse
32
from django.utils import dateparse, six
32 33
from django.utils.safestring import mark_safe
33 34
from wcs.qommon import evalutils
34 35
from wcs.qommon import tokens
......
44 45

  
45 46
@register.filter
46 47
def startswith(string, substring):
47
    return string and unicode(string).startswith(unicode(substring))
48
    return string and six.text_type(string).startswith(six.text_type(substring))
48 49

  
49 50
@register.filter
50 51
def split(string, separator=' '):
51 52
    if not string:
52 53
        return []
53
    return unicode(string).split(unicode(separator))
54
    return six.text_type(string).split(six.text_type(separator))
54 55

  
55 56
@register.filter
56 57
def parse_date(date_string):
......
306 307

  
307 308
@register.filter
308 309
def token_check(token1, token2):
309
    return unicode(token1).strip().upper() == unicode(token2).strip().upper()
310
    return six.text_type(token1).strip().upper() == six.text_type(token2).strip().upper()
310 311

  
311 312

  
312 313
def get_latlon(obj):
......
348 349
    proj = pyproj.Proj(init='EPSG:4326')
349 350
    target_proj = pyproj.Proj(init=projection_name)
350 351
    return pyproj.transform(proj, target_proj, coords['lon'], coords['lat'])
352

  
353
@register.filter
354
def luhn(value):
355
    '''Verify Luhn checksum on a string representing a number'''
356
    if not value:
357
        return False
358
    string_value = six.text_type(value)
359
    string_value = string_value.strip()
360
    string_value = re.sub(r'\s', '', string_value)
361
    if not string_value.isdigit():
362
        return False
363

  
364
    # take all digits couting from the right, double value for digits pair
365
    # index (counting from 1), if double has 2 digits take their sum
366
    checksum = 0
367
    for i, x in enumerate(reversed(string_value)):
368
        if i % 2 == 0:
369
            checksum += int(x)
370
        else:
371
            checksum += sum(int(y) for y in str(2 * int(x)))
372
    return checksum % 10 == 0
351
-