diff --git a/cmp/models.py b/cmp/models.py index a20e42a..98d95a8 100644 --- a/cmp/models.py +++ b/cmp/models.py @@ -31,6 +31,16 @@ def __str__(self): def get_absolute_url(self): return reverse('countries', args=[str(self.id)]) +class Rank(models.Model): + # 6 + name = models.CharField(max_length=50, unique=True) + rank_types = (('OR','Other Rank'),('NC','Non Commisioned Officer'),('OF','Officer')) + abbreviation = models.CharField(max_length=50, blank=True) + rank_class = models.CharField(max_length=2, blank=True, choices=rank_types,default='Other Rank') + + def __str__(self): + return self.name + class Cemetery(models.Model): # 1 name = models.CharField(max_length=255, unique=True, default='') @@ -41,57 +51,46 @@ class Cemetery(models.Model): def __str__(self): return self.name - -class Decoration(models.Model): - # 4 - name = models.CharField(max_length=255, unique=True, default='') - notes = models.CharField(max_length=255, unique=False, default='') - country = models.ForeignKey('Country', on_delete=models.CASCADE) - details_link = models.CharField(max_length=255, unique=False, default='') - abbreviation = models.CharField(max_length=255, unique=False, default='') - - def __str__(self): - return self.Name - -class Company(models.Model): - # 2 +class PowCamp(models.Model): name = models.CharField(max_length=255, unique=True, default='') + nearest_city = models.CharField(max_length=255, unique=False, default='') notes = models.CharField(max_length=255, unique=False, default='') + country = models.ForeignKey('Country', to_field='country_number', on_delete=models.CASCADE, related_name='powcamps') + wartime_country = models.CharField(max_length=255, unique=False, default='') + latitude = models.CharField(max_length=255, unique=False, default='') + longitude = models.CharField(max_length=255, unique=False, default='') def __str__(self): return self.name -class Rank(models.Model): - name = models.CharField(max_length=50, unique=True) - rank_types = (('OR','Other Rank'),('NC','Non Commisioned Officer'),('OF','Officer')) - abbreviation = models.CharField(max_length=50, blank=True) - rank_class = models.CharField(max_length=2, blank=True, choices=rank_types,default='Other Rank') +class Theatre(models.Model): + # 11 + name = models.CharField(max_length=255, unique=True, default='') def __str__(self): return self.name - -class PowCamp(models.Model): +class Company(models.Model): + # 2 name = models.CharField(max_length=255, unique=True, default='') - nearest_city = models.CharField(max_length=255, unique=False, default='') notes = models.CharField(max_length=255, unique=False, default='') - country = models.ForeignKey('Country', to_field='country_number', on_delete=models.CASCADE, related_name='powcamps') - wartime_country = models.CharField(max_length=255, unique=False, default='') - latitude = models.CharField(max_length=255, unique=False, default='') - longitude = models.CharField(max_length=255, unique=False, default='') def __str__(self): return self.name - -class Theatre(models.Model): - # 11 +class Decoration(models.Model): + # 4 name = models.CharField(max_length=255, unique=True, default='') + notes = models.CharField(max_length=255, unique=False, default='') + country = models.ForeignKey('Country', on_delete=models.CASCADE) + details_link = models.CharField(max_length=255, unique=False, default='') + abbreviation = models.CharField(max_length=255, unique=False, default='') + def __str__(self): return self.name + class Soldier(models.Model): - # 10 surname = models.CharField(max_length=255, unique=False, default='') initials = models.CharField(max_length=255, unique=False, default='') army_number = models.CharField(max_length=255, unique=False, default='') @@ -103,18 +102,47 @@ def __str__(self): class SoldierDeath(models.Model): - soldier = models.OneToOneField(Soldier, on_delete=models.CASCADE, primary_key=True) - date = models.DateField(null=True, blank=True) - company = models.ForeignKey(Company, blank=True, null=True, default="UNKNOWN", on_delete=models.CASCADE) - cemetery = models.ForeignKey(Cemetery, blank=True, null=True, default=110, on_delete=models.CASCADE) + soldier = models.OneToOneField(Soldier, on_delete=models.CASCADE, related_name='soldierdeath') + date = models.DateField(null=True, blank=True) + company = models.ForeignKey(Company, blank=True, null=True, default="UNKNOWN", on_delete=models.CASCADE, related_name='companies') + cemetery = models.ForeignKey(Cemetery, blank=True, null=True, default=110, on_delete=models.CASCADE, related_name='cemeteries') cwgc_id = models.IntegerField(blank=True, null=True, unique=False, verbose_name="War Graves ID") - - def __str__(self): - return f"{self.soldier} {self.date} {self.cemetery}" + def __unicode__(self): + return '%s %s %s' % (self.Soldier, self.Date, self.cemetery) + + def cwgc_url(self): + """Build a URL for a link to CWGC site.""" + wg_site = 'http://www.cwgc.org' + if self.cwgc_id: + wg_string = 'find-war-dead/casualty/%s/' % (self.cwgc_id) + wg_url = '%s/%s' % (wg_site, wg_string ) + return wg_url + else: + dk = self.Date + wg_string = 'search/SearchResults.aspx?surname=%s&initials=%s&war=0&yearfrom=%s&yearto=%s&force=%s&nationality=&send.x=26&send.y=19"' % (self.Soldier.Surname, self.Soldier.first_initial(), dk.year, dk.year, 'Army') + wg_url = '%s/%s' % (wg_site, wg_string ) + return wg_url + def grave_photo(self): + photo_dir = '/sites/corpsofmilitarypolice.org/www/media/grave_images' + id_photo_dir = '/sites/corpsofmilitarypolice.org/www/media/grave_images/soldier_id' + """Determine whether or not a photograph exists + for a soldier with a particular army number""" + army_number = self.Soldier.Army_number + modded_an = re.sub('\/','_',army_number,1) + photo_name = modded_an + ".jpg" + id_photo_name = str(self.Soldier.id) + ".jpg" + photo_file = '%s/%s' % (photo_dir, photo_name) + id_photo_file = '%s/%s' % (id_photo_dir, id_photo_name) + if os.path.isfile(photo_file): + return photo_name + elif os.path.isfile(id_photo_file): + return 'soldier_id/%s' % id_photo_name + else: + return None + class SoldierImprisonment(models.Model): - # 9 soldier = models.ForeignKey('Soldier', on_delete=models.CASCADE) legacy_company = models.CharField(max_length=255, unique=False, default='') pow_number = models.CharField(max_length=255, unique=False, default='') @@ -127,9 +155,26 @@ class SoldierImprisonment(models.Model): class SoldierDecoration(models.Model): - # 8 - name = models.CharField(max_length=255, unique=True, default='') - notes = models.CharField(max_length=255, unique=False, default='') - country_id = models.ForeignKey('Country', on_delete=models.CASCADE) - details_link = models.CharField(max_length=255, unique=False, default='') - abbreviation = models.CharField(max_length=255, unique=False, default='') + soldier = models.ForeignKey(Soldier, null=False, blank=False, on_delete=models.CASCADE) + company = models.ForeignKey(Company, blank=True, null=True, on_delete=models.CASCADE ) + decoration = models.ForeignKey(Decoration, blank=True, null=True, on_delete=models.CASCADE) + gazette_issue = models.CharField(max_length=50, blank=True) + gazette_page = models.CharField(max_length=50, blank=True) + gazette_date = models.DateField(null=True, blank=True) + theatre = models.ForeignKey(Theatre, blank=True, null=True, help_text="Theatre of Operations e.g. Normandy, B.E.F. France & Flanders. NOT Country names", on_delete=models.CASCADE) + country = models.ForeignKey(Country, blank=True, null=True, on_delete=models.CASCADE) + citation = models.TextField(max_length=50000, blank=True) + notes = models.TextField(max_length=50000, blank=True) + def __str__(self): + return self.decoration.name + + def generate_gazette_url(self): + """Build a URL for the London Gazette website. This will not handle Edinburgh gazette""" + gz_site = 'http://www.thegazette.co.uk' + # "${gz_url}/SearchResults.aspx?GeoType=${gz_type}&st=${sc_type}&sb=issue&issue=${gz_issue}&gpn=${gz_page}&" + gz_type = 'london' + sc_type = 'adv' + #gz_string = "SearchResults.aspx?GeoType=${gz_type}&st=${sc_type}&sb=issue&issue=${gz_issue}&gpn=${gz_page}&" + gz_string = "%s/London/issue/%s/supplement/%s" % (gz_site, self.GztIssue, self.GztPage ) + gazette_url = gz_string + return gazette_url diff --git a/cmp/urls.py b/cmp/urls.py index 6f816e7..2853df3 100644 --- a/cmp/urls.py +++ b/cmp/urls.py @@ -30,5 +30,7 @@ path("mgmt/soldiers", views.edit_soldiers, name="soldiers"), path("mgmt/soldiers//", views.detail_soldiers, name="soldiers"), path("mgmt/soldiers/edit/", views.edit_soldiers, name="edit-soldiers"), + + path('soldier//', views.soldier, name='soldier'), ] diff --git a/cmp/views.py b/cmp/views.py index a0e23a1..5a7b7eb 100644 --- a/cmp/views.py +++ b/cmp/views.py @@ -310,3 +310,22 @@ def edit_ranks(request): form.save() return HttpResponse("Rank Added") return render(request, "cmp/edit-ranks.html", {"form": form}) + + +def soldier(request, soldier_id): + # get or return a 404 + soldier = get_object_or_404(Soldier, pk=soldier_id) + return render(request, "cmp/soldier.html", {"soldier": soldier}) + + +#def soldier_detail(request, soldier_id): +# """Gather together details about soldier""" +# s = Soldier.objects.get(id=soldier_id) +# soldier_record = { +# 's_surname': s.surname, +# #'s_initials': s.dot_initials(), +# 's_rank': s.rank, +# 's_armynumber': s.army_number, +# 's_notes': s.notes, +# } +# return soldier_record \ No newline at end of file diff --git a/insertall.sh b/insertall.sh index 2db133a..2b4601a 100755 --- a/insertall.sh +++ b/insertall.sh @@ -1,4 +1,6 @@ python manage.py runscript insert-all-countries +python manage.py runscript add-flags-to-countries.py +#python manage.py runscript insert-all-theatres python manage.py runscript insert-all-cemeteries python manage.py runscript insert-all-pow-camps python manage.py runscript insert-all-ranks @@ -7,3 +9,4 @@ python manage.py runscript insert-all-companies python manage.py runscript insert-all-soldiers python manage.py runscript insert-all-soldier-imprisonments python manage.py runscript insert-all-soldier-deaths +python manage.py runscript insert-all-soldier-decorations diff --git a/scripts/delete-all-soldier-deaths.py b/scripts/delete-all-soldier-deaths.py index 361ff41..eaf9d75 100644 --- a/scripts/delete-all-soldier-deaths.py +++ b/scripts/delete-all-soldier-deaths.py @@ -1,5 +1,5 @@ from cmp.models import SoldierDeath def run(): - soldierDeaths = SoldierDeath.objects.all() - soldierDeaths.delete() + SoldierDeaths = SoldierDeath.objects.all() + SoldierDeaths.delete() \ No newline at end of file diff --git a/scripts/delete-all-soldier-decorations.py b/scripts/delete-all-soldier-decorations.py new file mode 100644 index 0000000..24bf697 --- /dev/null +++ b/scripts/delete-all-soldier-decorations.py @@ -0,0 +1,5 @@ +from cmp.models import SoldierDecoration + +def run(): + SoldierDecorations = SoldierDecoration.objects.all() + SoldierDecorations.delete() diff --git a/scripts/insert-all-cemeteries.py b/scripts/insert-all-cemeteries.py index 97e896d..d08e415 100644 --- a/scripts/insert-all-cemeteries.py +++ b/scripts/insert-all-cemeteries.py @@ -14,36 +14,17 @@ def run(): ref_data_url = "https://raw.githubusercontent.com/gm3dmo/old-cmp/main/data/cemetery.csv" http = urllib3.PoolManager() r = http.request('GET', ref_data_url) - print(r.status) + print(f"""Fetch table response code: {r.status}""") # load the response into a csv dictionary reader reader = csv.DictReader(r.data.decode('utf-8').splitlines()) reader.fieldnames = [field.replace('.', '_') for field in reader.fieldnames] # add a country model for each row in the csv file for row in reader: - print(row['id']) if row['latitude'] == '': row['latitude'] = 0 if row['longitude'] == '': row['longitude'] = 0 - if int(row['id']) == 948: - print(row) - continue - if int(row['id']) == 991: - print(row) - continue - if int(row['id']) == 1007: - print(row) - continue - if int(row['id']) == 1043: - print(row) - continue - if int(row['id']) == 1051: - print(row) - continue - if int(row['id']) == 1068: - print(row) - continue try: Cemetery.objects.create( id=row['id'], @@ -53,5 +34,5 @@ def run(): longitude=row['longitude'] ) except Exception as e: - print("Error with: " + row['name']) + print(f"""💥row: ({row}) """) raise e diff --git a/scripts/insert-all-companies.py b/scripts/insert-all-companies.py index 1635b97..0efefa5 100644 --- a/scripts/insert-all-companies.py +++ b/scripts/insert-all-companies.py @@ -14,18 +14,18 @@ def run(): ref_data_url = "https://raw.githubusercontent.com/gm3dmo/old-cmp/main/data/company.csv" http = urllib3.PoolManager() r = http.request('GET', ref_data_url) - print(r.status) + print(f"""Fetch table response code: {r.status}""") # load the response into a csv dictionary reader reader = csv.DictReader(r.data.decode('utf-8').splitlines()) print(reader.fieldnames) for row in reader: - print(row['name']) + #print(row['name']) try: Company.objects.create( name = row['name'] ) except Exception as e: - print("Error with: " + row['name']) + print(f"""💥row: ({row}) """) raise e diff --git a/scripts/insert-all-countries.py b/scripts/insert-all-countries.py index 0ee100b..8e2bae8 100644 --- a/scripts/insert-all-countries.py +++ b/scripts/insert-all-countries.py @@ -15,7 +15,7 @@ def run(): ref_data_url = "https://raw.githubusercontent.com/gm3dmo/old-cmp/main/data/country.csv" http = urllib3.PoolManager() r = http.request('GET', ref_data_url) - print(r.status) + print(f"""Fetch table response code: {r.status}""") # load the response into a csv dictionary reader reader = csv.DictReader(r.data.decode('utf-8').splitlines()) #reader.fieldnames = [field.replace('.', '_') for field in reader.fieldnames] diff --git a/scripts/insert-all-decorations.py b/scripts/insert-all-decorations.py index b4af76b..ab23546 100644 --- a/scripts/insert-all-decorations.py +++ b/scripts/insert-all-decorations.py @@ -14,13 +14,13 @@ def run(): ref_data_url = "https://raw.githubusercontent.com/gm3dmo/old-cmp/main/data/decoration.csv" http = urllib3.PoolManager() r = http.request('GET', ref_data_url) - print(r.status) + print(f"""Fetch table response code: {r.status}""") # load the response into a csv dictionary reader reader = csv.DictReader(r.data.decode('utf-8').splitlines()) # add a country model for each row in the csv file for row in reader: - print(row['id']) + #print(row['id']) try: Decoration.objects.create( id=row['id'], diff --git a/scripts/insert-all-pow-camps.py b/scripts/insert-all-pow-camps.py index 2b2d398..e098afa 100644 --- a/scripts/insert-all-pow-camps.py +++ b/scripts/insert-all-pow-camps.py @@ -15,13 +15,14 @@ def run(): ref_data_url = "https://raw.githubusercontent.com/gm3dmo/old-cmp/main/data/pow-camp.csv" http = urllib3.PoolManager() r = http.request('GET', ref_data_url) - print(r.status) + print(f"""Fetch table response code: {r.status}""") + # load the response into a csv dictionary reader reader = csv.DictReader(r.data.decode('utf-8').splitlines()) # add a country model for each row in the csv file for row in reader: - print(f""" {row['id']} {row['Name']} ({row['PresentCountry_id']}) {row['WartimeCountry']} {row['Latitude']} {row['Longitude']}""") + #print(f""" {row['id']} {row['Name']} ({row['PresentCountry_id']}) {row['WartimeCountry']} {row['Latitude']} {row['Longitude']}""") try: PowCamp.objects.create( id=row['id'], @@ -32,6 +33,6 @@ def run(): longitude=row['Longitude'] ) except Exception as e: - print("Error with: " + row['Name']) + print(f"""💥row: ({row}) """) raise e diff --git a/scripts/insert-all-ranks.py b/scripts/insert-all-ranks.py index 0a5e20f..0057671 100644 --- a/scripts/insert-all-ranks.py +++ b/scripts/insert-all-ranks.py @@ -14,13 +14,13 @@ def run(): ref_data_url = "https://raw.githubusercontent.com/gm3dmo/old-cmp/main/data/rank.csv" http = urllib3.PoolManager() r = http.request('GET', ref_data_url) - print(r.status) + print(f"""Fetch table response code: {r.status}""") # load the response into a csv dictionary reader reader = csv.DictReader(r.data.decode('utf-8').splitlines()) # add a country model for each row in the csv file for row in reader: - print(row['name']) + #print(row['name']) try: Rank.objects.create( id=row['id'], @@ -29,9 +29,5 @@ def run(): rank_class=row['class'] ) except Exception as e: - print("Error with: " + row['name']) + print(f"""💥row: ({row}) """) raise e - - for rank in Rank.objects.all(): - print(f"""{rank.id} {rank.name}""") - diff --git a/scripts/insert-all-soldier-deaths.py b/scripts/insert-all-soldier-deaths.py index 74f00f5..f71fb46 100644 --- a/scripts/insert-all-soldier-deaths.py +++ b/scripts/insert-all-soldier-deaths.py @@ -12,10 +12,10 @@ def run(): print(f"""\033[4;33m{title}\033[0m""") print("-" * len(title)) - ref_data_url = "https://raw.githubusercontent.com/gm3dmo/old-cmp/main/data/soldier-death3.csv" + ref_data_url = "https://raw.githubusercontent.com/gm3dmo/old-cmp/main/data/soldier-death.csv" http = urllib3.PoolManager() r = http.request('GET', ref_data_url) - print(r.status) + print(f"""Fetch table response code: {r.status}""") # load the response into a csv dictionary reader reader = csv.DictReader(r.data.decode('utf-8').splitlines()) @@ -27,7 +27,7 @@ def run(): if company: company = company.first() else: - print(f"""row: ({row['id']}) cwgc:({row['cwgc_id']})""") + #print(f"""row: ({row['id']}) cwgc:({row['cwgc_id']})""") company = Company.objects.filter(name="UNKNOWN").first() cwgc_id = row.get('cwgc_id', 90909) if row.get('cwgc_id') != '' else 90909 SoldierDeath.objects.create( diff --git a/scripts/insert-all-soldier-decorations.py b/scripts/insert-all-soldier-decorations.py new file mode 100644 index 0000000..4b00c3d --- /dev/null +++ b/scripts/insert-all-soldier-decorations.py @@ -0,0 +1,63 @@ + +def run(): + + import sys + import urllib3 + import csv + from cmp.models import SoldierDecoration + from cmp.models import Company + from cmp.models import Country + from cmp.models import Soldier + + print() + title = sys.argv[2] + print(f"""\033[4;33m{title}\033[0m""") + print("-" * len(title)) + + ref_data_url = "https://raw.githubusercontent.com/gm3dmo/old-cmp/main/data/soldier-decoration.csv" + http = urllib3.PoolManager() + r = http.request('GET', ref_data_url) + print(f"""Fetch table response code: {r.status}""") + # load the response into a csv dictionary reader + reader = csv.DictReader(r.data.decode('ISO-8859-1').splitlines()) + + for row in reader: + #print(f"""row: ({row['id']}) cwgc:({row['cwgc_id']})""") + try: + company = Company.objects.filter(name=row['company_id']) + if company: + company = company.first() + else: + #print(f"""row: ({row['id']}) cwgc:({row['cwgc_id']})""") + company = Company.objects.filter(name="UNKNOWN").first() + country = Country.objects.filter(name=row['country_id']) + if country: + country = country.first() + else: + country = Country.objects.filter(name="UNKNOWN").first() + gazette_date = row.get('gazetteDate', None) + if gazette_date == "": + gazette_date = None + + if int(row.get("id")) == 384: + print(f"""row: {row}""") + breakpoint() + + SoldierDecoration.objects.create( + #id,soldier_id,company_id,decoration_id,gazetteIssue,gazettePage,gazetteDate,citation,notes,country_id + # create the model + id = int(row['id']), + #soldier = soldier + soldier_id = int(row['soldier_id']), + company_id = company.id, + decoration_id = int(row['decoration_id']), + gazette_issue = row['gazetteIssue'], + gazette_page = row['gazettePage'], + gazette_date = gazette_date, + citation = row['citation'], + notes = row['notes'], + country_id = country.id + ) + except Exception as e: + print(f"""💥row: {row}""") + raise e diff --git a/scripts/insert-all-soldier-imprisonments.py b/scripts/insert-all-soldier-imprisonments.py index fa3549a..69949d6 100644 --- a/scripts/insert-all-soldier-imprisonments.py +++ b/scripts/insert-all-soldier-imprisonments.py @@ -14,15 +14,13 @@ def run(): ref_data_url = "https://raw.githubusercontent.com/gm3dmo/old-cmp/main/data/soldier-imprisonment.csv" http = urllib3.PoolManager() r = http.request('GET', ref_data_url) - print(r.status) + print(f"""Fetch table response code: {r.status}""") # load the response into a csv dictionary reader reader = csv.DictReader(r.data.decode('utf-8').splitlines()) # breakpoint() - print(reader) - # print(reader.fieldnames) # id,soldier_id,company_id,powNumber,powCamp_id,dateFrom,dateTo,notes for row in reader: - print(f"""SoldierImprisonment: {row['id']} {row['soldier_id']} """) + #print(f"""SoldierImprisonment: {row['id']} {row['soldier_id']} """) try: SoldierImprisonment.objects.create( id = row['id'], @@ -35,6 +33,5 @@ def run(): notes = row['notes'] ) except Exception as e: - print("Error with: " + row['id']) - + print(f"""💥row: ({row}) """) raise e diff --git a/scripts/insert-all-soldiers.py b/scripts/insert-all-soldiers.py index 99a27ca..3695578 100644 --- a/scripts/insert-all-soldiers.py +++ b/scripts/insert-all-soldiers.py @@ -14,7 +14,7 @@ def run(): ref_data_url = "https://raw.githubusercontent.com/gm3dmo/old-cmp/main/data/soldier.csv" http = urllib3.PoolManager() r = http.request('GET', ref_data_url) - print(r.status) + print(f"""Fetch table response code: {r.status}""") # load the response into a csv dictionary reader reader = csv.DictReader(r.data.decode('ISO-8859-1').splitlines()) # breakpoint() @@ -22,7 +22,7 @@ def run(): # print(reader.fieldnames) for row in reader: # id,surname,initials,army_number,rank_id,notes - print(f"""{row['id']} {row['surname']}""") + #print(f"""{row['id']} {row['surname']}""") try: Soldier.objects.create( id = row['id'], @@ -33,6 +33,6 @@ def run(): notes = row['notes'] ) except Exception as e: - print("Error with: " + row['surname']) + print(f"""💥row: ({row}) """) raise e diff --git a/templates/cmp/soldier.html b/templates/cmp/soldier.html new file mode 100644 index 0000000..2d9d2f5 --- /dev/null +++ b/templates/cmp/soldier.html @@ -0,0 +1,20 @@ +{% extends "base.html" %} +{% load static crispy_forms_tags %} +{% block title %}Soldier{% endblock %} +{% block content %} + +

Soldier

+ + + + + + + + + + + +
Surname:{{ soldier.surname }}
Initials:{{ soldier.initials }}
Rank:{{ soldier.rank }}
Army Number:{{ soldier.army_number }}
Notes:{{ soldier.notes }}
+ +{% endblock %} \ No newline at end of file