diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2019-05-01 17:37:18 +0200 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2019-06-17 13:21:28 +0200 |
commit | 4719aa7484b0602061c8662bc00f130aef9079dd (patch) | |
tree | 2a399c7bbb37e7792f9ab75e46a0cb821426c646 | |
parent | b69789fac685745ae7bcb144262eb9dfea44286d (diff) | |
download | Ishtar-4719aa7484b0602061c8662bc00f130aef9079dd.tar.bz2 Ishtar-4719aa7484b0602061c8662bc00f130aef9079dd.zip |
Manage tiny urls for QR codes
-rw-r--r-- | archaeological_operations/tests/labels-8.odt | bin | 13361 -> 12838 bytes | |||
-rw-r--r-- | example_project/settings.py | 2 | ||||
-rw-r--r-- | ishtar_common/migrations/0095_tinyurl.py | 22 | ||||
-rw-r--r-- | ishtar_common/models.py | 33 | ||||
-rw-r--r-- | ishtar_common/tests.py | 17 | ||||
-rw-r--r-- | ishtar_common/urls.py | 2 | ||||
-rw-r--r-- | ishtar_common/views.py | 8 |
7 files changed, 81 insertions, 3 deletions
diff --git a/archaeological_operations/tests/labels-8.odt b/archaeological_operations/tests/labels-8.odt Binary files differindex 80c2cf449..13229c526 100644 --- a/archaeological_operations/tests/labels-8.odt +++ b/archaeological_operations/tests/labels-8.odt diff --git a/example_project/settings.py b/example_project/settings.py index 168f17b06..8f59a58e3 100644 --- a/example_project/settings.py +++ b/example_project/settings.py @@ -234,7 +234,7 @@ USE_BACKGROUND_TASK = False # Ishtar custom ISHTAR_MAP_MAX_ITEMS = 50000 -ISHTAR_QRCODE_VERSION = 8 # density of the QR code +ISHTAR_QRCODE_VERSION = 5 # density of the QR code ISHTAR_QRCODE_SCALE = 2 # scale of the QR code SRID = 4326 # WGS84 - World diff --git a/ishtar_common/migrations/0095_tinyurl.py b/ishtar_common/migrations/0095_tinyurl.py new file mode 100644 index 000000000..dfe752c8c --- /dev/null +++ b/ishtar_common/migrations/0095_tinyurl.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.18 on 2019-05-01 16:04 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('ishtar_common', '0094_auto_20190429_1041'), + ] + + operations = [ + migrations.CreateModel( + name='TinyUrl', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('link', models.URLField()), + ], + ), + ] diff --git a/ishtar_common/models.py b/ishtar_common/models.py index 4165128f6..e5721d922 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -31,6 +31,7 @@ import os import pyqrcode import re import shutil +import string import tempfile import time from io import BytesIO @@ -1010,6 +1011,31 @@ class HierarchicalType(GeneralType): return " > ".join(reversed(lbls)) +class TinyUrl(models.Model): + CHAR_MAP = string.ascii_letters + string.digits + link = models.URLField() + + @classmethod + def index_to_char(cls, seq): + return "".join([cls.CHAR_MAP[x] for x in seq]) + + def get_short_id(self): + c_id = self.id + digits = [] + while c_id > 0: + digits.append(c_id % 62) + c_id //= 62 + digits.reverse() + return self.index_to_char(digits) + + @classmethod + def decode_id(cls, value): + i = 0 + for c in value: + i = i * 64 + cls.CHAR_MAP.index(c) + return i + + class ItemKey(models.Model): key = models.TextField(_("Key")) content_type = models.ForeignKey(ContentType) @@ -1653,7 +1679,12 @@ class QRCodeItem(models.Model, ImageContainerModel): else: scheme = "http" url = scheme + "://" + site.domain + url - qr = pyqrcode.create(url, version=settings.ISHTAR_QRCODE_VERSION) + tiny_url = TinyUrl() + tiny_url.link = url + tiny_url.save() + short_url = scheme + "://" + site.domain + reverse( + 'tiny-redirect', args=[tiny_url.get_short_id()]) + qr = pyqrcode.create(short_url, version=settings.ISHTAR_QRCODE_VERSION) tmpdir_created = False if not tmpdir: tmpdir = tempfile.mkdtemp("-qrcode") diff --git a/ishtar_common/tests.py b/ishtar_common/tests.py index 01aba1f5b..0f00322fe 100644 --- a/ishtar_common/tests.py +++ b/ishtar_common/tests.py @@ -155,6 +155,23 @@ class UtilsTest(TestCase): u'data__old__traitement__constat_etat') self.assertEqual(res, expected) + def test_tinyfy_url(self): + base_url = "https://example.com" + tiny_url = models.TinyUrl() + tiny_url.link = base_url + tiny_url.save() + + short_id = tiny_url.get_short_id() + db_id = models.TinyUrl.decode_id(short_id) + self.assertEqual(tiny_url.pk, db_id) + + ty = models.TinyUrl.objects.get(id=db_id) + self.assertEqual(base_url, ty.link) + c = Client() + response = c.get(reverse('tiny-redirect', args=[short_id])) + self.assertEqual(response['Location'], base_url) + self.assertEqual(response.status_code, 302) + class CommandsTestCase(TestCase): fixtures = [settings.ROOT_PATH + diff --git a/ishtar_common/urls.py b/ishtar_common/urls.py index 99d80e7ad..55df6cb40 100644 --- a/ishtar_common/urls.py +++ b/ishtar_common/urls.py @@ -32,6 +32,8 @@ from ishtar_common.utils import check_rights, get_urls_for_model # forms urlpatterns = [ url(r'^status/$', views.status, name='status'), + url(r'^ty/(?P<url_id>[a-zA-Z0-9]+)$', views.tiny_redirect, + name='tiny-redirect'), url(r'^robots\.txt$', TemplateView.as_view(template_name='robots.txt', content_type='text/plain')), # internationalization diff --git a/ishtar_common/views.py b/ishtar_common/views.py index 65ea70685..a10c44c77 100644 --- a/ishtar_common/views.py +++ b/ishtar_common/views.py @@ -37,7 +37,7 @@ from django.db.models import Q from django.forms.models import modelformset_factory from django.http import HttpResponse, Http404, HttpResponseRedirect, \ HttpResponseBadRequest, JsonResponse -from django.shortcuts import redirect, render +from django.shortcuts import redirect, render, get_object_or_404 from django.utils.decorators import method_decorator from django.utils.translation import ugettext, ugettext_lazy as _ from django.views.generic import ListView, TemplateView, View @@ -76,6 +76,12 @@ def status(request): return HttpResponse('OK') +def tiny_redirect(request, url_id): + db_id = models.TinyUrl.decode_id(url_id) + link_db = get_object_or_404(models.TinyUrl, id=db_id) + return redirect(link_db.link) + + def index(request): """ Main page |