aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--load-git.c57
-rw-r--r--qthelper.cpp30
-rw-r--r--qthelperfromc.h2
3 files changed, 88 insertions, 1 deletions
diff --git a/load-git.c b/load-git.c
index 6942b6a41..7cb6c7a0a 100644
--- a/load-git.c
+++ b/load-git.c
@@ -17,9 +17,18 @@
#include "device.h"
#include "membuffer.h"
#include "git-access.h"
+#include "qthelperfromc.h"
const char *saved_git_id = NULL;
+struct picture_entry_list {
+ void *data;
+ int len;
+ const char *hash;
+ struct picture_entry_list *next;
+};
+struct picture_entry_list *pel = NULL;
+
struct keyword_action {
const char *keyword;
void (*fn)(char *, struct membuffer *, void *);
@@ -27,6 +36,21 @@ struct keyword_action {
#define ARRAY_SIZE(array) (sizeof(array)/sizeof(array[0]))
extern degrees_t parse_degrees(char *buf, char **end);
+git_blob *git_tree_entry_blob(git_repository *repo, const git_tree_entry *entry);
+
+static void save_picture_from_git(struct picture *picture)
+{
+ struct picture_entry_list *pic_entry = pel;
+
+ while (pic_entry) {
+ if (same_string(pic_entry->hash, picture->hash)) {
+ savePictureLocal(picture, pic_entry->data, pic_entry->len);
+ return;
+ }
+ pic_entry = pic_entry->next;
+ }
+ fprintf(stderr, "didn't find picture entry for %s\n", picture->filename);
+}
static char *get_utf8(struct membuffer *b)
{
@@ -1069,6 +1093,18 @@ static void finish_active_dive(void)
struct dive *dive = active_dive;
if (dive) {
+ /* check if we need to save pictures */
+ FOR_EACH_PICTURE(dive) {
+ if (!picture_exists(picture))
+ save_picture_from_git(picture);
+ }
+ /* free any memory we allocated to track pictures */
+ while (pel) {
+ free(pel->data);
+ void *lastone = pel;
+ pel = pel->next;
+ free(lastone);
+ }
active_dive = NULL;
record_dive(dive);
}
@@ -1420,6 +1456,23 @@ static int parse_settings_entry(git_repository *repo, const git_tree_entry *entr
return 0;
}
+static int parse_picture_file(git_repository *repo, const git_tree_entry *entry, const char *name)
+{
+ /* remember the picture data so we can handle it when all dive data has been loaded
+ * the name of the git file is PIC-<hash> */
+ git_blob *blob = git_tree_entry_blob(repo, entry);
+ const void *rawdata = git_blob_rawcontent(blob);
+ int len = git_blob_rawsize(blob);
+ struct picture_entry_list *new_pel = malloc(sizeof(struct picture_entry_list));
+ new_pel->next = pel;
+ pel = new_pel;
+ pel->data = malloc(len);
+ memcpy(pel->data, rawdata, len);
+ pel->len = len;
+ pel->hash = strdup(name + 4);
+ git_blob_free(blob);
+}
+
static int parse_picture_entry(git_repository *repo, const git_tree_entry *entry, const char *name)
{
git_blob *blob;
@@ -1480,6 +1533,10 @@ static int walk_tree_file(const char *root, const git_tree_entry *entry, git_rep
if (!strcmp(name, "00-Subsurface"))
return parse_settings_entry(repo, entry);
break;
+ case 'P':
+ if (dive && !strncmp(name, "PIC-", 4))
+ return parse_picture_file(repo, entry, name);
+ break;
}
report_error("Unknown file %s%s (%p %p)", root, name, dive, trip);
return GIT_WALK_SKIP;
diff --git a/qthelper.cpp b/qthelper.cpp
index 3f904d6f1..abf8641ae 100644
--- a/qthelper.cpp
+++ b/qthelper.cpp
@@ -377,7 +377,8 @@ extern "C" void copy_image_and_overwrite(const char *cfileName, const char *cnew
QFile file(newName);
if (file.exists())
file.remove();
- QFile::copy(fileName, newName);
+ if (!QFile::copy(fileName, newName))
+ qDebug() << "copy of" << fileName << "to" << newName << "failed";
}
extern "C" bool string_sequence_contains(const char *string_sequence, const char *text)
@@ -887,6 +888,33 @@ extern "C" const char *local_file_path(struct picture *picture)
return strdup(qPrintable(localFileName));
}
+extern "C" bool picture_exists(struct picture *picture)
+{
+ QString localFilename = fileFromHash(picture->hash);
+ QByteArray hash = hashFile(localFilename);
+ return same_string(hash.toHex().data(), picture->hash);
+}
+
+/* when we get a picture from git storage (local or remote) and can't find the picture
+ * based on its hash, we create a local copy with the hash as filename and the appropriate
+ * suffix */
+extern "C" void savePictureLocal(struct picture *picture, const char *data, int len)
+{
+ QString dirname(system_default_directory());
+ dirname += "/picturedata/";
+ QDir localPictureDir(dirname);
+ localPictureDir.mkpath(dirname);
+ QString suffix(picture->filename);
+ suffix.replace(QRegularExpression(".*\\."), "");
+ QString filename(dirname + picture->hash + "." + suffix);
+ QSaveFile out(filename);
+ if (out.open(QIODevice::WriteOnly)) {
+ out.write(data, len);
+ out.commit();
+ add_hash(filename, QByteArray::fromHex(picture->hash));
+ }
+}
+
extern "C" void picture_load_exif_data(struct picture *p)
{
EXIFInfo exif;
diff --git a/qthelperfromc.h b/qthelperfromc.h
index 6e8d92b9f..9a5e9551a 100644
--- a/qthelperfromc.h
+++ b/qthelperfromc.h
@@ -9,6 +9,8 @@ void subsurface_mkdir(const char *dir);
char *get_file_name(const char *fileName);
void copy_image_and_overwrite(const char *cfileName, const char *cnewName);
char *hashstring(char *filename);
+bool picture_exists(struct picture *picture);
const char *local_file_path(struct picture *picture);
+void savePictureLocal(struct picture *picture, const char *data, int len);
#endif // QTHELPERFROMC_H