use airport data from zig fetch

This commit is contained in:
Emil Lerch 2025-12-18 14:33:04 -08:00
parent 7e7fd77ec7
commit 5614225050
Signed by: lobo
GPG key ID: A7B62D657EF764F8
4 changed files with 16 additions and 28 deletions

View file

@ -9,6 +9,8 @@ pub fn build(b: *std.Build) void {
.optimize = optimize,
});
const openflights = b.dependency("openflights", .{});
const maxminddb_upstream = b.dependency("maxminddb", .{});
// Build libmaxminddb as a static library
@ -56,6 +58,9 @@ pub fn build(b: *std.Build) void {
});
exe.root_module.addImport("httpz", httpz.module("httpz"));
exe.root_module.addAnonymousImport("airports.dat", .{
.root_source_file = openflights.path("data/airports.dat"),
});
exe.linkLibrary(maxminddb);
exe.linkLibC();
@ -78,6 +83,9 @@ pub fn build(b: *std.Build) void {
}),
});
tests.root_module.addImport("httpz", httpz.module("httpz"));
tests.root_module.addAnonymousImport("airports.dat", .{
.root_source_file = openflights.path("data/airports.dat"),
});
tests.linkLibrary(maxminddb);
tests.linkLibC();

View file

@ -7,7 +7,6 @@ pub const Config = struct {
cache_dir: []const u8,
geolite_path: []const u8,
geocache_file: ?[]const u8,
airports_dat_path: ?[]const u8,
pub fn load(allocator: std.mem.Allocator) !Config {
var env = try std.process.getEnvMap(allocator);
@ -25,7 +24,6 @@ pub const Config = struct {
.cache_dir = if (env.get("WTTR_CACHE_DIR")) |v| try allocator.dupe(u8, v) else try allocator.dupe(u8, "/tmp/wttr-cache"),
.geolite_path = if (env.get("WTTR_GEOLITE_PATH")) |v| try allocator.dupe(u8, v) else try allocator.dupe(u8, "./GeoLite2-City.mmdb"),
.geocache_file = if (env.get("WTTR_GEOCACHE_FILE")) |v| try allocator.dupe(u8, v) else null,
.airports_dat_path = if (env.get("WTTR_AIRPORTS_DAT")) |v| try allocator.dupe(u8, v) else null,
};
}
@ -34,7 +32,6 @@ pub const Config = struct {
allocator.free(self.cache_dir);
allocator.free(self.geolite_path);
if (self.geocache_file) |f| allocator.free(f);
if (self.airports_dat_path) |f| allocator.free(f);
}
};
@ -48,5 +45,4 @@ test "config loads defaults" {
try std.testing.expectEqual(@as(usize, 10_000), cfg.cache_size);
try std.testing.expectEqualStrings("./GeoLite2-City.mmdb", cfg.geolite_path);
try std.testing.expect(cfg.geocache_file == null);
try std.testing.expect(cfg.airports_dat_path == null);
}

View file

@ -12,17 +12,12 @@ const Airports = @This();
allocator: std.mem.Allocator,
airports: std.StringHashMap(Airport),
pub fn initFromFile(allocator: std.mem.Allocator, file_path: []const u8) !Airports {
const file = try std.fs.cwd().openFile(file_path, .{});
defer file.close();
const csv_data = try file.readToEndAlloc(allocator, 10 * 1024 * 1024); // 10MB max
defer allocator.free(csv_data);
return try init(allocator, csv_data);
pub fn init(allocator: std.mem.Allocator) !Airports {
const csv_data = @embedFile("airports.dat");
return try initFromData(allocator, csv_data);
}
pub fn init(allocator: std.mem.Allocator, csv_data: []const u8) !Airports {
pub fn initFromData(allocator: std.mem.Allocator, csv_data: []const u8) !Airports {
var airports = std.StringHashMap(Airport).init(allocator);
var lines = std.mem.splitScalar(u8, csv_data, '\n');
@ -121,7 +116,7 @@ test "AirportDB lookup" {
const allocator = std.testing.allocator;
const csv = "1,\"Munich Airport\",\"Munich\",\"Germany\",\"MUC\",\"EDDM\",48.353802,11.7861,1487,1,\"E\",\"Europe/Berlin\",\"airport\",\"OurAirports\"";
var db = try Airports.init(allocator, csv);
var db = try Airports.initFromData(allocator, csv);
defer db.deinit();
const result = db.lookup("MUC");

View file

@ -36,9 +36,6 @@ pub fn main() !void {
} else {
try stdout.print("Geocache: in-memory only\n", .{});
}
if (cfg.airports_dat_path) |f| {
try stdout.print("Airports database: {s}\n", .{f});
}
try stdout.flush();
// Ensure GeoLite2 database exists
@ -57,19 +54,11 @@ pub fn main() !void {
defer geocache.deinit();
// Initialize airports database
var airports_db: ?Airports = null;
if (cfg.airports_dat_path) |path| {
airports_db = Airports.initFromFile(allocator, path) catch |err| blk: {
std.log.warn("Failed to load airports database: {}", .{err});
break :blk null;
};
}
if (airports_db) |*db| {
defer db.deinit();
}
var airports_db = try Airports.init(allocator);
defer airports_db.deinit();
// Initialize location resolver
var resolver = Resolver.init(allocator, &geoip, &geocache, if (airports_db) |*db| db else null);
var resolver = Resolver.init(allocator, &geoip, &geocache, &airports_db);
var cache = try Cache.init(allocator, .{
.max_entries = cfg.cache_size,