summaryrefslogtreecommitdiffstats
path: root/load-git.c
diff options
context:
space:
mode:
Diffstat (limited to 'load-git.c')
-rw-r--r--load-git.c129
1 files changed, 117 insertions, 12 deletions
diff --git a/load-git.c b/load-git.c
index 1cdb44cff..d8052a550 100644
--- a/load-git.c
+++ b/load-git.c
@@ -10,6 +10,8 @@
#include <fcntl.h>
#include <git2.h>
+#include "gettext.h"
+
#include "dive.h"
#include "device.h"
#include "membuffer.h"
@@ -23,13 +25,6 @@ struct keyword_action {
#define ARRAY_SIZE(array) (sizeof(array)/sizeof(array[0]))
extern degrees_t parse_degrees(char *buf, char **end);
-static void parse_dive_gps(char *line, struct membuffer *str, void *_dive)
-{
- struct dive *dive = _dive;
-
- dive->latitude = parse_degrees(line, &line);
- dive->longitude = parse_degrees(line, &line);
-}
static char *get_utf8(struct membuffer *b)
{
@@ -145,8 +140,59 @@ static int get_index(const char *line)
static int get_hex(const char *line)
{ return strtoul(line, NULL, 16); }
+/* this is in qthelper.cpp, so including the .h file is a pain */
+extern const char *printGPSCoords(int lat, int lon);
+
+static void parse_dive_gps(char *line, struct membuffer *str, void *_dive)
+{
+ uint32_t uuid;
+ degrees_t latitude = parse_degrees(line, &line);
+ degrees_t longitude = parse_degrees(line, &line);
+ struct dive *dive = _dive;
+ struct dive_site *ds = get_dive_site_for_dive(dive);
+ if (!ds) {
+ uuid = get_dive_site_uuid_by_gps(latitude, longitude, NULL);
+ if (!uuid)
+ uuid = create_dive_site_with_gps("", latitude, longitude);
+ dive->dive_site_uuid = uuid;
+ } else {
+ if (dive_site_has_gps_location(ds) &&
+ (ds->latitude.udeg != latitude.udeg || ds->longitude.udeg != longitude.udeg)) {
+ // we have a dive site that already has GPS coordinates
+ ds->notes = add_to_string(ds->notes, translate("gettextFromC", "multiple gps locations for this dive site; also %s\n"),
+ printGPSCoords(latitude.udeg, longitude.udeg));
+ }
+ ds->latitude = latitude;
+ ds->longitude = longitude;
+ }
+
+}
+
static void parse_dive_location(char *line, struct membuffer *str, void *_dive)
-{ struct dive *dive = _dive; dive->location = get_utf8(str); }
+{
+ uint32_t uuid;
+ char *name = get_utf8(str);
+ struct dive *dive = _dive;
+ struct dive_site *ds = get_dive_site_for_dive(dive);
+ fprintf(stderr, "looking for a site named {%s} ", name);
+ if (!ds) {
+ uuid = get_dive_site_uuid_by_name(name, NULL);
+ if (!uuid) { fprintf(stderr, "found none, creating\n");
+ uuid = create_dive_site(name);
+ } else { fprintf(stderr, "found one with uuid %8x\n", uuid); }
+ dive->dive_site_uuid = uuid;
+ } else {
+ // we already had a dive site linked to the dive
+ fprintf(stderr, "dive had site with uuid %8x and name {%s}\n", ds->uuid, ds->name);
+ if (same_string(ds->name, "")) {
+ ds->name = name;
+ } else {
+ // and that dive site had a name. that's weird - if our name is different, add it to the notes
+ if (!same_string(ds->name, name))
+ ds->notes = add_to_string(ds->notes, translate("gettextFromC", "additional name for site: %s\n"), name);
+ }
+ }
+}
static void parse_dive_divemaster(char *line, struct membuffer *str, void *_dive)
{ struct dive *dive = _dive; dive->divemaster = get_utf8(str); }
@@ -160,6 +206,9 @@ static void parse_dive_suit(char *line, struct membuffer *str, void *_dive)
static void parse_dive_notes(char *line, struct membuffer *str, void *_dive)
{ struct dive *dive = _dive; dive->notes = get_utf8(str); }
+static void parse_dive_divesiteid(char *line, struct membuffer *str, void *_dive)
+{ struct dive *dive = _dive; dive->dive_site_uuid = get_hex(line); }
+
/*
* We can have multiple tags in the membuffer. They are separated by
* NUL bytes.
@@ -205,6 +254,24 @@ static void parse_dive_visibility(char *line, struct membuffer *str, void *_dive
static void parse_dive_notrip(char *line, struct membuffer *str, void *_dive)
{ struct dive *dive = _dive; dive->tripflag = NO_TRIP; }
+static void parse_site_description(char *line, struct membuffer *str, void *_ds)
+{ struct dive_site *ds = _ds; ds->description = strdup(mb_cstring(str)); }
+
+static void parse_site_name(char *line, struct membuffer *str, void *_ds)
+{ struct dive_site *ds = _ds; ds->name = strdup(mb_cstring(str)); }
+
+static void parse_site_notes(char *line, struct membuffer *str, void *_ds)
+{ struct dive_site *ds = _ds; ds->notes = strdup(mb_cstring(str)); }
+
+extern degrees_t parse_degrees(char *buf, char **end);
+static void parse_site_gps(char *line, struct membuffer *str, void *_ds)
+{
+ struct dive_site *ds = _ds;
+
+ ds->latitude = parse_degrees(line, &line);
+ ds->longitude = parse_degrees(line, &line);
+}
+
/* Parse key=val parts of samples and cylinders etc */
static char *parse_keyvalue_entry(void (*fn)(void *, const char *, const char *), void *fndata, char *line)
{
@@ -672,7 +739,7 @@ static void parse_settings_userid(char *line, struct membuffer *str, void *_unus
* *can* do some day. And if we do change the version, this warning will show if
* you read with a version of subsurface that doesn't know about it.
*/
-#define VERSION 2
+#define VERSION 3
static void parse_settings_version(char *line, struct membuffer *str, void *_unused)
{
int version = atoi(line);
@@ -761,6 +828,12 @@ static void parse_picture_gps(char *line, struct membuffer *str, void *_pic)
pic->longitude = parse_degrees(line, &line);
}
+static void parse_picture_hash(char *line, struct membuffer *str, void *_pic)
+{
+ struct picture *pic = _pic;
+ pic->hash = get_utf8(str);
+}
+
/* These need to be sorted! */
struct keyword_action dc_action[] = {
#undef D
@@ -783,7 +856,7 @@ static void divecomputer_parser(char *line, struct membuffer *str, void *_dc)
struct keyword_action dive_action[] = {
#undef D
#define D(x) { #x, parse_dive_ ## x }
- D(airtemp), D(buddy), D(cylinder), D(divemaster), D(duration),
+ D(airtemp), D(buddy), D(cylinder), D(divemaster), D(divesiteid), D(duration),
D(gps), D(location), D(notes), D(notrip), D(rating), D(suit),
D(tags), D(visibility), D(watertemp), D(weightsystem)
};
@@ -794,6 +867,18 @@ static void dive_parser(char *line, struct membuffer *str, void *_dive)
}
/* These need to be sorted! */
+struct keyword_action site_action[] = {
+#undef D
+#define D(x) { #x, parse_site_ ## x }
+ D(description), D(gps), D(name), D(notes)
+};
+
+static void site_parser(char *line, struct membuffer *str, void *_ds)
+{
+ match_action(line, str, _ds, site_action, ARRAY_SIZE(site_action));
+}
+
+/* These need to be sorted! */
struct keyword_action trip_action[] = {
#undef D
#define D(x) { #x, parse_trip_ ## x }
@@ -821,7 +906,7 @@ static void settings_parser(char *line, struct membuffer *str, void *_unused)
static struct keyword_action picture_action[] = {
#undef D
#define D(x) { #x, parse_picture_ ## x }
- D(filename), D(gps)
+ D(filename), D(gps), D(hash)
};
static void picture_parser(char *line, struct membuffer *str, void *_pic)
@@ -1190,6 +1275,9 @@ static int walk_tree_directory(const char *root, const git_tree_entry *entry)
if (!strcmp(name, "Pictures"))
return picture_directory(root, name);
+ if (!strcmp(name, "01-Divesites"))
+ return GIT_WALK_OK;
+
while (isdigit(c = name[digits]))
digits++;
@@ -1284,6 +1372,20 @@ static int parse_dive_entry(git_repository *repo, const git_tree_entry *entry, c
return 0;
}
+static int parse_site_entry(git_repository *repo, const git_tree_entry *entry, const char *suffix)
+{
+ if (*suffix == '\0')
+ return report_error("Dive site without uuid");
+ struct dive_site *ds = alloc_dive_site();
+ ds->uuid = strtol(suffix, NULL, 16);
+ git_blob *blob = git_tree_entry_blob(repo, entry);
+ if (!blob)
+ return report_error("Unable to read dive site file");
+ for_each_line(blob, site_parser, ds);
+ git_blob_free(blob);
+ return 0;
+}
+
static int parse_trip_entry(git_repository *repo, const git_tree_entry *entry)
{
git_blob *blob = git_tree_entry_blob(repo, entry);
@@ -1343,7 +1445,6 @@ static int walk_tree_file(const char *root, const git_tree_entry *entry, git_rep
struct dive *dive = active_dive;
dive_trip_t *trip = active_trip;
const char *name = git_tree_entry_name(entry);
-
switch (*name) {
/* Picture file? They are saved as time offsets in the dive */
case '-': case '+':
@@ -1356,6 +1457,10 @@ static int walk_tree_file(const char *root, const git_tree_entry *entry, git_rep
if (dive && !strncmp(name, "Dive", 4))
return parse_dive_entry(repo, entry, name+4);
break;
+ case 'S':
+ if (!strncmp(name, "Site", 4))
+ return parse_site_entry(repo, entry, name + 5);
+ break;
case '0':
if (trip && !strcmp(name, "00-Trip"))
return parse_trip_entry(repo, entry);