Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Copy, move and delete thumbnails #29

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 23 additions & 18 deletions src/base/fm-thumbnail-loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,6 @@
static gboolean backend_loaded = FALSE;
static FmThumbnailLoaderBackend backend = {NULL};

typedef enum
{
LOAD_NORMAL = 1 << 0, /* need to load normal thumbnail */
LOAD_LARGE = 1 << 1, /* need to load large thumbnail */
GENERATE_NORMAL = 1 << 2, /* need to regenerated normal thumbnail */
GENERATE_LARGE = 1 << 3, /* need to regenerated large thumbnail */
}ThumbnailTaskFlags;

typedef struct _ThumbnailTask ThumbnailTask;
struct _ThumbnailTask
{
Expand Down Expand Up @@ -427,14 +419,33 @@ static void load_thumbnails(ThumbnailTask* task)
return;
}

/* dst_normal and dst_large should be already allocated and contain the name of a thumbnail file */
void get_thumbnail_paths( gchar* src_uri, gchar* dst_normal, gchar* dst_large, ThumbnailTaskFlags flags)
{
GChecksum* sum = g_checksum_new(G_CHECKSUM_MD5);
g_checksum_update(sum, (guchar*)src_uri, -1);
const char* md5;
md5 = g_checksum_get_string(sum); /* md5 sum of the URI */

if ( (flags & LOAD_NORMAL) || (flags & GENERATE_NORMAL) ){
gchar* basename = strrchr(dst_normal, '/') + 1;
memcpy( basename, md5, strlen(md5) );
}

if ( (flags & LOAD_LARGE) || (flags & GENERATE_LARGE) ){
gchar* basename = strrchr(dst_large, '/') + 1;
memcpy( basename, md5, strlen(md5) );
}
}

