1 /*
2     Output only format for Human Readable formats.
3 
4     Copyright (C) 2004 Scott Brynen, scott (at) brynen.com
5     Copyright (C) 2002 Robert Lipe, robertlipe@usa.net
6 
7     This program is free software; you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation; either version 2 of the License, or
10     (at your option) any later version.
11 
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16 
17     You should have received a copy of the GNU General Public License
18     along with this program; if not, write to the Free Software
19     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
20 */
21 
22 
23 #include "defs.h"
24 #include "jeeps/gpsmath.h"
25 #include <ctype.h>
26 
27 static gbfile *file_out;
28 static short_handle mkshort_handle;
29 
30 static char *suppresssep = NULL;
31 static char *txt_encrypt = NULL;
32 static char *includelogs = NULL;
33 static char *degformat = NULL;
34 static char *altunits = NULL;
35 static char *split_output = NULL;
36 static int waypoint_count;
37 static char *output_name;
38 
39 #define MYNAME "TEXT"
40 
41 static
42 arglist_t text_args[] = {
43   {
44     "nosep", &suppresssep,
45     "Suppress separator lines between waypoints",
46     NULL, ARGTYPE_BOOL, ARG_NOMINMAX
47   },
48   {
49     "encrypt", &txt_encrypt,
50     "Encrypt hints using ROT13", NULL, ARGTYPE_BOOL, ARG_NOMINMAX
51   },
52   {
53     "logs", &includelogs,
54     "Include groundspeak logs if present", NULL, ARGTYPE_BOOL, ARG_NOMINMAX
55   },
56   {
57     "degformat", &degformat,
58     "Degrees output as 'ddd', 'dmm'(default) or 'dms'", "dmm", ARGTYPE_STRING, ARG_NOMINMAX
59   },
60   {
61     "altunits", &altunits,
62     "Units for altitude (f)eet or (m)etres", "m", ARGTYPE_STRING, ARG_NOMINMAX
63   },
64   {
65     "splitoutput", &split_output,
66     "Write each waypoint in a separate file", NULL, ARGTYPE_BOOL, ARG_NOMINMAX
67   },
68 
69   ARG_TERMINATOR
70 };
71 
72 
73 
74 static void
wr_init(const char * fname)75 wr_init(const char *fname)
76 {
77   waypoint_count = 0;
78   output_name = xstrdup(fname);
79   if (!split_output) {
80     file_out = gbfopen(fname, "w", MYNAME);
81   }
82   mkshort_handle = mkshort_new_handle();
83 }
84 
85 static void
wr_deinit(void)86 wr_deinit(void)
87 {
88   if (!split_output) {
89     gbfclose(file_out);
90   }
91   mkshort_del_handle(&mkshort_handle);
92   xfree(output_name);
93 }
94 
95 static void
text_disp(const waypoint * wpt)96 text_disp(const waypoint *wpt)
97 {
98   int latint, lonint;
99   char tbuf[1024];
100   time_t tm = wpt->creation_time;
101   gbint32 utmz;
102   double utme, utmn;
103   char utmzc;
104   char *tmpout1, *tmpout2;
105   char *altout;
106   fs_xml *fs_gpx;
107 
108   waypoint_count++;
109 
110   if (split_output) {
111     char *thisfname;
112     xasprintf(&thisfname, "%s%d", output_name, waypoint_count);
113     file_out = gbfopen(thisfname, "w", MYNAME);
114   }
115 
116   lonint = abs((int) wpt->longitude);
117   latint = abs((int) wpt->latitude);
118 
119   GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude,
120                            &utme, &utmn, &utmz, &utmzc);
121 
122   if (tm == 0) {
123     tm = time(NULL);
124   }
125   strftime(tbuf, sizeof(tbuf), "%d-%b-%Y", localtime(&tm));
126 
127   tmpout1 = pretty_deg_format(wpt->latitude, wpt->longitude, degformat[2], " ", 0);
128   if (wpt->altitude != unknown_alt) {
129     xasprintf(&altout, " alt:%d", (int)((altunits[0]=='f')?METERS_TO_FEET(wpt->altitude):wpt->altitude));
130   } else {
131     altout = "";
132   }
133   xasprintf(&tmpout2, "%s (%d%c %6.0f %7.0f)%s", tmpout1, utmz, utmzc, utme, utmn, altout);
134   gbfprintf(file_out, "%-16s  %59s\n",
135             (global_opts.synthesize_shortnames) ? mkshort_from_wpt(mkshort_handle, wpt) : wpt->shortname,
136             tmpout2);
137   xfree(tmpout2);
138   xfree(tmpout1);
139   if (altout[0]) {
140     xfree(altout);
141   }
142 
143 
144   if (strcmp(wpt->description, wpt->shortname)) {
145     gbfprintf(file_out, "%s", wpt->description);
146     if (wpt->gc_data->placer) {
147       gbfprintf(file_out, " by %s", wpt->gc_data->placer);
148     }
149   }
150   if (wpt->gc_data->terr) {
151     gbfprintf(file_out, " - %s / %s - (%d%s / %d%s)\n",
152               gs_get_cachetype(wpt->gc_data->type), gs_get_container(wpt->gc_data->container),
153               (int)(wpt->gc_data->diff / 10), (wpt->gc_data->diff%10)?".5":"",
154               (int)(wpt->gc_data->terr / 10), (wpt->gc_data->terr%10)?".5":"");
155     if (wpt->gc_data->desc_short.utfstring) {
156       char *stripped_html = strip_html(&wpt->gc_data->desc_short);
157       gbfprintf(file_out, "\n%s\n", stripped_html);
158       xfree(stripped_html);
159     }
160     if (wpt->gc_data->desc_long.utfstring) {
161       char *stripped_html = strip_html(&wpt->gc_data->desc_long);
162       gbfprintf(file_out, "\n%s\n", stripped_html);
163       xfree(stripped_html);
164     }
165     if (wpt->gc_data->hint) {
166       char *hint = NULL;
167       if (txt_encrypt) {
168         hint = rot13(wpt->gc_data->hint);
169       } else {
170         hint = xstrdup(wpt->gc_data->hint);
171       }
172       gbfprintf(file_out, "\nHint: %s\n", hint);
173       xfree(hint);
174     }
175   } else if (wpt->notes && (!wpt->description || strcmp(wpt->notes,wpt->description))) {
176     gbfprintf(file_out, "\n%s\n", wpt->notes);
177   }
178 
179   fs_gpx = NULL;
180   if (includelogs) {
181     fs_gpx = (fs_xml *)fs_chain_find(wpt->fs, FS_GPX);
182   }
183 
184   if (fs_gpx && fs_gpx->tag) {
185     xml_tag *root = fs_gpx->tag;
186     xml_tag *curlog = NULL;
187     xml_tag *logpart = NULL;
188     curlog = xml_findfirst(root, "groundspeak:log");
189     while (curlog) {
190       time_t logtime = 0;
191       struct tm *logtm = NULL;
192       gbfprintf(file_out, "\n");
193 
194       logpart = xml_findfirst(curlog, "groundspeak:type");
195       if (logpart) {
196         gbfprintf(file_out, "%s by ", logpart->cdata);
197       }
198 
199       logpart = xml_findfirst(curlog, "groundspeak:finder");
200       if (logpart) {
201         gbfprintf(file_out, "%s on ", logpart->cdata);
202       }
203 
204       logpart = xml_findfirst(curlog, "groundspeak:date");
205       if (logpart) {
206         logtime = xml_parse_time(logpart->cdata, NULL);
207         logtm = localtime(&logtime);
208         if (logtm) {
209           gbfprintf(file_out,
210                     "%4.4d-%2.2d-%2.2d\n",
211                     logtm->tm_year+1900,
212                     logtm->tm_mon+1,
213                     logtm->tm_mday);
214         }
215       }
216 
217       logpart = xml_findfirst(curlog, "groundspeak:log_wpt");
218       if (logpart) {
219         char *coordstr = NULL;
220         float lat = 0;
221         float lon = 0;
222         coordstr = xml_attribute(logpart, "lat");
223         if (coordstr) {
224           lat = atof(coordstr);
225         }
226         coordstr = xml_attribute(logpart, "lon");
227         if (coordstr) {
228           lon = atof(coordstr);
229         }
230         coordstr = pretty_deg_format(lat, lon, degformat[2], " ", 0);
231         gbfprintf(file_out, "%s\n", coordstr);
232         xfree(coordstr);
233       }
234 
235       logpart = xml_findfirst(curlog, "groundspeak:text");
236       if (logpart) {
237         char *encstr = NULL;
238         char *s = NULL;
239         int encoded = 0;
240         encstr = xml_attribute(logpart, "encoded");
241         encoded = (toupper(encstr[0]) != 'F');
242 
243         if (txt_encrypt && encoded) {
244           s = rot13(logpart->cdata);
245         } else {
246           s = xstrdup(logpart->cdata);
247         }
248 
249         gbfprintf(file_out, "%s", s);
250         xfree(s);
251       }
252 
253       gbfprintf(file_out, "\n");
254       curlog = xml_findnext(root, curlog, "groundspeak:log");
255     }
256   }
257   if (! suppresssep) {
258     gbfprintf(file_out, "\n-----------------------------------------------------------------------------\n");
259   } else {
260     gbfprintf(file_out, "\n");
261   }
262 
263   if (split_output) {
264     gbfclose(file_out);
265     file_out = NULL;
266   }
267 }
268 
269 static void
data_write(void)270 data_write(void)
271 {
272   if (! suppresssep && !split_output) {
273     gbfprintf(file_out, "-----------------------------------------------------------------------------\n");
274   }
275   setshort_length(mkshort_handle, 6);
276   waypt_disp_all(text_disp);
277 }
278 
279 
280 ff_vecs_t text_vecs = {
281   ff_type_file,
282   { ff_cap_write, ff_cap_none, ff_cap_none},
283   NULL,
284   wr_init,
285   NULL,
286   wr_deinit,
287   NULL,
288   data_write,
289   NULL,
290   text_args,
291   CET_CHARSET_ASCII, 0	/* CET-REVIEW */
292 
293 };
294