first pass at MetNo user agent
This commit is contained in:
parent
ea17e18c6f
commit
24903e4beb
2 changed files with 33 additions and 5 deletions
|
|
@ -10,7 +10,7 @@ const Airports = @import("location/Airports.zig");
|
||||||
const Resolver = @import("location/resolver.zig").Resolver;
|
const Resolver = @import("location/resolver.zig").Resolver;
|
||||||
const GeoLite2 = @import("location/GeoLite2.zig");
|
const GeoLite2 = @import("location/GeoLite2.zig");
|
||||||
|
|
||||||
pub fn main() !void {
|
pub fn main() !u8 {
|
||||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||||
defer _ = gpa.deinit();
|
defer _ = gpa.deinit();
|
||||||
const allocator = gpa.allocator();
|
const allocator = gpa.allocator();
|
||||||
|
|
@ -67,7 +67,10 @@ pub fn main() !void {
|
||||||
});
|
});
|
||||||
defer rate_limiter.deinit();
|
defer rate_limiter.deinit();
|
||||||
|
|
||||||
var metno = try MetNo.init(allocator);
|
var metno = MetNo.init(allocator, null) catch |err| {
|
||||||
|
if (err == MetNo.MissingIdentificationError) return 1;
|
||||||
|
return err;
|
||||||
|
};
|
||||||
defer metno.deinit();
|
defer metno.deinit();
|
||||||
|
|
||||||
var server = try Server.init(allocator, cfg.listen_host, cfg.listen_port, .{
|
var server = try Server.init(allocator, cfg.listen_host, cfg.listen_port, .{
|
||||||
|
|
@ -77,6 +80,7 @@ pub fn main() !void {
|
||||||
}, &rate_limiter);
|
}, &rate_limiter);
|
||||||
|
|
||||||
try server.listen();
|
try server.listen();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
test {
|
test {
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ const zeit = @import("zeit");
|
||||||
|
|
||||||
const MetNo = @This();
|
const MetNo = @This();
|
||||||
|
|
||||||
|
pub const MissingIdentificationError = error.MetNoIdentificationRequired;
|
||||||
|
|
||||||
const MetNoOpenWeatherEntry = struct { []const u8, types.WeatherCode };
|
const MetNoOpenWeatherEntry = struct { []const u8, types.WeatherCode };
|
||||||
// symbol codes: https://github.com/metno/weathericons/tree/main/weather
|
// symbol codes: https://github.com/metno/weathericons/tree/main/weather
|
||||||
// they also have _day, _night and _polartwilight variants
|
// they also have _day, _night and _polartwilight variants
|
||||||
|
|
@ -63,10 +65,24 @@ const WeatherCodeMap = std.StaticStringMap(types.WeatherCode);
|
||||||
const weather_code_map = WeatherCodeMap.initComptime(weather_code_entries);
|
const weather_code_map = WeatherCodeMap.initComptime(weather_code_entries);
|
||||||
|
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
|
identifying_email: []const u8,
|
||||||
|
|
||||||
|
pub fn init(allocator: std.mem.Allocator, identifying_email: ?[]const u8) !MetNo {
|
||||||
|
const email = identifying_email orelse blk: {
|
||||||
|
const env_email = std.process.getEnvVarOwned(allocator, "METNO_TOS_IDENTIFYING_EMAIL") catch |err| {
|
||||||
|
if (err == error.EnvironmentVariableNotFound) {
|
||||||
|
std.log.err("Met.no Terms of Service require identification. Set METNO_TOS_IDENTIFYING_EMAIL environment variable. See https://api.met.no/doc/TermsOfService", .{});
|
||||||
|
std.log.err("See \x1b]8;;https://api.met.no/doc/TermsOfService\x1b\\https://api.met.no/doc/TermsOfService\x1b]8;;\x1b\\ for more information", .{});
|
||||||
|
return MissingIdentificationError;
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
};
|
||||||
|
break :blk env_email;
|
||||||
|
};
|
||||||
|
|
||||||
pub fn init(allocator: std.mem.Allocator) !MetNo {
|
|
||||||
return MetNo{
|
return MetNo{
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
|
.identifying_email = email,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -100,12 +116,20 @@ fn fetchRaw(ptr: *anyopaque, allocator: std.mem.Allocator, coords: Coordinates)
|
||||||
|
|
||||||
var response_buf: [1024 * 1024]u8 = undefined;
|
var response_buf: [1024 * 1024]u8 = undefined;
|
||||||
var writer = std.Io.Writer.fixed(&response_buf);
|
var writer = std.Io.Writer.fixed(&response_buf);
|
||||||
|
|
||||||
|
const user_agent = try std.fmt.allocPrint(
|
||||||
|
self.allocator,
|
||||||
|
"wttr/1.0 git.lerch.org/lobo/wttr {s}",
|
||||||
|
.{self.identifying_email},
|
||||||
|
);
|
||||||
|
defer self.allocator.free(user_agent);
|
||||||
|
|
||||||
const result = try client.fetch(.{
|
const result = try client.fetch(.{
|
||||||
.location = .{ .uri = uri },
|
.location = .{ .uri = uri },
|
||||||
.method = .GET,
|
.method = .GET,
|
||||||
.response_writer = &writer,
|
.response_writer = &writer,
|
||||||
.extra_headers = &.{
|
.extra_headers = &.{
|
||||||
.{ .name = "User-Agent", .value = "wttr.in-zig/1.0 github.com/chubin/wttr.in" },
|
.{ .name = "User-Agent", .value = user_agent },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -145,7 +169,7 @@ fn deinitProvider(ptr: *anyopaque) void {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *MetNo) void {
|
pub fn deinit(self: *MetNo) void {
|
||||||
_ = self;
|
self.allocator.free(self.identifying_email);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parseMetNoResponse(allocator: std.mem.Allocator, coords: Coordinates, json: std.json.Value) !types.WeatherData {
|
fn parseMetNoResponse(allocator: std.mem.Allocator, coords: Coordinates, json: std.json.Value) !types.WeatherData {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue