location
This commit is contained in:
BIN
examples/data/location/location_example
Executable file
BIN
examples/data/location/location_example
Executable file
Binary file not shown.
@@ -9,9 +9,13 @@ println('Location database initialized')
|
||||
// Initialize the database (downloads and imports data)
|
||||
// This only needs to be done once or when updating data
|
||||
println('Downloading and importing location data (this may take a few minutes)...')
|
||||
loc.download_and_import() or { panic(err) }
|
||||
|
||||
//the arg is if we redownload
|
||||
loc.download_and_import(false) or { panic(err) }
|
||||
println('Data import complete')
|
||||
|
||||
|
||||
|
||||
// // Example 1: Search for a city
|
||||
// println('\nSearching for London...')
|
||||
// results := loc.search('London', 'GB', 5, true) or { panic(err) }
|
||||
|
||||
@@ -29,7 +29,7 @@ pub fn new_location_db(reset bool) !LocationDB {
|
||||
|
||||
// init_tables drops and recreates all tables
|
||||
fn (mut l LocationDB) init_tables(reset bool) ! {
|
||||
if reset{
|
||||
if reset {
|
||||
l.db.exec('DROP TABLE IF EXISTS AlternateName')!
|
||||
l.db.exec('DROP TABLE IF EXISTS City')!
|
||||
l.db.exec('DROP TABLE IF EXISTS Country')!
|
||||
@@ -40,6 +40,11 @@ fn (mut l LocationDB) init_tables(reset bool) ! {
|
||||
create table City
|
||||
create table AlternateName
|
||||
}!
|
||||
|
||||
// When resetting, ensure all countries have import_date set to 0
|
||||
if reset {
|
||||
l.db.exec('UPDATE Country SET import_date = 0')!
|
||||
}
|
||||
}
|
||||
|
||||
// close closes the database connection
|
||||
|
||||
@@ -15,8 +15,8 @@ pub fn new(reset bool) !Location {
|
||||
}
|
||||
|
||||
// init_database downloads and imports the initial dataset
|
||||
pub fn (mut l Location) download_and_import() ! {
|
||||
l.db.download_and_import_data()!
|
||||
pub fn (mut l Location) download_and_import(redownload bool) ! {
|
||||
l.db.download_and_import_data(redownload)!
|
||||
}
|
||||
|
||||
// Example usage:
|
||||
|
||||
@@ -2,6 +2,7 @@ module location
|
||||
|
||||
import os
|
||||
import io
|
||||
import time
|
||||
import freeflowuniverse.herolib.osal
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.core.texttools
|
||||
@@ -11,9 +12,13 @@ const (
|
||||
)
|
||||
|
||||
// download_and_import_data downloads and imports GeoNames data
|
||||
pub fn (mut l LocationDB) download_and_import_data() ! {
|
||||
pub fn (mut l LocationDB) download_and_import_data(redownload bool) ! {
|
||||
// Download country info
|
||||
|
||||
if redownload{
|
||||
l.reset_import_dates()!
|
||||
}
|
||||
|
||||
country_file := osal.download(
|
||||
url: '${geonames_url}/countryInfo.txt'
|
||||
dest: '${l.tmp_dir.path}/country.txt'
|
||||
@@ -25,6 +30,42 @@ pub fn (mut l LocationDB) download_and_import_data() ! {
|
||||
|
||||
}
|
||||
|
||||
// reset_import_dates sets all country import_dates to 0
|
||||
pub fn (mut l LocationDB) reset_import_dates() ! {
|
||||
l.db.exec('BEGIN TRANSACTION')!
|
||||
l.db.exec('UPDATE Country SET import_date = 0')!
|
||||
l.db.exec('COMMIT')!
|
||||
console.print_header('Reset all country import dates to 0')
|
||||
}
|
||||
|
||||
// should_import_cities checks if a city should be imported based on its last import date on country level
|
||||
fn (mut l LocationDB) should_import_cities(iso2 string) !bool {
|
||||
console.print_debug('Checking if should import country: ${iso2}')
|
||||
|
||||
country := sql l.db {
|
||||
select from Country where iso2 == "${iso2}" limit 1
|
||||
} or { []Country{} }
|
||||
|
||||
console.print_debug('SQL query result: ${country.len} records found')
|
||||
|
||||
if country.len == 0 {
|
||||
console.print_debug('No existing record found for ${iso2}, will import')
|
||||
return true // New country, should import
|
||||
}
|
||||
|
||||
// Check if last import was more than a month ago
|
||||
now := time.now().unix()
|
||||
one_month := i64(30 * 24 * 60 * 60) // 30 days in seconds
|
||||
last_import := country[0].import_date
|
||||
time_since_import := now - last_import
|
||||
|
||||
console.print_debug('Last import: ${last_import}, Time since import: ${time_since_import} seconds (${time_since_import/86400} days)')
|
||||
should_import := (time_since_import > one_month) || (last_import == 0)
|
||||
console.print_debug('Should import ${iso2}: ${should_import}')
|
||||
|
||||
return should_import
|
||||
}
|
||||
|
||||
// import_country_data imports country information from a file
|
||||
fn (mut l LocationDB) import_country_data(filepath string) ! {
|
||||
console.print_header('Starting import from: ${filepath}')
|
||||
@@ -99,7 +140,6 @@ fn (mut l LocationDB) import_cities() ! {
|
||||
console.print_header('Starting Cities Import')
|
||||
|
||||
// Query all countries from the database
|
||||
|
||||
mut countries := sql l.db {
|
||||
select from Country
|
||||
}!
|
||||
@@ -109,6 +149,13 @@ fn (mut l LocationDB) import_cities() ! {
|
||||
iso2 := country.iso2.to_upper()
|
||||
console.print_header('Processing country: ${country.name} (${iso2})')
|
||||
|
||||
// Check if we need to import cities for this country
|
||||
should_import := l.should_import_cities(iso2)!
|
||||
if !should_import {
|
||||
console.print_debug('Skipping ${country.name} (${iso2}) - recently imported')
|
||||
continue
|
||||
}
|
||||
|
||||
// Download and process cities for this country
|
||||
cities_file := osal.download(
|
||||
url: '${geonames_url}/${iso2}.zip'
|
||||
@@ -117,9 +164,16 @@ fn (mut l LocationDB) import_cities() ! {
|
||||
minsize_kb: 2
|
||||
)!
|
||||
|
||||
println(cities_file)
|
||||
|
||||
l.import_city_data("${l.tmp_dir.path}/${iso2}/${iso2}.txt")!
|
||||
|
||||
// Update the country's import date after successful city import
|
||||
now := time.now().unix()
|
||||
l.db.exec('BEGIN TRANSACTION')!
|
||||
sql l.db {
|
||||
update Country set import_date = now where iso2 == iso2
|
||||
}!
|
||||
l.db.exec('COMMIT')!
|
||||
console.print_debug('Updated import date for ${country.name} (${iso2}) to ${now}')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ pub:
|
||||
continent string @[max_len: 2]
|
||||
population i64
|
||||
timezone string @[max_len: 40]
|
||||
import_date i64 // Epoch timestamp of last import
|
||||
}
|
||||
|
||||
pub struct City {
|
||||
|
||||
Reference in New Issue
Block a user