diff --git a/src/http/handler.zig b/src/http/handler.zig index 28cf208..93ef6df 100644 --- a/src/http/handler.zig +++ b/src/http/handler.zig @@ -24,9 +24,21 @@ pub fn handleWeather( req: *httpz.Request, res: *httpz.Response, ) !void { - // Get client IP for location detection - const client_ip = getClientIP(req); - try handleWeatherInternal(opts, req, res, client_ip); + // Check for location query parameter first + const query_string = req.url.query; + const params = try QueryParams.parse(req.arena, query_string); + defer { + if (params.format) |f| req.arena.free(f); + if (params.lang) |l| req.arena.free(l); + } + + const location = if (params.location) |loc| loc else blk: { + // Fall back to IP-based detection + const client_ip = getClientIP(req); + break :blk client_ip; + }; + + try handleWeatherInternal(opts, req, res, location); } pub fn handleWeatherLocation( diff --git a/src/http/query.zig b/src/http/query.zig index d6e042e..ca52c3a 100644 --- a/src/http/query.zig +++ b/src/http/query.zig @@ -3,6 +3,7 @@ const std = @import("std"); pub const QueryParams = struct { format: ?[]const u8 = null, lang: ?[]const u8 = null, + location: ?[]const u8 = null, units: ?Units = null, transparency: ?u8 = null, @@ -26,10 +27,16 @@ pub const QueryParams = struct { params.format = if (value) |v| try allocator.dupe(u8, v) else null; } else if (std.mem.eql(u8, key, "lang")) { params.lang = if (value) |v| try allocator.dupe(u8, v) else null; + } else if (std.mem.eql(u8, key, "location")) { + params.location = if (value) |v| try allocator.dupe(u8, v) else null; } else if (std.mem.eql(u8, key, "u")) { params.units = .uscs; } else if (std.mem.eql(u8, key, "m")) { params.units = .metric; + } else if (std.mem.eql(u8, key, "use_imperial")) { + params.units = .uscs; + } else if (std.mem.eql(u8, key, "use_metric")) { + params.units = .metric; } else if (std.mem.eql(u8, key, "transparency")) { if (value) |v| { params.transparency = try std.fmt.parseInt(u8, v, 10); diff --git a/src/location/resolver.zig b/src/location/resolver.zig index 97abf29..cc15e85 100644 --- a/src/location/resolver.zig +++ b/src/location/resolver.zig @@ -107,14 +107,17 @@ pub const Resolver = struct { var response_buf: [1024 * 1024]u8 = undefined; var writer = std.Io.Writer.fixed(&response_buf); - const result = try client.fetch(.{ + const result = client.fetch(.{ .location = .{ .uri = uri }, .method = .GET, .response_writer = &writer, .extra_headers = &.{ .{ .name = "User-Agent", .value = "wttr.in-zig/1.0" }, }, - }); + }) catch { + std.log.warn("Nominatim API call failed for: {s}", .{name}); + return error.GeocodingFailed; + }; if (result.status != .ok) { return error.GeocodingFailed;