/* in thread */
static gpointer load_thumbnail_thread(gpointer user_data)
{
ThumbnailTask* task;
GChecksum* sum = g_checksum_new(G_CHECKSUM_MD5);
gchar* normal_path = g_build_filename(thumb_dir, "normal/00000000000000000000000000000000.png", NULL);
gchar* normal_path = g_build_filename(thumb_dir, thumbnails_normal_path, thumbnails_empty_basename, NULL);
gchar* normal_basename = strrchr(normal_path, '/') + 1;
gchar* large_path = g_build_filename(thumb_dir, "large/00000000000000000000000000000000.png", NULL);
gchar* large_path = g_build_filename(thumb_dir, thumbnails_large_path, thumbnails_empty_basename, NULL);
gchar* large_basename = strrchr(large_path, '/') + 1;

/* ensure thumbnail directories exists */
Expand All @@ -453,7 +464,6 @@ static gpointer load_thumbnail_thread(gpointer user_data)
if(G_LIKELY(task))
{
char* uri;
const char* md5;
GList *reql;

for (reql = task->requests; reql; reql = reql->next)
Expand All @@ -466,20 +476,15 @@ static gpointer load_thumbnail_thread(gpointer user_data)
g_mutex_unlock(lock_ptr);
uri = fm_path_to_uri(fm_file_info_get_path(task->fi));

/* generate filename for the thumbnail */
g_checksum_update(sum, (guchar*)uri, -1);
md5 = g_checksum_get_string(sum); /* md5 sum of the URI */

task->uri = uri;

get_thumbnail_paths( (gchar*)uri, normal_path, large_path, task->flags );
if (task->flags & LOAD_NORMAL)
{
memcpy( normal_basename, md5, 32 );
task->normal_path = normal_path;
}
if (task->flags & LOAD_LARGE)
{
memcpy( large_basename, md5, 32 );
task->large_path = large_path;
}
/* FIXME: support fail/<PRG>/<MD5>.png to skip creation */
Expand Down Expand Up @@ -746,7 +751,7 @@ guint fm_thumbnail_loader_get_size(FmThumbnailLoader* req)
/* in main loop */
void _fm_thumbnail_loader_init()
{
thumb_dir = g_build_filename(fm_get_home_dir(), ".thumbnails", NULL);
thumb_dir = g_build_filename(fm_get_home_dir(), thumbnails_path, NULL);
hash = g_hash_table_new((GHashFunc)fm_path_hash, (GEqualFunc)fm_path_equal);
#if !GLIB_CHECK_VERSION(2, 32, 0)
lock_ptr = g_mutex_new();
Expand Down
14 changes: 14 additions & 0 deletions src/base/fm-thumbnail-loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,20 @@ struct _FmThumbnailLoaderBackend {
gboolean fm_thumbnail_loader_set_backend(FmThumbnailLoaderBackend* _backend)
__attribute__((warn_unused_result,nonnull(1)));

typedef enum
{
LOAD_NORMAL = 1 << 0, /* need to load normal thumbnail */
LOAD_LARGE = 1 << 1, /* need to load large thumbnail */
GENERATE_NORMAL = 1 << 2, /* need to regenerated normal thumbnail */
GENERATE_LARGE = 1 << 3, /* need to regenerated large thumbnail */
}ThumbnailTaskFlags;

static gchar thumbnails_path[] = ".thumbnails";
static gchar thumbnails_normal_path[] = "normal";
static gchar thumbnails_large_path[] = "large";
static gchar thumbnails_empty_basename[] = "00000000000000000000000000000000.png";
void get_thumbnail_paths( gchar* src_uri, gchar* dst_normal, gchar* dst_large, ThumbnailTaskFlags flags);

G_END_DECLS

#endif /* __FM_THUMBNAIL_LOADER_H__ */
34 changes: 34 additions & 0 deletions src/job/fm-file-ops-job-change-attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@

#include "fm-file-ops-job-change-attr.h"
#include "fm-folder.h"
#include "fm-utils.h"
#include "../base/fm-thumbnail-loader.h"

static const char query[] = G_FILE_ATTRIBUTE_STANDARD_TYPE","
G_FILE_ATTRIBUTE_STANDARD_NAME","
Expand Down Expand Up @@ -153,6 +155,38 @@ static gboolean _fm_file_ops_job_change_attr_file(FmFileOpsJob* job, GFile* gf,
}
else
{
/* move thumbnail, if existing */
if(renamed != NULL && g_file_is_native(gf))
{
gchar* thumb_dir = g_build_filename(fm_get_home_dir(), thumbnails_path, NULL);
gchar* src_path_normal = g_build_filename(thumb_dir, thumbnails_normal_path, thumbnails_empty_basename, NULL);
gchar* src_path_large = g_build_filename(thumb_dir, thumbnails_large_path, thumbnails_empty_basename, NULL);
gchar* dest_path_normal = g_build_filename(thumb_dir, thumbnails_normal_path, thumbnails_empty_basename, NULL);
gchar* dest_path_large = g_build_filename(thumb_dir, thumbnails_large_path, thumbnails_empty_basename, NULL);
gchar* src_uri = g_file_get_uri(gf);
gchar* dest_uri = g_file_get_uri(renamed);
ThumbnailTaskFlags flags = LOAD_NORMAL | LOAD_LARGE;
get_thumbnail_paths( src_uri, src_path_normal, src_path_large, flags);
get_thumbnail_paths( dest_uri, dest_path_normal, dest_path_large, flags);
GFile* src_normal = g_file_new_for_path(src_path_normal);
GFile* src_large = g_file_new_for_path(src_path_large);
GFile* dest_normal = g_file_new_for_path(dest_path_normal);
GFile* dest_large = g_file_new_for_path(dest_path_large);
g_file_copy (src_normal, dest_normal, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, NULL);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose this should be not copying operation but moving one instead. Thank you.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, it's fixed now

g_file_copy (src_large, dest_large, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, NULL);
g_free(thumb_dir);
g_free(src_path_normal);
g_free(src_path_large);
g_free(dest_path_normal);
g_free(dest_path_large);
g_free(src_uri);
g_free(dest_uri);
g_object_unref(src_normal);
g_object_unref(src_large);
g_object_unref(dest_normal);
g_object_unref(dest_large);
}

g_object_unref(renamed);
changed = TRUE;
}
Expand Down
24 changes: 24 additions & 0 deletions src/job/fm-file-ops-job-delete.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
#include "fm-config.h"
#include "fm-file.h"
#include <glib/gi18n-lib.h>
#include "fm-utils.h"
#include "../base/fm-thumbnail-loader.h"

static const char query[] = G_FILE_ATTRIBUTE_STANDARD_TYPE","
G_FILE_ATTRIBUTE_STANDARD_NAME","
Expand Down Expand Up @@ -269,6 +271,28 @@ gboolean _fm_file_ops_job_delete_run(FmFileOpsJob* job)
src = fm_path_to_gfile(path);

ret = _fm_file_ops_job_delete_file(fmjob, src, NULL, parent_folder, FALSE);

/* delete thumbnails, if existing */
if(ret == TRUE && g_file_is_native(src))
{
gchar* thumb_dir = g_build_filename(fm_get_home_dir(), thumbnails_path, NULL);
gchar* src_path_normal = g_build_filename(thumb_dir, thumbnails_normal_path, thumbnails_empty_basename, NULL);
gchar* src_path_large = g_build_filename(thumb_dir, thumbnails_large_path, thumbnails_empty_basename, NULL);
gchar* src_uri = g_file_get_uri(src);
ThumbnailTaskFlags flags = LOAD_NORMAL | LOAD_LARGE;
get_thumbnail_paths( src_uri, src_path_normal, src_path_large, flags);
GFile* src_normal = g_file_new_for_path(src_path_normal);
GFile* src_large = g_file_new_for_path(src_path_large);
g_file_delete (src_normal, NULL, NULL);
g_file_delete (src_large, NULL, NULL);
g_free(thumb_dir);
g_free(src_path_normal);
g_free(src_path_large);
g_free(src_uri);
g_object_unref(src_normal);
g_object_unref(src_large);
}

g_object_unref(src);
}
if (parent_folder)
Expand Down
67 changes: 67 additions & 0 deletions src/job/fm-file-ops-job-xfer.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <unistd.h>
#include "fm-utils.h"
#include <glib/gi18n-lib.h>
#include "../base/fm-thumbnail-loader.h"

static const char query[]=
G_FILE_ATTRIBUTE_STANDARD_TYPE","
Expand Down Expand Up @@ -746,6 +747,39 @@ gboolean _fm_file_ops_job_copy_run(FmFileOpsJob* job)
g_free(tmp_basename);
if(!_fm_file_ops_job_copy_file(job, src, NULL, dest, NULL, df))
ret = FALSE;

/* copy thumbnails, if existing */
if(ret == TRUE && g_file_is_native(src) && g_file_is_native(dest))
{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would consider to honor "thumbnail_local" configuration variable in regards of decision if we have to create a copy for a file thumbnail.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, done

gchar* thumb_dir = g_build_filename(fm_get_home_dir(), thumbnails_path, NULL);
gchar* src_path_normal = g_build_filename(thumb_dir, thumbnails_normal_path, thumbnails_empty_basename, NULL);
gchar* src_path_large = g_build_filename(thumb_dir, thumbnails_large_path, thumbnails_empty_basename, NULL);
gchar* src_uri = g_file_get_uri(src);
gchar* dest_path_normal = g_build_filename(thumb_dir, thumbnails_normal_path, thumbnails_empty_basename, NULL);
gchar* dest_path_large = g_build_filename(thumb_dir, thumbnails_large_path, thumbnails_empty_basename, NULL);
gchar* dest_uri = g_file_get_uri(dest);
ThumbnailTaskFlags flags = LOAD_NORMAL | LOAD_LARGE;
get_thumbnail_paths( src_uri, src_path_normal, src_path_large, flags);
get_thumbnail_paths( dest_uri, dest_path_normal, dest_path_large, flags);
GFile* src_normal = g_file_new_for_path(src_path_normal);
GFile* src_large = g_file_new_for_path(src_path_large);
GFile* dest_normal = g_file_new_for_path(dest_path_normal);
GFile* dest_large = g_file_new_for_path(dest_path_large);
g_file_copy (src_normal, dest_normal, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, NULL);
g_file_copy (src_large, dest_large, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, NULL);
g_free(thumb_dir);
g_free(src_path_normal);
g_free(src_path_large);
g_free(src_uri);
g_free(dest_path_normal);
g_free(dest_path_large);
g_free(dest_uri);
g_object_unref(src_normal);
g_object_unref(src_large);
g_object_unref(dest_normal);
g_object_unref(dest_large);
}

g_object_unref(src);
g_object_unref(dest);
}
Expand Down Expand Up @@ -870,6 +904,39 @@ gboolean _fm_file_ops_job_move_run(FmFileOpsJob* job)

if(!_fm_file_ops_job_move_file(job, src, NULL, dest, path, sf, df))
ret = FALSE;

/* move thumbnails, if existing */
if(ret == TRUE && g_file_is_native(src) && g_file_is_native(dest))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about to delete thumbnail if destination file isn't native?
Also I would consider to honor "thumbnail_local" configuration variable in that regard.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok for me. Done

{
gchar* thumb_dir = g_build_filename(fm_get_home_dir(), thumbnails_path, NULL);
gchar* src_path_normal = g_build_filename(thumb_dir, thumbnails_normal_path, thumbnails_empty_basename, NULL);
gchar* src_path_large = g_build_filename(thumb_dir, thumbnails_large_path, thumbnails_empty_basename, NULL);
gchar* src_uri = g_file_get_uri(src);
gchar* dest_path_normal = g_build_filename(thumb_dir, thumbnails_normal_path, thumbnails_empty_basename, NULL);
gchar* dest_path_large = g_build_filename(thumb_dir, thumbnails_large_path, thumbnails_empty_basename, NULL);
gchar* dest_uri = g_file_get_uri(dest);
ThumbnailTaskFlags flags = LOAD_NORMAL | LOAD_LARGE;
get_thumbnail_paths( src_uri, src_path_normal, src_path_large, flags);
get_thumbnail_paths( dest_uri, dest_path_normal, dest_path_large, flags);
GFile* src_normal = g_file_new_for_path(src_path_normal);
GFile* src_large = g_file_new_for_path(src_path_large);
GFile* dest_normal = g_file_new_for_path(dest_path_normal);
GFile* dest_large = g_file_new_for_path(dest_path_large);
g_file_move (src_normal, dest_normal, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, NULL);
g_file_move (src_large, dest_large, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, NULL);
g_free(thumb_dir);
g_free(src_path_normal);
g_free(src_path_large);
g_free(src_uri);
g_free(dest_path_normal);
g_free(dest_path_large);
g_free(dest_uri);
g_object_unref(src_normal);
g_object_unref(src_large);
g_object_unref(dest_normal);
g_object_unref(dest_large);
}

g_object_unref(src);
g_object_unref(dest);

Expand Down