X-Git-Url: https://git.toastfreeware.priv.at/gregoa/zavai.git/blobdiff_plain/01a8371687ebdbd667a9de9be6cdd49e9b00f5a2..a02834cf163f36b39331d73359107bdd44bb5aad:/src/log.vala?ds=sidebyside diff --git a/src/log.vala b/src/log.vala index e949939..607fffe 100644 --- a/src/log.vala +++ b/src/log.vala @@ -1,7 +1,7 @@ /* * log - logging functions * - * Copyright (C) 2009 Enrico Zini + * Copyright (C) 2009--2010 Enrico Zini * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,9 +18,328 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +using GLib; + namespace zavai { namespace log { +public class Waypoint : Object +{ + public time_t ts; + public double lat; + public double lon; + + public Waypoint() + { + if (gps.gps.fix_status() != libgps.STATUS_NO_FIX) + { + lat = gps.gps.info().fix.latitude; + lon = gps.gps.info().fix.longitude; + ts = (time_t)gps.gps.info().fix.time; + } else { + // Use 1000 as missing values + lat = 1000; + lon = 1000; + ts = time_t(); + } + } + + public void writeInside(FileStream outfd) + { + var t = Time.gm(ts); + outfd.printf(" \n", t.format("%Y-%m-%dT%H:%M:%SZ")); + } +} + + +public class LogEntry : Waypoint +{ + public string msg; + + public LogEntry() + { + base(); + } + + public void write(FileStream outfd) + { + outfd.printf(" \n", lat, lon); + writeInside(outfd); + outfd.printf(" %s\n", Markup.escape_text(msg)); + outfd.puts(" \n"); + } +} + +public class TrackEntry : Waypoint +{ + public TrackEntry() + { + base(); + } + + public void write(FileStream outfd) + { + outfd.printf(" \n", lat, lon); + writeInside(outfd); + outfd.puts(" \n"); + } +} + + +public class Log : Object +{ + public string tag; + public string title; + public List entries; + public List track; + + public Log(string tag, string title) + { + this.tag = tag; + this.title = title; + entries = null; + track = null; + } + + public void add(string msg) + { + var entry = new LogEntry(); + entry.msg = msg; + entries.append(entry); + } + + public void add_trackpoint() + { + track.append(new TrackEntry()); + } + + public void save() + { + if (entries == null) return; + + // Directory where we save the log + string dir = config.homedir + "/log-" + tag; + DirUtils.create(dir, 0777); + + // First try with a plain name + var t = Time.local(entries.data.ts); + string basename = dir + "/" + t.format("%Y%m%d-%H%M%S"); + + string pathname = basename + ".gpx"; + + // Find a pathname that does not exist already + for (int i = 1; FileUtils.test(pathname, FileTest.EXISTS); ++i) + pathname = "%s-%d.gpx".printf(basename, i); + + // Write out + var outfd = FileStream.open(pathname, "w"); + if (outfd == null) + { + zavai.log.error("opening " + pathname + ": " + strerror(errno)); + return; + } + + write(outfd); + outfd.flush(); + } + + protected void writeTrack(FileStream outfd) + { + outfd.puts(" \n"); + outfd.puts(" \n"); + for (weak List i = track; i != null; i = i.next) + i.data.write(outfd); + outfd.puts(" \n"); + outfd.puts(" \n"); + } + + protected void writeEntries(FileStream outfd) + { + outfd.puts(" \n"); + for (weak List i = entries; i != null; i = i.next) + i.data.write(outfd); + outfd.puts(" \n"); + } + + protected void write(FileStream outfd) + { + outfd.puts("\n"); + outfd.puts("\n"); + outfd.puts(" \n"); + outfd.printf(" %s\n", Markup.escape_text(title)); + outfd.puts(" \n"); + if (track != null) writeTrack(outfd); + if (entries != null) writeEntries(outfd); + outfd.puts(" \n"); + } +} + +enum LogParserState { + NONE, + METADATA, + TRACK, + WPT, +} + +class LogParser: Object +{ + const MarkupParser parser = { // It's a structure, not an object + start,// when an element opens + end, // when an element closes + text, // when text is found + null, // when comments are found + null // when errors occur + }; + + MarkupParseContext context = null; + public Log result = null; + LogParserState state = LogParserState.NONE; + string cur_text = ""; + + construct + { + context = new MarkupParseContext( + parser, // the structure with the callbacks + 0, // MarkupParseFlags + this, // extra argument for the callbacks, methods in this case + destroy // when the parsing ends + ); + } + + void destroy() + { + cur_text = ""; + } + + public bool parse(string content, ssize_t len = -1) throws MarkupError + { + return context.parse(content, len); + } + + + /* + outfd.puts(" \n"); + outfd.printf(" %s\n", Markup.escape_text(title)); + outfd.puts(" \n"); + if (track != null) writeTrack(outfd); + if (entries != null) writeEntries(outfd); + outfd.puts(" \n"); + */ + + + void start (MarkupParseContext context, string name, + string[] attr_names, string[] attr_values) throws MarkupError + { + if (name == "gpx") + { + state = LogParserState.NONE; + result = new Log("TODO:TAG", "TODO:TITLE"); + } else if (name == "metadata") { + state = LogParserState.METADATA; + } else if (name == "wpt") { + state = LogParserState.WPT; + } else if (name == "trkseg") { + state = LogParserState.TRACK; + } + cur_text = ""; + } + + void end (MarkupParseContext context, string name) throws MarkupError + { + if (name == "state") + if (state == LogParserState.METADATA) + result.title = cur_text; + } + + void text (MarkupParseContext context, + string text, size_t text_len) throws MarkupError + { + cur_text += text; + } +} + +public class Logger : Resource, Object +{ + protected List logs; + + public Logger() + { + logs = null; + zavai.registry.register(this); + } + + protected void start_trace() + { + gps.gps.pos_changed += on_pos_changed; + } + + protected void end_trace() + { + gps.gps.pos_changed -= on_pos_changed; + } + + protected void on_pos_changed() + { + for (weak List i = logs; i != null; i = i.next) + i.data.add_trackpoint(); + } + + protected void pop(Log log) + { + for (weak List i = logs; i != null; i = i.next) + if (i.data == log) + logs.delete_link(i); + } + + public Log start(string tag, string title) + { + bool was_empty = (logs == null); + Log res = new Log(tag, title); + logs.append(res); + if (was_empty) start_trace(); + return res; + } + + public void end(Log log) + { + pop(log); + log.save(); + if (logs == null) end_trace(); + } + + public Log load(string fname) + { + string contents; + size_t length; + FileUtils.get_contents(fname, out contents, out length); + LogParser parser = new LogParser(); + parser.parse(contents, (ssize_t)length); + return parser.result; + } + + public void instant(string tag, string msg) + { + var log = new Log(tag, msg); + log.add(msg); + log.save(); + } + + public void shutdown() + { + bool had_logs = (logs != null); + while (logs != null) + { + logs.data.save(); + logs.delete_link(logs); + } + if (had_logs) end_trace(); + } +} + public void error(string s) { stderr.printf("%s\n", s); @@ -38,5 +357,12 @@ public void debug(string s) stderr.printf("%s\n", s); } +Logger log = null; + +public void init() +{ + log = new Logger(); +} + } }