mirror of
https://expo.survex.com/repositories/troggle/.git
synced 2025-12-14 05:55:06 +00:00
encryption round-trip works
This commit is contained in:
@@ -52,6 +52,7 @@ from troggle.parsers.imports import (
|
||||
import_logbook,
|
||||
import_logbooks,
|
||||
import_people,
|
||||
import_users,
|
||||
import_QMs,
|
||||
import_survex,
|
||||
import_survex_checks,
|
||||
@@ -221,6 +222,7 @@ class JobQueue:
|
||||
"reinit",
|
||||
"caves",
|
||||
"people",
|
||||
"users",
|
||||
"logbooks",
|
||||
"QMs",
|
||||
"scans",
|
||||
@@ -247,6 +249,8 @@ class JobQueue:
|
||||
if module in ["runlabel", "date", "test", "TOTAL"]:
|
||||
continue
|
||||
# print(i, module, f"length={len(self.results[module])} ")
|
||||
if module == "users":
|
||||
continue
|
||||
if self.results[module][i]:
|
||||
total += float(self.results[module][i])
|
||||
return total
|
||||
@@ -425,6 +429,7 @@ def usage():
|
||||
init - initialisation. Automatic if you run reset.
|
||||
caves - read in the caves (must run first after initialisation)
|
||||
people - read in the people from folk.csv (must run after 'caves')
|
||||
users - read in registered troggle users from file (emails encrypted)
|
||||
logbooks - read in the logbooks
|
||||
QMs - read in the QM csv files (older caves only)
|
||||
scans - the survey scans in all the wallets (must run before survex)
|
||||
@@ -492,6 +497,8 @@ if __name__ == "__main__":
|
||||
jq.enq("logbooks", import_logbook) # default year set in imports.py
|
||||
elif "people" in sys.argv:
|
||||
jq.enq("people", import_people)
|
||||
elif "users" in sys.argv:
|
||||
jq.enq("users", import_users)
|
||||
elif "QMs" in sys.argv:
|
||||
jq.enq("QMs", import_QMs)
|
||||
elif "reset" in sys.argv:
|
||||
|
||||
3
dev.toml
3
dev.toml
@@ -10,7 +10,7 @@ lint.ignore = ["E402", "F541"]
|
||||
|
||||
[project]
|
||||
name = "troggle"
|
||||
version = "2024.12.1"
|
||||
version = "2025.01.18"
|
||||
description = "Troggle - cave data management"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.13"
|
||||
@@ -18,6 +18,7 @@ dependencies = [
|
||||
]
|
||||
[dependency-groups]
|
||||
dev = [
|
||||
"cryptography>=44.0.0",
|
||||
"django>=5",
|
||||
"beautifulsoup4>=4.12.3",
|
||||
"piexif>=1.1.3",
|
||||
|
||||
@@ -181,7 +181,8 @@ def do_ARGE_cave(slug, caveid, areacode, svxid):
|
||||
caveid may be kataster number or it may be e.g. LA34
|
||||
"""
|
||||
|
||||
default_note = "This is (probably) an ARGE or VfHO cave where we only have the survex file and no other information"
|
||||
default_note = "This is (probably) an ARGE or VfHO cave where we only have the survex file and no other information."
|
||||
default_note += "<br />If there is a 'Messteam' or 'Zeichner' listed, then it is probably ARGE."
|
||||
url = f"{areacode}/{caveid}/{caveid}.html"
|
||||
|
||||
urltest = Cave.objects.filter(url=url)
|
||||
@@ -210,11 +211,17 @@ def do_ARGE_cave(slug, caveid, areacode, svxid):
|
||||
|
||||
print(f"{caveid} {rest}")
|
||||
passages = "\n"
|
||||
# ; Messteam: Uwe Kirsamer, Uli Nohlen, Aiko Schütz, Torben Schulz,Thomas Holder,Robert Winkler
|
||||
# ; Zeichner: Aiko Schütz, Robert Winkler
|
||||
for line in rest:
|
||||
if line.strip().startswith("*begin"):
|
||||
passages = f"{passages}{line}"
|
||||
passages = f"{passages}{line}<br />\n"
|
||||
if line.strip().startswith("; Messteam:") or line.strip().startswith("; Zeichner:"):
|
||||
passages = f"{passages}{line}<br />\n"
|
||||
|
||||
commentary= "ARGE or VfHO cave.<br />3 lines of the survexfile,<br /> then all the *begin lines and any '; Messteam' and '; Zeichner' lines:<br><pre>"
|
||||
cave = Cave(
|
||||
underground_description="ARGE or VfHO cave.<br>3 lines of the survexfile, then all the *begin lines:<br><pre>" + line1 +line2 +line3 +passages +"</pre>",
|
||||
underground_description=commentary + line1 +line2 +line3 +passages +"</pre>",
|
||||
unofficial_number="ARGE-or-VfHO",
|
||||
survex_file= f"{svxid}.svx",
|
||||
url=url,
|
||||
|
||||
@@ -26,6 +26,12 @@ def import_people():
|
||||
with transaction.atomic():
|
||||
troggle.parsers.people.load_people_expos()
|
||||
|
||||
def import_users():
|
||||
print("-- Importing troggle Users (users.json) to ", end="")
|
||||
print(django.db.connections.databases["default"]["NAME"])
|
||||
with transaction.atomic():
|
||||
troggle.parsers.people.load_users()
|
||||
|
||||
def import_surveyscans():
|
||||
print("-- Importing Survey Scans and Wallets")
|
||||
with transaction.atomic():
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
import base64
|
||||
import csv
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
from cryptography.fernet import Fernet
|
||||
from html import unescape
|
||||
from pathlib import Path
|
||||
|
||||
from django.conf import settings
|
||||
from django.core import serializers
|
||||
from django.contrib.auth.models import User
|
||||
from django.db import models
|
||||
from unidecode import unidecode
|
||||
|
||||
from troggle.core.models.troggle import DataIssue, Expedition, Person, PersonExpedition
|
||||
@@ -15,7 +21,6 @@ The standalone script needs to be renedred defucnt, and all the parsing needs to
|
||||
or they should use the same code by importing a module.
|
||||
"""
|
||||
|
||||
|
||||
def parse_blurb(personline, header, person):
|
||||
"""create mugshot Photo instance
|
||||
Would be better if all this was done before the Person object was created in the db, then it would not
|
||||
@@ -86,6 +91,94 @@ def troggle_slugify(longname):
|
||||
|
||||
return slug
|
||||
|
||||
USERS_FILE = "users_e.json"
|
||||
ENCRYPTED_DIR = "encrypted"
|
||||
def load_users():
|
||||
"""These are the previously registered users of the troggle system.
|
||||
"""
|
||||
PARSER_USERS = "_users"
|
||||
DataIssue.objects.filter(parser=PARSER_USERS).delete()
|
||||
|
||||
key = settings.LONGTERM_SECRET_KEY # Django generated
|
||||
k = base64.urlsafe_b64encode(key.encode("utf8")[:32]) # make Fernet compatible
|
||||
f = Fernet(k)
|
||||
print(f)
|
||||
|
||||
|
||||
jsonfile = settings.EXPOWEB / ENCRYPTED_DIR / USERS_FILE
|
||||
jsonurl = "/" + str(Path(ENCRYPTED_DIR) / USERS_FILE)
|
||||
if not (jsonfile.is_file()):
|
||||
message = f" ! Users json file does not exist: '{jsonfile}'"
|
||||
DataIssue.objects.create(parser=PARSER_USERS, message=message)
|
||||
print(message)
|
||||
return None
|
||||
|
||||
with open(jsonfile, 'r', encoding='utf-8') as json_f:
|
||||
try:
|
||||
registered_users_dict = json.load(json_f)
|
||||
except FileNotFoundError:
|
||||
print("File not found!")
|
||||
except json.JSONDecodeError:
|
||||
print("Invalid JSON format! - JSONDecodeError")
|
||||
except Exception as e:
|
||||
print(f"An exception occurred: {str(e)}")
|
||||
message = f"! Troggle USERs. Failed to load {jsonfile} JSON file"
|
||||
print(message)
|
||||
DataIssue.objects.update_or_create(parser=PARSER_USERS, message=message, url=jsonurl)
|
||||
return None
|
||||
users_list = registered_users_dict["registered_users"]
|
||||
|
||||
print(f" - {len(users_list)} users read from JSON")
|
||||
for userdata in users_list:
|
||||
if userdata["username"]:
|
||||
if userdata["username"] == "expo":
|
||||
continue
|
||||
if userdata["username"] == "expoadmin":
|
||||
continue
|
||||
try:
|
||||
e_email = userdata["email"]
|
||||
email = f.decrypt(e_email).decode()
|
||||
print(f" - user: '{userdata["username"]} <{email}>' ")
|
||||
if existing_user := User.objects.filter(username=userdata["username"]): # WALRUS
|
||||
# print(f" - deleting existing user '{existing_user[0]}' before importing")
|
||||
existing_user[0].delete()
|
||||
user = User.objects.create_user(userdata["username"], email, "secret")
|
||||
user.set_password = "secret" # stores hash not password
|
||||
user.is_staff = False
|
||||
user.is_superuser = False
|
||||
user.save()
|
||||
except Exception as e:
|
||||
print(f"Exception <{e}>\nusers in db: {len(User.objects.all())}\n{User.objects.all()}")
|
||||
formatted_json = json.dumps(userdata, indent=4)
|
||||
print(formatted_json)
|
||||
return None
|
||||
else:
|
||||
print(f" - user: BAD username for {userdata} ")
|
||||
# if userdata["date"] != "" or userdata["date"] != "None":
|
||||
# message = f"! {str(self.walletname)} Date format not ISO {userdata['date']}. Failed to load from {jsonfile} JSON file"
|
||||
# from troggle.core.models.troggle import DataIssue
|
||||
# DataIssue.objects.update_or_create(parser="wallets", message=message, url=wurl)
|
||||
|
||||
|
||||
ru = []
|
||||
for u in User.objects.all():
|
||||
if u.username == "expo":
|
||||
continue
|
||||
if u.username == "expoadmin":
|
||||
continue
|
||||
e_email = f.encrypt(u.email.encode("utf8")).decode()
|
||||
ru.append({"username":u.username, "email": e_email, "password": u.password})
|
||||
print(u.username, e_email)
|
||||
original = f.decrypt(e_email).decode()
|
||||
print(u.username, original)
|
||||
|
||||
jsondict = { "registered_users": ru }
|
||||
encryptedfile = settings.EXPOWEB / ENCRYPTED_DIR / "encrypt.json"
|
||||
with open(encryptedfile, 'w', encoding='utf-8') as json_f:
|
||||
json.dump(jsondict, json_f, indent=1)
|
||||
return True
|
||||
|
||||
|
||||
def load_people_expos():
|
||||
"""This is where the folk.csv file is parsed to read people's names.
|
||||
Which it gets wrong for people like Lydia-Clare Leather and various 'von' and 'de' middle 'names'
|
||||
|
||||
@@ -18,6 +18,7 @@ dependencies = [
|
||||
]
|
||||
[dependency-groups]
|
||||
dev = [
|
||||
"cryptography>=44.0.0",
|
||||
"django>=5",
|
||||
"beautifulsoup4>=4.12.3",
|
||||
"piexif>=1.1.3",
|
||||
|
||||
@@ -18,6 +18,7 @@ dependencies = [
|
||||
]
|
||||
[dependency-groups]
|
||||
server = [
|
||||
"cryptography>=44.0.0",
|
||||
"django==3.2.19",
|
||||
"beautifulsoup4==4.11.2",
|
||||
"piexif==1.1.3",
|
||||
|
||||
@@ -16,7 +16,7 @@ if 'runserver' in sys.argv:
|
||||
print(">>>>running on dev local runserver<<<<")
|
||||
DEVSERVER = True
|
||||
else:
|
||||
print(">>>>running on expo.survex.com<<<<")
|
||||
# print(">>>>running on expo.survex.com<<<<")
|
||||
DEVSERVER = False
|
||||
|
||||
EPOCH = date.fromisoformat('1970-01-01')
|
||||
|
||||
64
uv.lock
generated
64
uv.lock
generated
@@ -22,6 +22,28 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/b1/fe/e8c672695b37eecc5cbf43e1d0638d88d66ba3a44c4d321c796f4e59167f/beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed", size = 147925 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cffi"
|
||||
version = "1.17.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "pycparser" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/8d/f8/dd6c246b148639254dad4d6803eb6a54e8c85c6e11ec9df2cffa87571dbe/cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e", size = 182989 },
|
||||
{ url = "https://files.pythonhosted.org/packages/8b/f1/672d303ddf17c24fc83afd712316fda78dc6fce1cd53011b839483e1ecc8/cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2", size = 178802 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0e/2d/eab2e858a91fdff70533cab61dcff4a1f55ec60425832ddfdc9cd36bc8af/cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3", size = 454792 },
|
||||
{ url = "https://files.pythonhosted.org/packages/75/b2/fbaec7c4455c604e29388d55599b99ebcc250a60050610fadde58932b7ee/cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683", size = 478893 },
|
||||
{ url = "https://files.pythonhosted.org/packages/4f/b7/6e4a2162178bf1935c336d4da8a9352cccab4d3a5d7914065490f08c0690/cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5", size = 485810 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c7/8a/1d0e4a9c26e54746dc08c2c6c037889124d4f59dffd853a659fa545f1b40/cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4", size = 471200 },
|
||||
{ url = "https://files.pythonhosted.org/packages/26/9f/1aab65a6c0db35f43c4d1b4f580e8df53914310afc10ae0397d29d697af4/cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd", size = 479447 },
|
||||
{ url = "https://files.pythonhosted.org/packages/5f/e4/fb8b3dd8dc0e98edf1135ff067ae070bb32ef9d509d6cb0f538cd6f7483f/cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed", size = 484358 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f1/47/d7145bf2dc04684935d57d67dff9d6d795b2ba2796806bb109864be3a151/cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9", size = 488469 },
|
||||
{ url = "https://files.pythonhosted.org/packages/bf/ee/f94057fa6426481d663b88637a9a10e859e492c73d0384514a17d78ee205/cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", size = 172475 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "coverage"
|
||||
version = "7.6.9"
|
||||
@@ -50,6 +72,37 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/26/74/b0729f196f328ac55e42b1e22ec2f16d8bcafe4b8158a26ec9f1cdd1d93e/coverage-7.6.9-cp313-cp313t-win_amd64.whl", hash = "sha256:97ddc94d46088304772d21b060041c97fc16bdda13c6c7f9d8fcd8d5ae0d8611", size = 211815 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cryptography"
|
||||
version = "44.0.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "cffi", marker = "platform_python_implementation != 'PyPy'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/91/4c/45dfa6829acffa344e3967d6006ee4ae8be57af746ae2eba1c431949b32c/cryptography-44.0.0.tar.gz", hash = "sha256:cd4e834f340b4293430701e772ec543b0fbe6c2dea510a5286fe0acabe153a02", size = 710657 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/55/09/8cc67f9b84730ad330b3b72cf867150744bf07ff113cda21a15a1c6d2c7c/cryptography-44.0.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:84111ad4ff3f6253820e6d3e58be2cc2a00adb29335d4cacb5ab4d4d34f2a123", size = 6541833 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7e/5b/3759e30a103144e29632e7cb72aec28cedc79e514b2ea8896bb17163c19b/cryptography-44.0.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b15492a11f9e1b62ba9d73c210e2416724633167de94607ec6069ef724fad092", size = 3922710 },
|
||||
{ url = "https://files.pythonhosted.org/packages/5f/58/3b14bf39f1a0cfd679e753e8647ada56cddbf5acebffe7db90e184c76168/cryptography-44.0.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:831c3c4d0774e488fdc83a1923b49b9957d33287de923d58ebd3cec47a0ae43f", size = 4137546 },
|
||||
{ url = "https://files.pythonhosted.org/packages/98/65/13d9e76ca19b0ba5603d71ac8424b5694415b348e719db277b5edc985ff5/cryptography-44.0.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:761817a3377ef15ac23cd7834715081791d4ec77f9297ee694ca1ee9c2c7e5eb", size = 3915420 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b1/07/40fe09ce96b91fc9276a9ad272832ead0fddedcba87f1190372af8e3039c/cryptography-44.0.0-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3c672a53c0fb4725a29c303be906d3c1fa99c32f58abe008a82705f9ee96f40b", size = 4154498 },
|
||||
{ url = "https://files.pythonhosted.org/packages/75/ea/af65619c800ec0a7e4034207aec543acdf248d9bffba0533342d1bd435e1/cryptography-44.0.0-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:4ac4c9f37eba52cb6fbeaf5b59c152ea976726b865bd4cf87883a7e7006cc543", size = 3932569 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c7/af/d1deb0c04d59612e3d5e54203159e284d3e7a6921e565bb0eeb6269bdd8a/cryptography-44.0.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ed3534eb1090483c96178fcb0f8893719d96d5274dfde98aa6add34614e97c8e", size = 4016721 },
|
||||
{ url = "https://files.pythonhosted.org/packages/bd/69/7ca326c55698d0688db867795134bdfac87136b80ef373aaa42b225d6dd5/cryptography-44.0.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f3f6fdfa89ee2d9d496e2c087cebef9d4fcbb0ad63c40e821b39f74bf48d9c5e", size = 4240915 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ef/d4/cae11bf68c0f981e0413906c6dd03ae7fa864347ed5fac40021df1ef467c/cryptography-44.0.0-cp37-abi3-win32.whl", hash = "sha256:eb33480f1bad5b78233b0ad3e1b0be21e8ef1da745d8d2aecbb20671658b9053", size = 2757925 },
|
||||
{ url = "https://files.pythonhosted.org/packages/64/b1/50d7739254d2002acae64eed4fc43b24ac0cc44bf0a0d388d1ca06ec5bb1/cryptography-44.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:abc998e0c0eee3c8a1904221d3f67dcfa76422b23620173e28c11d3e626c21bd", size = 3202055 },
|
||||
{ url = "https://files.pythonhosted.org/packages/11/18/61e52a3d28fc1514a43b0ac291177acd1b4de00e9301aaf7ef867076ff8a/cryptography-44.0.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:660cb7312a08bc38be15b696462fa7cc7cd85c3ed9c576e81f4dc4d8b2b31591", size = 6542801 },
|
||||
{ url = "https://files.pythonhosted.org/packages/1a/07/5f165b6c65696ef75601b781a280fc3b33f1e0cd6aa5a92d9fb96c410e97/cryptography-44.0.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1923cb251c04be85eec9fda837661c67c1049063305d6be5721643c22dd4e2b7", size = 3922613 },
|
||||
{ url = "https://files.pythonhosted.org/packages/28/34/6b3ac1d80fc174812486561cf25194338151780f27e438526f9c64e16869/cryptography-44.0.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:404fdc66ee5f83a1388be54300ae978b2efd538018de18556dde92575e05defc", size = 4137925 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d0/c7/c656eb08fd22255d21bc3129625ed9cd5ee305f33752ef2278711b3fa98b/cryptography-44.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:c5eb858beed7835e5ad1faba59e865109f3e52b3783b9ac21e7e47dc5554e289", size = 3915417 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ef/82/72403624f197af0db6bac4e58153bc9ac0e6020e57234115db9596eee85d/cryptography-44.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f53c2c87e0fb4b0c00fa9571082a057e37690a8f12233306161c8f4b819960b7", size = 4155160 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a2/cd/2f3c440913d4329ade49b146d74f2e9766422e1732613f57097fea61f344/cryptography-44.0.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:9e6fc8a08e116fb7c7dd1f040074c9d7b51d74a8ea40d4df2fc7aa08b76b9e6c", size = 3932331 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7f/df/8be88797f0a1cca6e255189a57bb49237402b1880d6e8721690c5603ac23/cryptography-44.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:d2436114e46b36d00f8b72ff57e598978b37399d2786fd39793c36c6d5cb1c64", size = 4017372 },
|
||||
{ url = "https://files.pythonhosted.org/packages/af/36/5ccc376f025a834e72b8e52e18746b927f34e4520487098e283a719c205e/cryptography-44.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a01956ddfa0a6790d594f5b34fc1bfa6098aca434696a03cfdbe469b8ed79285", size = 4239657 },
|
||||
{ url = "https://files.pythonhosted.org/packages/46/b0/f4f7d0d0bcfbc8dd6296c1449be326d04217c57afb8b2594f017eed95533/cryptography-44.0.0-cp39-abi3-win32.whl", hash = "sha256:eca27345e1214d1b9f9490d200f9db5a874479be914199194e746c893788d417", size = 2758672 },
|
||||
{ url = "https://files.pythonhosted.org/packages/97/9b/443270b9210f13f6ef240eff73fd32e02d381e7103969dc66ce8e89ee901/cryptography-44.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:708ee5f1bafe76d041b53a4f95eb28cdeb8d18da17e597d46d7833ee59b97ede", size = 3202071 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "django"
|
||||
version = "5.1.4"
|
||||
@@ -100,6 +153,15 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/51/85/9c33f2517add612e17f3381aee7c4072779130c634921a756c97bc29fb49/pillow-11.0.0-cp313-cp313t-win_arm64.whl", hash = "sha256:75acbbeb05b86bc53cbe7b7e6fe00fbcf82ad7c684b3ad82e3d711da9ba287d3", size = 2256828 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pycparser"
|
||||
version = "2.22"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", size = 172736 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", size = 117552 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "soupsieve"
|
||||
version = "2.6"
|
||||
@@ -127,6 +189,7 @@ source = { virtual = "." }
|
||||
dev = [
|
||||
{ name = "beautifulsoup4" },
|
||||
{ name = "coverage" },
|
||||
{ name = "cryptography" },
|
||||
{ name = "django" },
|
||||
{ name = "piexif" },
|
||||
{ name = "pillow" },
|
||||
@@ -139,6 +202,7 @@ dev = [
|
||||
dev = [
|
||||
{ name = "beautifulsoup4", specifier = ">=4.12.3" },
|
||||
{ name = "coverage", specifier = ">=7.6.9" },
|
||||
{ name = "cryptography" },
|
||||
{ name = "django", specifier = ">=5" },
|
||||
{ name = "piexif", specifier = ">=1.1.3" },
|
||||
{ name = "pillow", specifier = ">=11.0.0" },
|
||||
|
||||
Reference in New Issue
Block a user