That ought to do.

This commit is contained in:
Kumi 2020-10-10 21:32:57 +02:00
parent ff97a4845b
commit b2e760053f
9 changed files with 95 additions and 30 deletions

View file

@ -5,4 +5,6 @@
This application requires Python3 to be installed with all the packages listed in `requirements.txt`, as well as the following software:
* Perl and the erect2cubic package
* Hugin (incl. Nona)
* Hugin (incl. Nona)
* Java and zxing
* PythonMagick

View file

@ -1,15 +1,17 @@
import tempfile
import subprocess
import PIL.Image
import PythonMagick
def convert(infile):
def convert(infile, extension):
pto = tempfile.NamedTemporaryFile()
image = tempfile.NamedTemporaryFile(suffix="." + infile.split(".")[-1].split("/")[-1])
with open(infile, "rb") as inimage:
image.write(inimage.read())
image = tempfile.NamedTemporaryFile(suffix=extension)
image.write(infile.read())
erect = ["erect2cubic", f"--erect={image.name}", f"--ptofile={pto.name}", "--filespec=PNG_m"]
subprocess.run(erect)
tiles = tempfile.TemporaryDirectory()
nona = ["nona", pto.name, "-o", tiles.name + "/out"]
subprocess.run(nona)
return PIL.Image.open(tiles.name + "/out0005.png")
image = PythonMagick.Image(tiles.name + "/out0005.png")
geo = PythonMagick.Geometry(int(image.baseColumns() / 3), int(image.baseColumns() / 3), int(image.baseColumns() / 3), int(image.baseColumns() / 3))
image.crop(geo)
return image

View file

@ -78,7 +78,7 @@ class Content(Model):
class Media(Model):
uuid = UUIDField(primary_key=True)
code = ForeignKey(Content, CASCADE)
content = ForeignKey(Content, CASCADE)
@classmethod
def generate_uuid(cls):

View file

@ -15,7 +15,7 @@ Including another URLconf
"""
from django.urls import path
from core.views import APICreateSeries, APISeriesByIDDispatcher, APICodesBySeriesIDDispatcher, APICreateCodes, APICodeByID
from core.views import APICreateSeries, APISeriesByIDDispatcher, APICodesBySeriesIDDispatcher, APICreateCodes, APICodeByID, APIAnalyzeContent
urlpatterns = [
path('series/', APICreateSeries.as_view()),
@ -24,4 +24,5 @@ urlpatterns = [
path('codes/', APICreateCodes.as_view()),
path('codes/<uuid>/', APICodeByID.as_view()),
path('codes/<seriesid>/<codeid>/', APICodeByID.as_view()),
path('content/', APIAnalyzeContent.as_view()),
]

View file

@ -14,7 +14,12 @@ from io import BytesIO
import urllib.request
from core.models import Series, APIKey, Code
import boto3
from core.models import Series, APIKey, Code, Media, Content
from customsettings import AWS_ACCESS_KEY_ID, AWS_BUCKET, AWS_SECRET_ACCESS_KEY
from converter import convert
from reader import read_code
class APIView(View):
@method_decorator(csrf_exempt)
@ -224,13 +229,62 @@ class APICodeByID(CodeAPIView):
class APIAnalyzeContent(APIView):
def post(self, request, *args, **kwargs):
url = request.body.decode("utf-8")
data = json.loads(request.body.decode("utf-8"))
if data.get("url"):
try:
URLValidator()(data["url"])
content = BytesIO(urllib.request.urlopen(data["url"]).read())
extension = "." + data["url"].split(".")[-1]
except:
return JsonResponse({"error": "Failed to retrieve file %s" % data["url"]})
try:
val = URLValidator().val(url)
except ValidationError:
return JsonResponse({"error": "Failed to validate URL"})
else:
try:
session = boto3.Session(aws_access_key_id=AWS_ACCESS_KEY_ID, aws_secret_access_key=AWS_SECRET_ACCESS_KEY)
s3 = session.resource("s3")
bucket = s3.Bucket(AWS_BUCKET)
content = BytesIO()
bucket.download_fileobj(data["path"], content)
extension = "." + data["path"].split(".")[-1]
except:
return JsonResponse({"error": "Failed to retrieve file %s" % data["path"]})
content = BytesIO(urllib.request.urlopen('url').read())
content.seek(0)
down = convert(content, extension)
literal = read_code(down)
if literal:
code = None
if len(literal.split(":")) == 3:
seriesid = literal.split(":")[1]
codeid = literal.split(":")[2]
try:
code = Code.objects.get(id=codeid, series=Series.objects.get(id=seriesid))
parsed = code.title
except (Code.DoesNotExist, Series.DoesNotExist):
return JsonResponse({"error": "No code found for Series %s Code %s" % (seriesid, codeid)})
else:
parsed = ":".join(literal.split(":")[1:])
content = Content.objects.create(literal=literal)
media = Media.objects.create(content=content)
output = {
"uuid": media.uuid,
"literal": media.content.literal
}
if code:
output["parsed"] = parsed
output["code"] = model_to_dict(code)
output["code"]["series"] = model_to_dict(code.series)
else:
output = {"error": "No code found in provided image"}
return JsonResponse(output)

View file

@ -2,10 +2,13 @@
# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'me98p&0-ijj-*vov@vm_&z&x#gr9uvvc9*y$n!!%=+javz^-#7'
SECRET_KEY = 'somesecretstring'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
AWS_BUCKET = "bucket"
AWS_ACCESS_KEY_ID = "accesskey"
AWS_SECRET_ACCESS_KEY = "secretkey"

View file

@ -322,6 +322,8 @@ paths:
schema:
url:
type: string
path:
type: string
uuid:
type: string
format: uuid

View file

@ -11,14 +11,13 @@ class QRCode:
self.content = content
self.rect = rect
def read_code(imagepath):
image = PIL.Image.open(imagepath)
def read_code(image):
reader = zxing.BarCodeReader()
codes = []
for _ in range(10):
tempimage = tempfile.NamedTemporaryFile()
image.save(tempimage, format="png")
tempimage = tempfile.NamedTemporaryFile(suffix=".png")
image.write(tempimage.name)
zxcontent = reader.decode(tempimage.name)
zbcontent = pyzbar.pyzbar.decode(PIL.Image.open(tempimage.name))
content = []
@ -30,13 +29,11 @@ def read_code(imagepath):
content.append(single.data.decode())
for code in content:
if not code in codes:
codes.append(code)
if code.startswith("EXP360:"):
return code
if codes:
return codes
image = PIL.ImageEnhance.Contrast(image).enhance(2.5)
image.modulate(150, 100, 100)
image.contrast(150)
if __name__ == "__main__":
content = read_code(sys.argv[1])

View file

@ -1,4 +1,8 @@
django
pyqrcode
PIL
numpy
pillow
numpy
boto3
pyzbar
numpy
zxing