Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion api
Submodule api updated 560 files
4 changes: 2 additions & 2 deletions front/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ app/mediafiles/img/*
!app/mediafiles/img/.gitkeep
app/mediafiles/annotation/*
!app/mediafiles/annotation/.gitkeep
app/mediafiles/regions/*
!app/mediafiles/regions/.gitkeep
app/mediafiles/region_extraction/*
!app/mediafiles/region_extraction/.gitkeep
app/mediafiles/similarity/*
!app/mediafiles/similarity/.gitkeep
app/mediafiles/pdf/*
Expand Down
4 changes: 2 additions & 2 deletions front/app/config/.env.template
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ PROD_API_URL=https://discover-api.enpc.com
# Port of the API (set only for localhost and HTTP connexions to the API)
API_PORT=5001

# Computer vision apps to install (available regions / similarity / vectorization)
INSTALLED_APPS=regions,similarity
# Computer vision apps to install (available region_extraction / similarity / vectorization)
INSTALLED_APPS=region_extraction,similarity

# Redis host (for Docker => redis / for other config => localhost)
REDIS_HOST=localhost
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from app.config.settings import WEBAPP_NAME
from app.webapp.utils.paths import BASE_DIR

MODULE_NAME = "regions"
MODULE_NAME = "region_extraction"
MODULE_DIR = BASE_DIR / WEBAPP_NAME / MODULE_NAME

EXTRACTOR_MODEL = "illustration_extraction.pt"
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
from django import forms

from app.config.settings import APP_LANG
from app.regions.const import MODULE_NAME
from app.region_extraction.const import MODULE_NAME
from app.webapp.forms import get_available_models

DEFAULT_MODEL = "illustration_extraction"


class RegionsForm(forms.Form):
class RegionExtractionForm(forms.Form):
class Meta:
fields = ("model",)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@


@celery_app.task
def process_regions_file(file_content, digit_id, model):
from app.webapp.models.regions import Digitization
from app.webapp.utils.iiif.annotation import process_regions
def process_region_extraction_file(file_content, digit_id, model):
from app.webapp.models.region_extraction import Digitization
from app.webapp.utils.iiif.annotation import process_region_extraction

digitization = Digitization.objects.filter(pk=digit_id).first()
return process_regions(file_content, digitization, model)
return process_region_extraction(file_content, digitization, model)


@celery_app.task
def delete_api_regions(digit_ref, model_name=None):
def delete_api_region_extraction(digit_ref, model_name=None):
model = f"?model_name={model_name}" if model_name else ""
response = requests.post(f"{API_URL}/regions/{digit_ref}/delete{model}")
response.raise_for_status()
Expand Down
25 changes: 25 additions & 0 deletions front/app/region_extraction/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from django.urls import path

from app.config.settings import APP_NAME

from app.region_extraction.views import *

app_name = "region_extraction"

urlpatterns = [
path(
f"{APP_NAME}/extract-regions/<str:digit_ref>",
send_region_extraction,
name="send-region-extraction",
),
path(
f"{APP_NAME}/region_extraction/notify",
receive_region_extraction_notification,
name="notify-regions",
),
path(
f"{APP_NAME}/witness/<int:wit_id>/regions/extract",
witness_region_extraction,
name="witness-region-extraction",
),
]
37 changes: 21 additions & 16 deletions front/app/regions/utils.py → front/app/region_extraction/utils.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import re
import requests

from app.regions.const import EXTRACTOR_MODEL
from app.regions.tasks import process_regions_file
from app.region_extraction.const import EXTRACTOR_MODEL
from app.region_extraction.tasks import process_region_extraction_file
from app.webapp.models.digitization import Digitization
from app.webapp.models.regions import Regions
from app.webapp.models.region_extraction import RegionExtraction
from app.webapp.models.witness import Witness
from app.webapp.utils import tasking
from app.webapp.utils.iiif import parse_ref
Expand All @@ -25,7 +25,7 @@ def prepare_request(witnesses, treatment_id, parameters=None):
witnesses,
treatment_id,
prepare_document,
"regions",
"region_extraction",
dict({"model": f"{EXTRACTOR_MODEL}"}, **(parameters or {})),
)

Expand Down Expand Up @@ -92,28 +92,33 @@ def process_results(data, completed=True):
log(f"Could not retrieve annotation from {result_url}", e)
continue

if not check_regions_json_file(json_content):
if not check_region_extraction_json_file(json_content):
continue

try:
model_name = result_url.split("/")[-1].split("+")[0] or EXTRACTOR_MODEL
process_regions_file.delay(json_content, digit_id, model_name)
process_region_extraction_file.delay(json_content, digit_id, model_name)
except Exception as e:
log(f"Could not process annotation from {result_url}", e)
raise e
return


def prepare_document(document: Witness | Digitization | Regions, **kwargs):
def prepare_document(document: Witness | Digitization | RegionExtraction, **kwargs):
if not type(document).__name__ == "Witness" and not document.has_images():
log(f"[prepare_document] Skipping {document}: no images to process")
return []

regions = document.get_regions() if hasattr(document, "get_regions") else [document]
region_extractions = (
document.get_region_extractions()
if hasattr(document, "get_region_extractions")
else [document]
)

if any(
region.model == kwargs["model"] and has_annotation(region.get_ref())
for region in regions
region_extraction.model == kwargs["model"]
and has_annotation(region_extraction.get_ref())
for region_extraction in region_extractions
):
log(f"[prepare_document] Skipping {document}: regions already extracted")
return []
Expand All @@ -126,18 +131,18 @@ def prepare_document(document: Witness | Digitization | Regions, **kwargs):
]


def regions_request(witnesses, treatment_id):
def region_extraction_request(witnesses, treatment_id):
"""
To relaunch extraction request in case the automatic process has failed
"""
tasking.task_request(
"regions",
"region_extraction",
witnesses,
treatment_id,
)


def check_regions_txt_file(file_content):
def check_region_extraction_txt_file(file_content):
"""
Check that the TXT of the file content really contains annotations
Should look something like this:
Expand All @@ -156,12 +161,12 @@ def check_regions_txt_file(file_content):
if line == "":
continue
if not pattern.match(line):
log(f"[check_regions_txt_file] incorrect line {line}")
log(f"[check_region_extraction_txt_file] incorrect line {line}")
return False
return True


def check_regions_json_file(file_content):
def check_region_extraction_json_file(file_content):
"""
Check that the JSON of the file content really contains annotations
Should contain something like this:
Expand Down Expand Up @@ -209,5 +214,5 @@ def check_regions_json_file(file_content):
# return False
return True
except Exception as e:
log(f"[check_regions_json_file] incorrect data", e)
log(f"[check_region_extraction_json_file] incorrect data", e)
return False
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@
)
from app.webapp.views import is_superuser, check_ref

from app.regions.utils import regions_request
from app.region_extraction.utils import region_extraction_request


@user_passes_test(is_superuser)
def send_regions_extraction(request, digit_ref):
def send_region_extraction(request, digit_ref):
"""
To relaunch regions extraction in case the automatic extraction failed
To relaunch region extraction in case the automatic extraction failed
"""
passed, digit = check_ref(digit_ref)
if not passed:
Expand All @@ -25,25 +25,25 @@ def send_regions_extraction(request, digit_ref):
# TODO delete regions files if existing

error = {
"response": f"Failed to send regions extraction request for digit #{digit.id}"
"response": f"Failed to send region extraction request for digit #{digit.id}"
}

try:
status = regions_request([digit.get_witness()], "manual")
status = region_extraction_request([digit.get_witness()], "manual")
except Exception as e:
error["cause"] = e
return JsonResponse(error, safe=False)

if status:
return JsonResponse(
{"response": f"Regions extraction was relaunched for digit #{digit.id}"},
{"response": f"Region extraction was relaunched for digit #{digit.id}"},
safe=False,
)
return JsonResponse(error, safe=False)


@require_POST
def witness_regions_extraction(request, wit_id):
def witness_region_extraction(request, wit_id):
"""
To launch regions extraction for a specific witness
"""
Expand Down Expand Up @@ -78,7 +78,7 @@ def witness_regions_extraction(request, wit_id):


@csrf_exempt
def receive_regions_notification(request):
def receive_region_extraction_notification(request):
"""
Receive results and notification from the API
"""
Expand Down
25 changes: 0 additions & 25 deletions front/app/regions/urls.py

This file was deleted.

40 changes: 27 additions & 13 deletions front/app/similarity/models/region_pair.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from app.webapp.utils.functions import cast, sort_key
from app.webapp.models.utils.functions import get_fieldname
from app.webapp.models.digitization import Digitization
from app.webapp.models.regions import Regions
from app.webapp.models.region_extraction import RegionExtraction
from app.similarity.models.similarity_parameters import SimilarityParameters


Expand All @@ -21,31 +21,45 @@ def extract_digit_id(img: str) -> int | None:
return int(matches[1]) if len(matches) > 1 else None


def get_region_digit_id(regions_id: int) -> int | None:
"""Get digitization ID associated with a regions_id"""
def get_region_digit_id(region_extraction_id: int) -> int | None:
"""Get digitization ID associated with a region_extraction_id"""
try:
region = Regions.objects.select_related("digitization").get(id=regions_id)
return region.digitization.id if region.digitization else None
except Regions.DoesNotExist:
region_extraction = RegionExtraction.objects.select_related("digitization").get(
id=region_extraction_id
)
return (
region_extraction.digitization.id
if region_extraction.digitization
else None
)
except RegionExtraction.DoesNotExist:
return None


def get_digit_regions_id(digit_id: int, create_if_missing: bool = False) -> int:
"""Get or create regions_id for a digitization ID"""
regions = Regions.objects.filter(digitization_id=digit_id).first()
def get_digit_region_extraction_id(
digit_id: int, create_if_missing: bool = False
) -> int:
"""Get or create region_extraction_id for a digitization ID"""
region_extraction = RegionExtraction.objects.filter(
digitization_id=digit_id
).first()

if not regions:
if not region_extraction:
if create_if_missing:
try:
digit = Digitization.objects.get(id=digit_id)
except Digitization.DoesNotExist:
raise ValidationError(f"Digitization {digit_id} does not exist")

regions = Regions.objects.create(digitization=digit, model="manual")
region_extraction = RegionExtraction.objects.create(
digitization=digit, model="manual"
)
else:
raise ValidationError(f"No regions found for digitization {digit_id}")
raise ValidationError(
f"No region extraction found for digitization {digit_id}"
)

return regions.id
return region_extraction.id


class RegionPairTuple(NamedTuple):
Expand Down
6 changes: 4 additions & 2 deletions front/app/similarity/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@ def process_similarity_file(file):


@celery_app.task
def delete_api_similarity(regions_ref, algorithm=None, feat_net=None):
def delete_api_similarity(region_extraction_ref, algorithm=None, feat_net=None):
args = {
"algorithm": algorithm,
"feat_net": feat_net,
}

response = requests.post(f"{API_URL}/similarity/{regions_ref}/delete", params=args)
response = requests.post(
f"{API_URL}/similarity/{region_extraction_ref}/delete", params=args
)
response.raise_for_status()
return response.json()
Loading