summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
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
commitaa3850870c5671178c4648f91c62cdd3fc8affa4 (patch)
tree2a399c7bbb37e7792f9ab75e46a0cb821426c646
parentde16fbff8bb115a4e03e739673b7d70e7f164237 (diff)
downloadIshtar-aa3850870c5671178c4648f91c62cdd3fc8affa4.tar.bz2
Ishtar-aa3850870c5671178c4648f91c62cdd3fc8affa4.zip
Manage tiny urls for QR codes
-rw-r--r--archaeological_operations/tests/labels-8.odtbin13361 -> 12838 bytes
-rw-r--r--example_project/settings.py2
-rw-r--r--ishtar_common/migrations/0095_tinyurl.py22
-rw-r--r--ishtar_common/models.py33
-rw-r--r--ishtar_common/tests.py17
-rw-r--r--ishtar_common/urls.py2
-rw-r--r--ishtar_common/views.py8
7 files changed, 81 insertions, 3 deletions
diff --git a/archaeological_operations/tests/labels-8.odt b/archaeological_operations/tests/labels-8.odt
index 80c2cf449..13229c526 100644
--- a/archaeological_operations/tests/labels-8.odt
+++ b/archaeological_operations/tests/labels-8.odt
Binary files differ
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