const std = @import("std"); const builtin = @import("builtin"); const clap = @import("clap"); const zdt = @import("zdt"); const render = @import("eink_feed_render"); pub const std_options: std.Options = .{ .log_level = if (builtin.mode == .Debug) .debug else .info, }; pub fn main() !void { var gpa = std.heap.GeneralPurposeAllocator(.{ .thread_safe = true, }){}; defer _ = gpa.deinit(); const allocator = gpa.allocator(); { const params = comptime clap.parseParamsComptime( \\-h, --help Display this help and exit. \\--url URL of eink-feed server. \\--channel Channel ID. \\--efa URL of EFA server. \\--stop Stop ID. \\--tz Time zone. \\--max Max number of departures listed. \\--show-operator Show operator. \\--stopfinder Search for stops on the EFA server with the given search query. ); var diag = clap.Diagnostic{}; var res = clap.parse(clap.Help, ¶ms, clap.parsers.default, .{ .diagnostic = &diag, .allocator = allocator, }) catch |err| { diag.report(std.io.getStdErr().writer(), err) catch {}; return err; }; defer res.deinit(); if (res.args.help != 0 or res.args.efa == null or ((res.args.stop == null or res.args.tz == null or res.args.url == null or res.args.channel == null) and res.args.stopfinder == null)) { const writer = std.io.getStdErr().writer(); try writer.writeAll("eink-feed-render-departures\n"); return clap.help(writer, clap.Help, ¶ms, .{}); } const efa = try render.apps.Departures.efa.Client.init(allocator, res.args.efa.?); defer efa.deinit(); if (res.args.stopfinder) |query| { try efa.findStops(query); return; } var tz = try zdt.Timezone.fromTzdata(res.args.tz.?, allocator); defer tz.deinit(); render.renderer.init(); defer render.renderer.deinit(); const feed_client = try render.FeedClient.init(allocator, res.args.url.?); defer feed_client.deinit(); const channel = try feed_client.getChannel(res.args.channel.?); defer channel.deinit(); const dim = render.Dimensions{ .width = channel.value.display.width, .height = channel.value.display.height, }; const orientation = channel.value.display.orientation.toInternal(); const departures = render.apps.Departures.init(allocator, dim); const stop_id: []const u8 = res.args.stop.?; const now = try zdt.Datetime.now(.{ .tz = &tz }); const efa_departures = try efa.getDepartures(stop_id); defer efa_departures.deinit(); const png = try departures.render(&efa_departures.value, .{ .now = &now, .tz = &tz, .max_items = res.args.max orelse 15, .show_operator = res.args.@"show-operator" != 0, }); defer allocator.free(png); try feed_client.uploadFrame( channel.value.id, orientation, png, "image/png", ); } }