mirror of
https://github.com/seanmorley15/AdventureLog.git
synced 2025-07-28 17:29:36 +02:00
commit
c10aa873de
3 changed files with 154 additions and 32 deletions
|
@ -3,18 +3,21 @@
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from worldtravel.models import Country, Region
|
from worldtravel.models import Country, Region
|
||||||
|
from django.db import transaction
|
||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
help = 'Imports the world travel data'
|
help = 'Imports the world travel data'
|
||||||
|
|
||||||
def handle(self, *args, **kwargs):
|
def add_arguments(self, parser):
|
||||||
|
parser.add_argument(
|
||||||
|
'-f', '--force',
|
||||||
|
action='store_true',
|
||||||
|
help='Force import even if data already exists'
|
||||||
|
)
|
||||||
|
|
||||||
# if the country or regions tables are not empty, do not insert data
|
def handle(self, *args, **options):
|
||||||
if Country.objects.exists() or Region.objects.exists():
|
force = options['force']
|
||||||
self.stdout.write(self.style.NOTICE(
|
|
||||||
'Countries or regions already exist in the database!'))
|
|
||||||
return
|
|
||||||
|
|
||||||
countries = [
|
countries = [
|
||||||
('United States', 'us', 'NA'),
|
('United States', 'us', 'NA'),
|
||||||
|
@ -39,21 +42,6 @@ class Command(BaseCommand):
|
||||||
('Italy', 'it', 'EU'),
|
('Italy', 'it', 'EU'),
|
||||||
]
|
]
|
||||||
|
|
||||||
for name, country_code, continent in countries:
|
|
||||||
country, created = Country.objects.get_or_create(
|
|
||||||
name=name,
|
|
||||||
country_code=country_code,
|
|
||||||
defaults={'continent': continent}
|
|
||||||
)
|
|
||||||
if created:
|
|
||||||
print(f'Inserted {name} into worldtravel countries')
|
|
||||||
else:
|
|
||||||
print(f'{name} already exists in worldtravel countries')
|
|
||||||
|
|
||||||
self.stdout.write(self.style.SUCCESS(
|
|
||||||
'Successfully inserted worldtravel countries!'
|
|
||||||
))
|
|
||||||
|
|
||||||
regions = [
|
regions = [
|
||||||
('US-AL', 'Alabama', 'us'),
|
('US-AL', 'Alabama', 'us'),
|
||||||
('US-AK', 'Alaska', 'us'),
|
('US-AK', 'Alaska', 'us'),
|
||||||
|
@ -136,7 +124,7 @@ class Command(BaseCommand):
|
||||||
('DE-TH', 'Thüringen', 'de'),
|
('DE-TH', 'Thüringen', 'de'),
|
||||||
('FR-ARA', 'Auvergne-Rhône-Alpes', 'fr'),
|
('FR-ARA', 'Auvergne-Rhône-Alpes', 'fr'),
|
||||||
('FR-BFC', 'Bourgogne-Franche-Comté', 'fr'),
|
('FR-BFC', 'Bourgogne-Franche-Comté', 'fr'),
|
||||||
('FR-BRE', 'Brittany', 'fr'),
|
('FR-BRE', 'Bretagne', 'fr'),
|
||||||
('FR-CVL', 'Centre-Val de Loire', 'fr'),
|
('FR-CVL', 'Centre-Val de Loire', 'fr'),
|
||||||
('FR-GES', 'Grand Est', 'fr'),
|
('FR-GES', 'Grand Est', 'fr'),
|
||||||
('FR-HDF', 'Hauts-de-France', 'fr'),
|
('FR-HDF', 'Hauts-de-France', 'fr'),
|
||||||
|
@ -501,17 +489,73 @@ class Command(BaseCommand):
|
||||||
('IT-34', 'Veneto', 'it'),
|
('IT-34', 'Veneto', 'it'),
|
||||||
]
|
]
|
||||||
|
|
||||||
for code, name, country_code in regions:
|
if not force and (Country.objects.exists() or Region.objects.exists()):
|
||||||
|
self.stdout.write(self.style.WARNING(
|
||||||
|
'Countries or regions already exist in the database. Use --force to override.'
|
||||||
|
))
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
with transaction.atomic():
|
||||||
|
if force:
|
||||||
|
self.sync_countries(countries)
|
||||||
|
self.sync_regions(regions)
|
||||||
|
else:
|
||||||
|
self.insert_countries(countries)
|
||||||
|
self.insert_regions(regions)
|
||||||
|
|
||||||
|
self.stdout.write(self.style.SUCCESS('Successfully imported world travel data'))
|
||||||
|
except Exception as e:
|
||||||
|
self.stdout.write(self.style.ERROR(f'Error importing data: {str(e)}'))
|
||||||
|
|
||||||
|
def sync_countries(self, countries):
|
||||||
|
country_codes = [code for _, code, _ in countries]
|
||||||
|
Country.objects.exclude(country_code__in=country_codes).delete()
|
||||||
|
|
||||||
|
for name, country_code, continent in countries:
|
||||||
|
country, created = Country.objects.update_or_create(
|
||||||
|
country_code=country_code,
|
||||||
|
defaults={'name': name, 'continent': continent}
|
||||||
|
)
|
||||||
|
if created:
|
||||||
|
self.stdout.write(f'Inserted {name} into worldtravel countries')
|
||||||
|
else:
|
||||||
|
self.stdout.write(f'Updated {name} in worldtravel countries')
|
||||||
|
|
||||||
|
def sync_regions(self, regions):
|
||||||
|
region_ids = [id for id, _, _ in regions]
|
||||||
|
Region.objects.exclude(id__in=region_ids).delete()
|
||||||
|
|
||||||
|
for id, name, country_code in regions:
|
||||||
country = Country.objects.get(country_code=country_code)
|
country = Country.objects.get(country_code=country_code)
|
||||||
region, created = Region.objects.get_or_create(
|
region, created = Region.objects.update_or_create(
|
||||||
id=code,
|
id=id,
|
||||||
defaults={'name': name, 'country': country}
|
defaults={'name': name, 'country': country}
|
||||||
)
|
)
|
||||||
if created:
|
if created:
|
||||||
print(f'Inserted region: {name} ({code})')
|
self.stdout.write(f'Inserted {name} into worldtravel regions')
|
||||||
else:
|
else:
|
||||||
print(f'Region already exists: {name} ({code})')
|
self.stdout.write(f'Updated {name} in worldtravel regions')
|
||||||
|
|
||||||
self.stdout.write(self.style.SUCCESS(
|
def insert_countries(self, countries):
|
||||||
'Successfully inserted worldtravel regions!'
|
for name, country_code, continent in countries:
|
||||||
))
|
country, created = Country.objects.get_or_create(
|
||||||
|
country_code=country_code,
|
||||||
|
defaults={'name': name, 'continent': continent}
|
||||||
|
)
|
||||||
|
if created:
|
||||||
|
self.stdout.write(f'Inserted {name} into worldtravel countries')
|
||||||
|
else:
|
||||||
|
self.stdout.write(f'{name} already exists in worldtravel countries')
|
||||||
|
|
||||||
|
def insert_regions(self, regions):
|
||||||
|
for id, name, country_code in regions:
|
||||||
|
country = Country.objects.get(country_code=country_code)
|
||||||
|
region, created = Region.objects.get_or_create(
|
||||||
|
id=id,
|
||||||
|
defaults={'name': name, 'country': country}
|
||||||
|
)
|
||||||
|
if created:
|
||||||
|
self.stdout.write(f'Inserted {name} into worldtravel regions')
|
||||||
|
else:
|
||||||
|
self.stdout.write(f'{name} already exists in worldtravel regions')
|
|
@ -9,6 +9,9 @@
|
||||||
|
|
||||||
export let type: string = 'visited';
|
export let type: string = 'visited';
|
||||||
|
|
||||||
|
export let longitude: number | null = null;
|
||||||
|
export let latitude: number | null = null;
|
||||||
|
|
||||||
import Wikipedia from '~icons/mdi/wikipedia';
|
import Wikipedia from '~icons/mdi/wikipedia';
|
||||||
import ClipboardList from '~icons/mdi/clipboard-list';
|
import ClipboardList from '~icons/mdi/clipboard-list';
|
||||||
import ActivityComplete from './ActivityComplete.svelte';
|
import ActivityComplete from './ActivityComplete.svelte';
|
||||||
|
@ -31,6 +34,11 @@
|
||||||
collection: null
|
collection: null
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (longitude && latitude) {
|
||||||
|
newAdventure.latitude = latitude;
|
||||||
|
newAdventure.longitude = longitude;
|
||||||
|
}
|
||||||
|
|
||||||
let image: File;
|
let image: File;
|
||||||
let fileInput: HTMLInputElement;
|
let fileInput: HTMLInputElement;
|
||||||
|
|
||||||
|
@ -137,6 +145,8 @@
|
||||||
query={newAdventure.name}
|
query={newAdventure.name}
|
||||||
on:close={() => (isPointModalOpen = false)}
|
on:close={() => (isPointModalOpen = false)}
|
||||||
on:submit={setLongLat}
|
on:submit={setLongLat}
|
||||||
|
latitude={newAdventure.latitude || null}
|
||||||
|
longitude={newAdventure.longitude || null}
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
@ -164,6 +174,28 @@
|
||||||
on:submit={handleSubmit}
|
on:submit={handleSubmit}
|
||||||
action="/adventures?/create"
|
action="/adventures?/create"
|
||||||
>
|
>
|
||||||
|
<div class="join">
|
||||||
|
<input
|
||||||
|
class="join-item btn btn-neutral"
|
||||||
|
type="radio"
|
||||||
|
name="type"
|
||||||
|
id="visited"
|
||||||
|
value="visited"
|
||||||
|
aria-label="Visited"
|
||||||
|
checked
|
||||||
|
on:click={() => (type = 'visited')}
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
class="join-item btn btn-neutral"
|
||||||
|
type="radio"
|
||||||
|
name="type"
|
||||||
|
id="planned"
|
||||||
|
value="planned"
|
||||||
|
aria-label="Planned"
|
||||||
|
on:click={() => (type = 'planned')}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
name="type"
|
name="type"
|
||||||
|
@ -310,7 +342,8 @@
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="btn btn-secondary"
|
class="btn btn-secondary"
|
||||||
on:click={() => (isPointModalOpen = true)}>Define Location</button
|
on:click={() => (isPointModalOpen = true)}
|
||||||
|
>{newAdventure.latitude && newAdventure.longitude ? 'Change' : 'Select'} Location</button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="btn btn-primary mr-4 mt-4">Create</button>
|
<button type="submit" class="btn btn-primary mr-4 mt-4">Create</button>
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
|
|
||||||
|
import NewAdventure from '$lib/components/NewAdventure.svelte';
|
||||||
import {
|
import {
|
||||||
DefaultMarker,
|
DefaultMarker,
|
||||||
MapEvents,
|
MapEvents,
|
||||||
|
@ -16,6 +17,19 @@
|
||||||
|
|
||||||
let clickedName = '';
|
let clickedName = '';
|
||||||
|
|
||||||
|
let newMarker = [];
|
||||||
|
|
||||||
|
let newLongitude = null;
|
||||||
|
let newLatitude = null;
|
||||||
|
|
||||||
|
function addMarker(e) {
|
||||||
|
newMarker = [];
|
||||||
|
newMarker = [...newMarker, { lngLat: e.detail.lngLat, name: 'Marker 1' }];
|
||||||
|
console.log(newMarker);
|
||||||
|
newLongitude = e.detail.lngLat.lng;
|
||||||
|
newLatitude = e.detail.lngLat.lat;
|
||||||
|
}
|
||||||
|
|
||||||
let markers = data.props.markers;
|
let markers = data.props.markers;
|
||||||
|
|
||||||
let visitedRegions = data.props.visitedRegions;
|
let visitedRegions = data.props.visitedRegions;
|
||||||
|
@ -29,10 +43,37 @@
|
||||||
visitArray.push(el.region);
|
visitArray.push(el.region);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function clearMarkers() {
|
||||||
|
newMarker = [];
|
||||||
|
newLatitude = null;
|
||||||
|
newLongitude = null;
|
||||||
|
}
|
||||||
|
|
||||||
// mapped to the checkbox
|
// mapped to the checkbox
|
||||||
let showGEO = true;
|
let showGEO = true;
|
||||||
|
|
||||||
|
let createModalOpen = false;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
{#if newMarker.length > 0}
|
||||||
|
<button type="button" class="btn btn-primary mb-2" on:click={() => (createModalOpen = true)}
|
||||||
|
>Add New Adventure at Marker</button
|
||||||
|
>
|
||||||
|
<button type="button" class="btn btn-neutral mb-2" on:click={clearMarkers}>Clear Marker</button>
|
||||||
|
{:else}
|
||||||
|
<button type="button" class="btn btn-primary mb-2" on:click={() => (createModalOpen = true)}
|
||||||
|
>Add New Adventure</button
|
||||||
|
>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#if createModalOpen}
|
||||||
|
<NewAdventure
|
||||||
|
on:close={() => (createModalOpen = false)}
|
||||||
|
longitude={newLongitude}
|
||||||
|
latitude={newLatitude}
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
|
|
||||||
<label for="show-geo">Show Borders?</label>
|
<label for="show-geo">Show Borders?</label>
|
||||||
<input type="checkbox" id="shpw-gep" name="show-geo" class="checkbox" bind:checked={showGEO} />
|
<input type="checkbox" id="shpw-gep" name="show-geo" class="checkbox" bind:checked={showGEO} />
|
||||||
|
|
||||||
|
@ -109,6 +150,10 @@
|
||||||
/> -->
|
/> -->
|
||||||
</GeoJSON>
|
</GeoJSON>
|
||||||
{/if}
|
{/if}
|
||||||
|
<MapEvents on:click={addMarker} />
|
||||||
|
{#each newMarker as marker}
|
||||||
|
<DefaultMarker lngLat={marker.lngLat} />
|
||||||
|
{/each}
|
||||||
</MapLibre>
|
</MapLibre>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue