Skip to content

Commit

Permalink
Merge pull request #50 from chnm/refactor/feedback
Browse files Browse the repository at this point in the history
Line code handling and visual styling of poetic text
  • Loading branch information
hepplerj authored Sep 16, 2024
2 parents ad38234 + 362fd8f commit cd7b513
Show file tree
Hide file tree
Showing 7 changed files with 197 additions and 37 deletions.
7 changes: 7 additions & 0 deletions manuscript/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ class LocationAdmin(ImportExportModelAdmin):
list_display = (
"placename_id",
"get_placename_modern",
"get_mss_placename",
"toponym_type",
"place_type",
"get_related_folios",
Expand All @@ -221,6 +222,12 @@ def get_placename_modern(self, obj):

get_placename_modern.short_description = "Modern Placename"

def get_mss_placename(self, obj):
alias = LocationAlias.objects.filter(location=obj).first()
return alias.placename_from_mss if alias else None

get_mss_placename.short_description = "Manuscript Placename"

def save_related(self, request, form, formsets, change):
super().save_related(request, form, formsets, change)
instance = form.instance
Expand Down
4 changes: 4 additions & 0 deletions manuscript/management/commands/load_aliases.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ def create_location_alias(
placename_id,
mss_transcription,
modern_name,
placename,
ancient_name,
country,
place_type,
Expand All @@ -79,6 +80,7 @@ def create_location_alias(
location_alias, created = LocationAlias.objects.get_or_create(
location=location,
placename_from_mss=mss_transcription,
placename_standardized=placename,
placename_modern=modern_name,
placename_ancient=ancient_name,
)
Expand Down Expand Up @@ -153,6 +155,7 @@ def load_data(self, filepath: str, sheet_name: str):
for index, row in df.iterrows():
placename_id = self.process_field(row, "place_id", index)
mss_transcription = self.process_field(row, "ex_label", index)
standardized_name = self.process_field(row, "histeng_name", index)
modern_name = self.process_field(row, "mod_name", index)
ancient_name = self.process_field(row, "anc_name", index)
country = self.process_field(row, "country", index)
Expand All @@ -166,6 +169,7 @@ def load_data(self, filepath: str, sheet_name: str):
placename_id,
mss_transcription,
modern_name,
standardized_name,
ancient_name,
country,
place_type,
Expand Down
107 changes: 107 additions & 0 deletions manuscript/management/commands/load_line_codes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import logging
import re

import pandas as pd
from django.core.exceptions import ValidationError
from django.core.management.base import BaseCommand

from manuscript.models import LineCode, Location

logger = logging.getLogger(__name__)


def validate_line_number_code(value):
pattern = r"^\d{2}\.\d{2}\.\d{2}(-\d{2}\.\d{2}\.\d{2})?$"
if not re.match(pattern, value):
raise ValidationError(
'Invalid number format. Expected format: "01.01.04" or "01.01.04-01.01.16"'
)


class Command(BaseCommand):
help_text = "Load data from an Excel file. This reads information about the toponym variants and imports them."

def add_arguments(self, parser):
parser.add_argument(
"--filepath",
type=str,
help="filepath of excel file to load",
default="tt_place_lasfera.xlsx",
)
parser.add_argument(
"--sheetname",
type=str,
help="name of sheet to load",
default="PID-Line Codes",
)

def handle_error(self, index, e, row, column_name, column_value):
logger.error(
"Error loading data at row %s, column '%s' with value '%s': %s - %s",
index + 1,
column_name,
column_value,
type(e),
e,
)
logger.debug("Row data: \n%s", row)

def process_field(self, row, field_name, index, is_bool=False):
try:
field_value = row.get(field_name)
if field_value is not None and isinstance(field_value, str):
field_value = field_value.strip()
return field_value
except Exception as e:
self.handle_error(index, e, row, field_name, row.get(field_name))
raise e

def handle(self, *args, **options):
filepath = options["filepath"]
sheetname = options.get("sheetname")

try:
df = pd.read_excel(filepath, sheet_name=sheetname)
logger.debug("DataFrame columns: %s", df.columns)
except Exception as e:
logger.error("Error reading Excel file: %s", e)
return

# Print the DataFrame columns to verify the actual column names
print("DataFrame columns:", df.columns)

for index, row in df.iterrows():
try:
logger.debug("Processing row %s: %s", index + 1, row)
line_code = self.process_field(row, "line_code", index)
toponym_id = self.process_field(row, "id", index)

logger.debug("line_code: %s, toponym_id: %s", line_code, toponym_id)

if not line_code or not toponym_id:
logger.warning("Missing line_code or id at row %s", index + 1)
continue

# Validate line_code
validate_line_number_code(line_code)

# Get the associated toponym
try:
toponym = Location.objects.get(placename_id=toponym_id)
except Location.DoesNotExist:
logger.warning(
"Toponym with id %s does not exist at row %s",
toponym_id,
index + 1,
)
continue

# Create or update the LineCode instance
LineCode.objects.update_or_create(
code=line_code, defaults={"associated_toponym": toponym}
)

logger.info("Successfully processed row %s", index + 1)

except Exception as e:
self.handle_error(index, e, row, "line_code", row.get("Line Code"))
44 changes: 37 additions & 7 deletions manuscript/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,9 @@ def manuscript(request: HttpRequest, siglum: str):
def toponyms(request: HttpRequest):
# Get unique and sorted LocationAlias objects based on placename_modern
toponym_alias_objs = (
LocationAlias.objects.values("placename_modern", "location_id")
LocationAlias.objects.values("placename_standardized", "location_id")
.distinct()
.order_by("placename_modern")
.order_by("placename_standardized")
)
return render(
request, "gazetteer/gazetteer_index.html", {"aliases": toponym_alias_objs}
Expand Down Expand Up @@ -290,25 +290,55 @@ def toponym(request: HttpRequest, toponym_param: int):
}
)

# Check if filtered_linecodes is not empty
print(f"Filtered linecodes: {filtered_linecodes}") # confirmed

# The line codes should indicate which folio and manuscript they belong to.
line_codes = []
for line_code in filtered_linecodes:
print(f"Processing line_code: {line_code.code}")
# Retrieve the Folio object through the associated_folio field
folio = line_code.associated_folio
# we create a variable that strips out the characters from the folio number so we're left
# with just the number
folio_number = re.sub(r"\D", "", folio.folio_number) if folio else None
print(f"Associated folio: {folio}")
if folio:
# We create a variable that strips out the characters from the folio number so we're left
# with just the number
folio_number = re.sub(r"\D", "", folio.folio_number)
# Retrieve the Manuscript object through the Folio model
manuscript = folio.manuscript
print(f"Associated manuscript: {manuscript}") # Debugging statement
line_codes.append(
{
"line_code": line_code.code,
"manuscript": manuscript.siglum,
"manuscript": manuscript.siglum if manuscript else "N/A",
"folio": folio.folio_number,
"folio_number": folio_number,
}
)
else:
# Handle case where folio is None
line_codes.append(
{
"line_code": line_code.code,
"manuscript": "No manuscript assigned.",
"folio": "No folio assigned.",
}
)
print(f"Final line_codes list: {line_codes}") # Debugging statement

return render(
request,
"gazetteer/gazetteer_single.html",
{
"toponym": filtered_toponym,
"manuscripts": filtered_manuscripts,
"aliases": processed_aliases,
"aggregated_aliases": aggregated_aliases,
"folios": filtered_folios,
"iiif_manifest": filtered_manuscripts[0].iiif_url,
"iiif_urls": iiif_urls,
"line_codes": line_codes, # Ensure line_codes is included in the context
},
)

return render(
request,
Expand Down
4 changes: 2 additions & 2 deletions templates/gazetteer/gazetteer_index.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ <h3 class="text-4xl pb-8 font-bold" id="top">
<ul>
{% for alias in aliases %}
<li class="p-2 hover:bg-gray-100">
<a class="underline hover:no-underline" href="{% url 'toponym_detail' alias.location_id %}">{{ alias.placename_modern }}</a>
<a class="underline hover:no-underline" href="{% url 'toponym_detail' alias.location_id %}">{{ alias.placename_standardized }}</a>
</li>
{% endfor %}
</ul>
Expand Down Expand Up @@ -59,7 +59,7 @@ <h3 class="text-4xl pb-8 font-bold" id="top">
if (toponym.latitude === null || toponym.longitude === null) {
return;
}
const aliases = toponym.aliases.placename_modern;
const aliases = toponym.aliases.placename_standardized;
const circleMarker = L.circleMarker([toponym.latitude, toponym.longitude], {
radius: 6,
color: 'none',
Expand Down
61 changes: 34 additions & 27 deletions templates/gazetteer/gazetteer_single.html
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{% extends "base.html" %}
{% load static %}

{% block title %}Data on toponym {{ aggregated_aliases.placename_moderns.0 }} - La Sfera{% endblock title %}
{% block title %}Data on toponym {{ aggregated_aliases.placename_standardizeds.0 }} - La Sfera{% endblock title %}

{% block content %}
<div class="mx-auto container pt-3">
<h3 class="text-4xl pb-8 font-bold" id="text">
<span class="border-b border-red-700 font-normal">{{ aggregated_aliases.placename_moderns.0 }}</span>
<span class="border-b border-red-700 font-normal">{{ aggregated_aliases.placename_standardizeds.0 }}</span>
</h3>
<p>&larr; <a class="underline hover:no-underline" href="{% url 'toponyms' %}">Return to gazetteer</a>.</p>

Expand All @@ -18,7 +18,7 @@ <h3 class="text-4xl pb-8 font-bold" id="text">
{# display the location aliases if any #}
{% if aliases %}
<div class="aliases mb-4">
<h4>Some of the variant spellings for <strong><span class="border-b border-red-700">{{ aggregated_aliases.placename_moderns.0 }}</span></strong> that appear in <em>Sfera</em> manuscripts are:</h4>
<h4>Some of the variant spellings for <strong><span class="border-b border-red-700">{{ aggregated_aliases.placename_standardizeds.0 }}</span></strong> that appear in <em>Sfera</em> manuscripts are:</h4>
{% if aggregated_aliases.placename_aliases %}
<ul class="flex flex-wrap gap-2">
{% for place_alias in aggregated_aliases.placename_aliases %}
Expand All @@ -42,9 +42,9 @@ <h4>Some of the variant spellings for <strong><span class="border-b border-red-7
{% endfor %}
</li>
{% endif %}
{% if aggregated_aliases.placename_moderns %}
{% if aggregated_aliases.placename_standardizeds %}
<li><strong>Modern name</strong>:
{% for modern in aggregated_aliases.placename_moderns %}
{% for modern in aggregated_aliases.placename_standardizeds %}
<span class="inline-flex items-center font-medium text-black border-b border-red-700">
{{ modern }}
</span>
Expand Down Expand Up @@ -80,41 +80,48 @@ <h4>Some of the variant spellings for <strong><span class="border-b border-red-7

{# Line codes for the toponym #}
{# we list all of the line_code values #}
{# Line codes for the toponym #}
<div class="flex-auto mb-2 bg-gray-50 p-2 m-2">
<h4 class="text-lg">The toponym <strong><span class="border-b border-red-700">{{ aggregated_aliases.placename_moderns.0 }}</span></strong> is mentioned in the text of <em>La Sfera</em> here:</h4>
<h4 class="text-lg">The toponym <strong><span class="border-b border-red-700">{{ aggregated_aliases.placename_standardizeds.0 }}</span></strong> is mentioned in the text of <em>La Sfera</em> here:</h4>

{% for line_code in line_codes %}
<table class="table-auto">
<thead>
<tr>
<th class="px-4 py-2">Line Code</th>
<th class="px-4 py-2">Manuscript</th>
<th class="px-4 py-2">Folio</th>
</tr>
</thead>
<tbody>
<table class="table-auto">
<thead>
<tr>
<th class="px-4 py-2">Line Code</th>
<th class="px-4 py-2">Manuscript</th>
<th class="px-4 py-2">Folio</th>
</tr>
</thead>
<tbody>
{% for line_code in line_codes %}
<tr>
<td class="border px-4 py-2">
<a class="underline hover:no-underline" href="{% url 'stanzas' %}#{{ line_code.line_code }}">{{ line_code.line_code }}</a>
</td>

<td class="border px-4 py-2"><a class="underline hover:no-underline" href="/manuscripts/{{ line_code.manuscript }}">{{ line_code.manuscript }}</a></td>

<td class="border px-4 py-2">
{% if line_code.manuscript != "No manuscript assigned." and line_code.manuscript %}
<a class="underline hover:no-underline" href="/manuscripts/{{ line_code.manuscript }}">{{ line_code.manuscript }}</a>
{% else %}
{{ line_code.manuscript }}
{% endif %}
</td>
<td class="border px-4 py-2">
{{ line_code.folio }}
</td>
</tr>
</tbody>
</table>
{% empty %}
<div>
<span class="prose">No line codes available for this toponym.</span>
</div>
{% endfor %}
{% empty %}
<tr>
<td colspan="3" class="border px-4 py-2">
<span class="prose">No line codes available for this toponym.</span>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>


<p class="pt-2 pb-2">The toponym <strong><span class="border-b border-red-700">{{ aggregated_aliases.placename_moderns.0 }}</span></strong> appears on at least one map in the following manuscripts:</p>
<p class="pt-2 pb-2">The toponym <strong><span class="border-b border-red-700">{{ aggregated_aliases.placename_standardizeds.0 }}</span></strong> appears on at least one map in the following manuscripts:</p>
<table class="table-auto">
<thead>
<tr>
Expand Down
7 changes: 6 additions & 1 deletion templates/stanzas.html
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ <h2 id="book-{{book_number}}" class="text-xl font-bold mb-4">Book {{ book_number
<div class="relative">
<div class="flex items-start">
<span class="line-code mr-2">
<a class="no-underline" href="#{{stanza.stanza_line_code_starts}}" id="{{stanza.stanza_line_code_starts}}">
<a class="no-underline" href="#{{stanza.stanza_line_code_starts}}" id="{{stanza.stanza_line_code_starts}}" title="Anchor link to line code {{ stanza.stanza_line_code_starts}}">
<span class="font-serif text-red-700 text-sm">
{{ stanza.stanza_line_code_starts }}
</span>
Expand Down Expand Up @@ -96,6 +96,11 @@ <h2 id="book-{{book_number}}" class="text-xl font-bold mb-4">Book {{ book_number
</div>
{% endfor %}
</div>
<div class="flex items-center my-16 py-4">
<div class="flex-grow border-t border-slate-300"></div>
<span class="mx-4 text-slate-300 text-4xl"></span>
<div class="flex-grow border-t border-slate-300"></div>
</div>
{% endfor %}
</div>
{% comment %} Return to top component {% endcomment %}
Expand Down

0 comments on commit cd7b513

Please sign in to comment.