diff options
-rw-r--r-- | load-git.c | 57 | ||||
-rw-r--r-- | qthelper.cpp | 30 | ||||
-rw-r--r-- | qthelperfromc.h | 2 |
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 |