char * dt_history_get_items_as_string(int32_t imgid) { GList *items = NULL; const char *onoff[2] = {_("off"), _("on")}; unsigned int count = 0; sqlite3_stmt *stmt; DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "select operation, enabled, multi_name from history where imgid=?1 order by num desc", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, imgid); // collect all the entries in the history from the db while (sqlite3_step(stmt) == SQLITE_ROW) { char *name = NULL, *multi_name = NULL; const char *mn = (char*)sqlite3_column_text(stmt, 2); if(mn && *mn && g_strcmp0(mn, " ") != 0 && g_strcmp0(mn, "0") != 0) multi_name = g_strconcat(" ", sqlite3_column_text(stmt, 2), NULL); name = g_strconcat(dt_iop_get_localized_name((char*)sqlite3_column_text(stmt, 0)), multi_name?multi_name:"", " (", (sqlite3_column_int(stmt, 1)==0)?onoff[0]:onoff[1], ")", NULL); items = g_list_append(items, name); g_free(multi_name); count++; } return dt_util_glist_to_str("\n", items, count); }
char *dt_history_get_items_as_string(int32_t imgid) { GList *items = NULL; const char *onoff[2] = { _("off"), _("on") }; sqlite3_stmt *stmt; DT_DEBUG_SQLITE3_PREPARE_V2( dt_database_get(darktable.db), "SELECT operation, enabled, multi_name FROM main.history WHERE imgid=?1 ORDER BY num DESC", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, imgid); // collect all the entries in the history from the db while(sqlite3_step(stmt) == SQLITE_ROW) { char *name = NULL, *multi_name = NULL; const char *mn = (char *)sqlite3_column_text(stmt, 2); if(mn && *mn && g_strcmp0(mn, " ") != 0 && g_strcmp0(mn, "0") != 0) multi_name = g_strconcat(" ", sqlite3_column_text(stmt, 2), NULL); name = g_strconcat(dt_iop_get_localized_name((char *)sqlite3_column_text(stmt, 0)), multi_name ? multi_name : "", " (", (sqlite3_column_int(stmt, 1) == 0) ? onoff[0] : onoff[1], ")", NULL); items = g_list_append(items, name); g_free(multi_name); } sqlite3_finalize(stmt); char *result = dt_util_glist_to_str("\n", items); g_list_free_full(items, g_free); return result; }
static void _lib_filmstrip_dnd_get_callback(GtkWidget *widget, GdkDragContext *context, GtkSelectionData *selection_data, guint target_type, guint time, gpointer user_data) { dt_lib_module_t *self = (dt_lib_module_t *)user_data; dt_lib_filmstrip_t *strip = (dt_lib_filmstrip_t *)self->data; g_assert(selection_data != NULL); int mouse_over_id = strip->mouse_over_id; int count = dt_collection_get_selected_count(NULL); switch(target_type) { case DND_TARGET_IMGID: { int id = ((count == 1) ? mouse_over_id : -1); gtk_selection_data_set(selection_data, gtk_selection_data_get_target(selection_data), _DWORD, (guchar *)&id, sizeof(id)); break; } default: // return the location of the file as a last resort case DND_TARGET_URI: // TODO: add all images from the selection { if(count == 1) { gchar pathname[PATH_MAX] = { 0 }; gboolean from_cache = TRUE; dt_image_full_path(mouse_over_id, pathname, sizeof(pathname), &from_cache); gchar *uri = g_strdup_printf("file://%s", pathname); // TODO: should we add the host? gtk_selection_data_set(selection_data, gtk_selection_data_get_target(selection_data), _BYTE, (guchar *)uri, strlen(uri)); g_free(uri); } else { sqlite3_stmt *stmt; GList *images = NULL; DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "SELECT imgid FROM main.selected_images", -1, &stmt, NULL); while(sqlite3_step(stmt) == SQLITE_ROW) { int id = sqlite3_column_int(stmt, 0); gchar pathname[PATH_MAX] = { 0 }; gboolean from_cache = TRUE; dt_image_full_path(id, pathname, sizeof(pathname), &from_cache); gchar *uri = g_strdup_printf("file://%s", pathname); // TODO: should we add the host? images = g_list_append(images, uri); } sqlite3_finalize(stmt); gchar *uri_list = dt_util_glist_to_str("\r\n", images); g_list_free_full(images, g_free); gtk_selection_data_set(selection_data, gtk_selection_data_get_target(selection_data), _BYTE, (guchar *)uri_list, strlen(uri_list)); g_free(uri_list); } break; } } }
char *dt_styles_get_item_list_as_string(const char *name) { GList *items = dt_styles_get_item_list(name, FALSE, -1); if(items == NULL) return NULL; GList *names = NULL; do { dt_style_item_t *item = (dt_style_item_t *)items->data; names = g_list_append(names, g_strdup(item->name)); } while((items = g_list_next(items))); char *result = dt_util_glist_to_str("\n", names); g_list_free_full(names, g_free); g_list_free_full(items, dt_style_item_free); return result; }
char * dt_history_get_items_as_string(int32_t imgid) { GList *items = NULL; const char *onoff[2] = {_("off"), _("on")}; unsigned int count = 0; sqlite3_stmt *stmt; DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "select operation, enabled from history where imgid=?1 order by num desc", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, imgid); // collect all the entries in the history from the db while (sqlite3_step(stmt) == SQLITE_ROW) { char name[512]= {0}; g_snprintf(name,512,"%s (%s)", dt_iop_get_localized_name((char*)sqlite3_column_text(stmt, 0)), (sqlite3_column_int(stmt, 1)==0)?onoff[0]:onoff[1]); items = g_list_append(items, g_strdup(name)); count++; } return dt_util_glist_to_str("\n", items, count); }
char * dt_styles_get_item_list_as_string(const char *name) { GList *items = dt_styles_get_item_list(name, FALSE, -1); if (items) { GList* names = NULL; unsigned int count = 0; do { dt_style_item_t *item=(dt_style_item_t *)items->data; names = g_list_append(names, g_strdup(item->name)); g_free(item->name); g_free(item); count++; } while ((items=g_list_next(items))); return dt_util_glist_to_str("\n", names, count); } return NULL; }
static flickcurl_upload_status *_flickr_api_upload_photo(dt_storage_flickr_params_t *p, char *fname, char *caption, char *description, gint imgid) { flickcurl_upload_params *params = g_malloc0(sizeof(flickcurl_upload_params)); flickcurl_upload_status *status; params->safety_level = 1; // Defaults to safe photos params->content_type = 1; // Defaults to photo (we don't support video!) params->title = caption; params->description = description; if(imgid) { GList *tags_list = dt_tag_get_list(imgid); params->tags = dt_util_glist_to_str(",", tags_list); g_list_free_full(tags_list, g_free); } params->photo_file = fname; // fname should be the URI of temp file params->is_public = (int)p->public_perm; params->is_friend = (int)p->friend_perm; params->is_family = (int)p->family_perm; status = flickcurl_photos_upload_params(p->flickr_api->fc, params); if(!status) { fprintf(stderr, "[flickr] Something went wrong when uploading"); g_free((gchar *)params->tags); g_free(params); return NULL; } g_free((gchar *)params->tags); g_free(params); return status; }
int store (dt_imageio_module_data_t *sdata, const int imgid, dt_imageio_module_format_t *format, dt_imageio_module_data_t *fdata, const int num, const int total, const gboolean high_quality) { dt_imageio_gallery_t *d = (dt_imageio_gallery_t *)sdata; char filename[DT_MAX_PATH_LEN]= {0}; char dirname[DT_MAX_PATH_LEN]= {0}; dt_image_full_path(imgid, dirname, DT_MAX_PATH_LEN); // we're potentially called in parallel. have sequence number synchronized: dt_pthread_mutex_lock(&darktable.plugin_threadsafe); { char tmp_dir[DT_MAX_PATH_LEN]; dt_variables_expand(d->vp, d->filename, TRUE); g_strlcpy(tmp_dir, dt_variables_get_result(d->vp), DT_MAX_PATH_LEN); // if filenamepattern is a directory just let att ${FILE_NAME} as default.. if ( g_file_test(tmp_dir, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR) || ((d->filename+strlen(d->filename)-1)[0]=='/' || (d->filename+strlen(d->filename)-1)[0]=='\\') ) snprintf (d->filename+strlen(d->filename), DT_MAX_PATH_LEN-strlen(d->filename), "/$(FILE_NAME)"); // avoid braindead export which is bound to overwrite at random: if(total > 1 && !g_strrstr(d->filename, "$")) { snprintf(d->filename+strlen(d->filename), DT_MAX_PATH_LEN-strlen(d->filename), "_$(SEQUENCE)"); } gchar* fixed_path = dt_util_fix_path(d->filename); g_strlcpy(d->filename, fixed_path, DT_MAX_PATH_LEN); g_free(fixed_path); d->vp->filename = dirname; d->vp->jobcode = "export"; d->vp->imgid = imgid; d->vp->sequence = num; dt_variables_expand(d->vp, d->filename, TRUE); g_strlcpy(filename, dt_variables_get_result(d->vp), DT_MAX_PATH_LEN); g_strlcpy(dirname, filename, DT_MAX_PATH_LEN); const char *ext = format->extension(fdata); char *c = dirname + strlen(dirname); for(; c>dirname && *c != '/'; c--); if(*c == '/') *c = '\0'; if(g_mkdir_with_parents(dirname, 0755)) { fprintf(stderr, "[imageio_storage_gallery] could not create directory: `%s'!\n", dirname); dt_control_log(_("could not create directory `%s'!"), dirname); dt_pthread_mutex_unlock(&darktable.plugin_threadsafe); return 1; } // store away dir. snprintf(d->cached_dirname, DT_MAX_PATH_LEN, "%s", dirname); c = filename + strlen(filename); for(; c>filename && *c != '.' && *c != '/' ; c--); if(c <= filename || *c=='/') c = filename + strlen(filename); sprintf(c,".%s",ext); // save image to list, in order: pair_t *pair = malloc(sizeof(pair_t)); char *title = NULL, *description = NULL, *tags = NULL; GList *res; res = dt_metadata_get(imgid, "Xmp.dc.title", NULL); if(res) { title = res->data; g_list_free(res); } res = dt_metadata_get(imgid, "Xmp.dc.description", NULL); if(res) { description = res->data; g_list_free(res); } unsigned int count = 0; res = dt_metadata_get(imgid, "Xmp.dc.subject", &count); if(res) { // don't show the internal tags (darktable|...) res = g_list_first(res); GList *iter = res; while(iter) { GList *next = g_list_next(iter); if(g_str_has_prefix(iter->data, "darktable|")) { g_free(iter->data); res = g_list_delete_link(res, iter); count--; } iter = next; } tags = dt_util_glist_to_str(", ", res, count); } char relfilename[256], relthumbfilename[256]; c = filename + strlen(filename); for(; c>filename && *c != '/' ; c--); if(*c == '/') c++; if(c <= filename) c = filename; snprintf(relfilename, 256, "%s", c); snprintf(relthumbfilename, 256, "%s", relfilename); c = relthumbfilename + strlen(relthumbfilename); for(; c>relthumbfilename && *c != '.'; c--); if(c <= relthumbfilename) c = relthumbfilename + strlen(relthumbfilename); sprintf(c, "-thumb.%s", ext); char subfilename[DT_MAX_PATH_LEN], relsubfilename[256]; snprintf(subfilename, DT_MAX_PATH_LEN, "%s", d->cached_dirname); char* sc = subfilename + strlen(subfilename); sprintf(sc, "/img_%d.html", num); sprintf(relsubfilename, "img_%d.html", num); snprintf(pair->line, 4096, "\n" " <div><a class=\"dia\" rel=\"lightbox[viewer]\" title=\"%s - %s\" href=\"%s\"><span></span><img src=\"%s\" alt=\"img%d\" class=\"img\"/></a>\n" " <h1>%s</h1>\n" " %s<br/><span class=\"tags\">%s</span></div>\n", title?title:relfilename, description?description:" ", relfilename, relthumbfilename, num, title?title:" ", description?description:" ", tags?tags:" "); char next[256]; sprintf(next, "img_%d.html", (num)%total+1); char prev[256]; sprintf(prev, "img_%d.html", (num==1)?total:num-1); /* Becomes unecessary with the Lightbox image viewer overlay FILE* subfile = fopen(subfilename, "wb"); fprintf(subfile, "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n" "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n" " <head>\n" " <meta http-equiv=\"Content-type\" content=\"text/html;charset=UTF-8\" />\n" " <link rel=\"shortcut icon\" href=\"style/favicon.ico\" />\n" " <link rel=\"stylesheet\" href=\"style/style.css\" type=\"text/css\" />\n" " <title>%s</title>\n" " </head>\n" " <body>\n" " <div class=\"title\"><a href=\"index.html\">%s</a></div>\n" " <div class=\"page\">\n" " <div style=\"width: 692px; max-width: 692px; height: 10px;\">\n" " <a style=\"float: left;\" href=\"%s\"><h1>prev</h1></a>\n" " <a style=\"float: right;\"href=\"%s\"><h1>next</h1></a>\n" " </div>\n" " <a href=\"%s\"><img src=\"%s\" width=\"692\" class=\"img\"/></a>\n" " %s<br/><span class=\"tags\">%s</span></div>\n" " <p style=\"clear:both;\"></p>\n" " </div>\n" " <div class=\"footer\">\n" " created with darktable "PACKAGE_VERSION"\n" " </div>\n" " </body>\n" "</html>\n", relfilename, title?title:relfilename, prev, next, relfilename, relfilename, description?description:" ", tags?tags:" "); fclose(subfile); */ pair->pos = num; g_free(title); g_free(description); g_free(tags); d->l = g_list_insert_sorted(d->l, pair, (GCompareFunc)sort_pos); } // end of critical block dt_pthread_mutex_unlock(&darktable.plugin_threadsafe); /* export image to file */ if(dt_imageio_export(imgid, filename, format, fdata, high_quality) != 0) { fprintf(stderr, "[imageio_storage_gallery] could not export to file: `%s'!\n", filename); dt_control_log(_("could not export to file `%s'!"), filename); return 1; } /* also export thumbnail: */ // write with reduced resolution: const int max_width = fdata->max_width; const int max_height = fdata->max_height; fdata->max_width = 200; fdata->max_height = 200; // alter filename with -thumb: char *c = filename + strlen(filename); for(; c>filename && *c != '.' && *c != '/' ; c--); if(c <= filename || *c=='/') c = filename + strlen(filename); const char *ext = format->extension(fdata); sprintf(c,"-thumb.%s",ext); if(dt_imageio_export(imgid, filename, format, fdata, FALSE) != 0) { fprintf(stderr, "[imageio_storage_gallery] could not export to file: `%s'!\n", filename); dt_control_log(_("could not export to file `%s'!"), filename); return 1; } // restore for next image: fdata->max_width = max_width; fdata->max_height = max_height; printf("[export_job] exported to `%s'\n", filename); char *trunc = filename + strlen(filename) - 32; if(trunc < filename) trunc = filename; dt_control_log(_("%d/%d exported to `%s%s'"), num, total, trunc != filename ? ".." : "", trunc); return 0; }
gboolean _variable_get_value(dt_variables_params_t *params, gchar *variable, gchar *value, size_t value_len) { const gchar *file_ext = NULL; gboolean got_value = FALSE; struct tm tim; localtime_r(¶ms->data->time, &tim); const gchar *homedir = dt_loc_get_home_dir(NULL); gchar *pictures_folder = NULL; if(g_get_user_special_dir(G_USER_DIRECTORY_PICTURES) == NULL) pictures_folder = g_build_path(G_DIR_SEPARATOR_S, homedir, "Pictures", (char *)NULL); else pictures_folder = g_strdup(g_get_user_special_dir(G_USER_DIRECTORY_PICTURES)); if(params->filename) { file_ext = (g_strrstr(params->filename, ".") + 1); if(file_ext == (gchar *)1) file_ext = params->filename + strlen(params->filename); } /* image exif time */ gboolean have_exif_tm = FALSE; int exif_iso = 100; char camera_maker[64]; char camera_alias[64]; int version = 0; int stars = 0; struct tm exif_tm = { 0 }; if(params->imgid) { const dt_image_t *img = dt_image_cache_get(darktable.image_cache, params->imgid, 'r'); if(sscanf(img->exif_datetime_taken, "%d:%d:%d %d:%d:%d", &exif_tm.tm_year, &exif_tm.tm_mon, &exif_tm.tm_mday, &exif_tm.tm_hour, &exif_tm.tm_min, &exif_tm.tm_sec) == 6) { exif_tm.tm_year -= 1900; exif_tm.tm_mon--; have_exif_tm = TRUE; } exif_iso = img->exif_iso; g_strlcpy(camera_maker, img->camera_maker, sizeof(camera_maker)); g_strlcpy(camera_alias, img->camera_alias, sizeof(camera_alias)); version = img->version; stars = (img->flags & 0x7); if(stars == 6) stars = -1; dt_image_cache_read_release(darktable.image_cache, img); } else if (params->data->exif_time) { localtime_r(¶ms->data->exif_time, &exif_tm); have_exif_tm = TRUE; } if(g_strcmp0(variable, "$(YEAR)") == 0 && (got_value = TRUE)) snprintf(value, value_len, "%.4d", tim.tm_year + 1900); else if(g_strcmp0(variable, "$(MONTH)") == 0 && (got_value = TRUE)) snprintf(value, value_len, "%.2d", tim.tm_mon + 1); else if(g_strcmp0(variable, "$(DAY)") == 0 && (got_value = TRUE)) snprintf(value, value_len, "%.2d", tim.tm_mday); else if(g_strcmp0(variable, "$(HOUR)") == 0 && (got_value = TRUE)) snprintf(value, value_len, "%.2d", tim.tm_hour); else if(g_strcmp0(variable, "$(MINUTE)") == 0 && (got_value = TRUE)) snprintf(value, value_len, "%.2d", tim.tm_min); else if(g_strcmp0(variable, "$(SECOND)") == 0 && (got_value = TRUE)) snprintf(value, value_len, "%.2d", tim.tm_sec); else if(g_strcmp0(variable, "$(EXIF_YEAR)") == 0 && (got_value = TRUE)) snprintf(value, value_len, "%.4d", (have_exif_tm ? exif_tm.tm_year : tim.tm_year) + 1900); else if(g_strcmp0(variable, "$(EXIF_MONTH)") == 0 && (got_value = TRUE)) snprintf(value, value_len, "%.2d", (have_exif_tm ? exif_tm.tm_mon : tim.tm_mon) + 1); else if(g_strcmp0(variable, "$(EXIF_DAY)") == 0 && (got_value = TRUE)) snprintf(value, value_len, "%.2d", (have_exif_tm ? exif_tm.tm_mday : tim.tm_mday)); else if(g_strcmp0(variable, "$(EXIF_HOUR)") == 0 && (got_value = TRUE)) snprintf(value, value_len, "%.2d", (have_exif_tm ? exif_tm.tm_hour : tim.tm_hour)); else if(g_strcmp0(variable, "$(EXIF_MINUTE)") == 0 && (got_value = TRUE)) snprintf(value, value_len, "%.2d", (have_exif_tm ? exif_tm.tm_min : tim.tm_min)); else if(g_strcmp0(variable, "$(EXIF_SECOND)") == 0 && (got_value = TRUE)) snprintf(value, value_len, "%.2d", (have_exif_tm ? exif_tm.tm_sec : tim.tm_sec)); else if(g_strcmp0(variable, "$(EXIF_ISO)") == 0 && (got_value = TRUE)) snprintf(value, value_len, "%d", exif_iso); else if(g_strcmp0(variable, "$(MAKER)") == 0 && (got_value = TRUE)) snprintf(value, value_len, "%s", camera_maker); else if(g_strcmp0(variable, "$(MODEL)") == 0 && (got_value = TRUE)) snprintf(value, value_len, "%s", camera_alias); else if(g_strcmp0(variable, "$(ID)") == 0 && (got_value = TRUE)) snprintf(value, value_len, "%d", params->imgid); else if(g_strcmp0(variable, "$(VERSION)") == 0 && (got_value = TRUE)) snprintf(value, value_len, "%d", version); else if(g_strcmp0(variable, "$(JOBCODE)") == 0 && (got_value = TRUE)) snprintf(value, value_len, "%s", params->jobcode); else if(g_strcmp0(variable, "$(ROLL_NAME)") == 0 && params->filename && (got_value = TRUE)) { gchar *dirname = g_path_get_dirname(params->filename); gchar *basename = g_path_get_basename(dirname); snprintf(value, value_len, "%s", basename); g_free(basename); g_free(dirname); } else if(g_strcmp0(variable, "$(FILE_DIRECTORY)") == 0 && params->filename && (got_value = TRUE)) { gchar *dirname = g_path_get_dirname(params->filename); snprintf(value, value_len, "%s", dirname); g_free(dirname); } // undocumented : backward compatibility else if(g_strcmp0(variable, "$(FILE_FOLDER)") == 0 && params->filename && (got_value = TRUE)) { gchar *dirname = g_path_get_dirname(params->filename); snprintf(value, value_len, "%s", dirname); g_free(dirname); } else if(g_strcmp0(variable, "$(FILE_NAME)") == 0 && params->filename && (got_value = TRUE)) { gchar *basename = g_path_get_basename(params->filename); snprintf(value, value_len, "%s", basename); g_free(basename); if(g_strrstr(value, ".")) *(g_strrstr(value, ".")) = 0; } else if(g_strcmp0(variable, "$(FILE_EXTENSION)") == 0 && params->filename && (got_value = TRUE)) snprintf(value, value_len, "%s", file_ext); else if(g_strcmp0(variable, "$(SEQUENCE)") == 0 && (got_value = TRUE)) snprintf(value, value_len, "%.4d", params->sequence >= 0 ? params->sequence : params->data->sequence); else if(g_strcmp0(variable, "$(USERNAME)") == 0 && (got_value = TRUE)) snprintf(value, value_len, "%s", g_get_user_name()); else if(g_strcmp0(variable, "$(HOME_FOLDER)") == 0 && (got_value = TRUE)) snprintf(value, value_len, "%s", homedir); // undocumented : backward compatibility else if(g_strcmp0(variable, "$(HOME)") == 0 && (got_value = TRUE)) snprintf(value, value_len, "%s", homedir); else if(g_strcmp0(variable, "$(PICTURES_FOLDER)") == 0 && (got_value = TRUE)) snprintf(value, value_len, "%s", pictures_folder); else if(g_strcmp0(variable, "$(DESKTOP_FOLDER)") == 0 && (got_value = TRUE)) snprintf(value, value_len, "%s", g_get_user_special_dir(G_USER_DIRECTORY_DESKTOP)); // undocumented : backward compatibility else if(g_strcmp0(variable, "$(DESKTOP)") == 0 && (got_value = TRUE)) snprintf(value, value_len, "%s", g_get_user_special_dir(G_USER_DIRECTORY_DESKTOP)); else if(g_strcmp0(variable, "$(STARS)") == 0 && (got_value = TRUE)) snprintf(value, value_len, "%d", stars); else if(g_strcmp0(variable, "$(LABELS)") == 0 && (got_value = TRUE)) { // TODO: currently we concatenate all the color labels with a ',' as a separator. Maybe it's better to // only use the first/last label? GList *res = dt_metadata_get(params->imgid, "Xmp.darktable.colorlabels", NULL); res = g_list_first(res); if(res != NULL) { GList *labels = NULL; do { labels = g_list_append(labels, (char *)(_(dt_colorlabels_to_string(GPOINTER_TO_INT(res->data))))); } while((res = g_list_next(res)) != NULL); char *str = dt_util_glist_to_str(",", labels); g_list_free(labels); snprintf(value, value_len, "%s", str); g_free(str); } else { snprintf(value, value_len, "%s", _("none")); } g_list_free(res); } else if(g_strcmp0(variable, "$(TITLE)") == 0 && params->filename && (got_value = TRUE)) { GList *res = dt_metadata_get(params->imgid, "Xmp.dc.title", NULL); res = g_list_first(res); if(res != NULL) { snprintf(value, value_len, "%s", (char *)res->data); } else { snprintf(value, value_len, "%s", _("none")); } g_list_free_full(res, &g_free); } else if(g_strcmp0(variable, "$(CREATOR)") == 0 && params->filename && (got_value = TRUE)) { GList *res = dt_metadata_get(params->imgid, "Xmp.dc.creator", NULL); res = g_list_first(res); if(res != NULL) { snprintf(value, value_len, "%s", (char *)res->data); } else { snprintf(value, value_len, "%s", _("none")); } g_list_free_full(res, &g_free); } else if(g_strcmp0(variable, "$(PUBLISHER)") == 0 && params->filename && (got_value = TRUE)) { GList *res = dt_metadata_get(params->imgid, "Xmp.dc.publisher", NULL); res = g_list_first(res); if(res != NULL) { snprintf(value, value_len, "%s", (char *)res->data); } else { snprintf(value, value_len, "%s", _("none")); } g_list_free_full(res, &g_free); } else if(g_strcmp0(variable, "$(RIGHTS)") == 0 && params->filename && (got_value = TRUE)) { GList *res = dt_metadata_get(params->imgid, "Xmp.dc.rights", NULL); res = g_list_first(res); if(res != NULL) { snprintf(value, value_len, "%s", (char *)res->data); } else { snprintf(value, value_len, "%s", _("none")); } g_list_free_full(res, &g_free); } g_free(pictures_folder); g_free((gchar *)homedir); return got_value; }
int store(dt_imageio_module_storage_t *self, dt_imageio_module_data_t *sdata, const int imgid, dt_imageio_module_format_t *format, dt_imageio_module_data_t *fdata, const int num, const int total, const gboolean high_quality, const gboolean upscale) { dt_imageio_latex_t *d = (dt_imageio_latex_t *)sdata; char filename[PATH_MAX] = { 0 }; char dirname[PATH_MAX] = { 0 }; gboolean from_cache = FALSE; dt_image_full_path(imgid, dirname, sizeof(dirname), &from_cache); // we're potentially called in parallel. have sequence number synchronized: dt_pthread_mutex_lock(&darktable.plugin_threadsafe); { // if filenamepattern is a directory just add ${FILE_NAME} as default.. if(g_file_test(d->filename, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR) || ((d->filename + strlen(d->filename))[0] == '/' || (d->filename + strlen(d->filename))[0] == '\\')) snprintf(d->filename + strlen(d->filename), sizeof(d->filename) - strlen(d->filename), "$(FILE_NAME)"); // avoid braindead export which is bound to overwrite at random: if(total > 1 && !g_strrstr(d->filename, "$")) { snprintf(d->filename + strlen(d->filename), sizeof(d->filename) - strlen(d->filename), "_$(SEQUENCE)"); } gchar *fixed_path = dt_util_fix_path(d->filename); g_strlcpy(d->filename, fixed_path, sizeof(d->filename)); g_free(fixed_path); d->vp->filename = dirname; d->vp->jobcode = "export"; d->vp->imgid = imgid; d->vp->sequence = num; dt_variables_expand(d->vp, d->filename, TRUE); gchar *result_filename = dt_variables_get_result(d->vp); g_strlcpy(filename, result_filename, sizeof(filename)); g_free(result_filename); g_strlcpy(dirname, filename, sizeof(dirname)); const char *ext = format->extension(fdata); char *c = dirname + strlen(dirname); for(; c > dirname && *c != '/'; c--) ; if(*c == '/') *c = '\0'; if(g_mkdir_with_parents(dirname, 0755)) { fprintf(stderr, "[imageio_storage_latex] could not create directory: `%s'!\n", dirname); dt_control_log(_("could not create directory `%s'!"), dirname); dt_pthread_mutex_unlock(&darktable.plugin_threadsafe); return 1; } // store away dir. snprintf(d->cached_dirname, sizeof(d->cached_dirname), "%s", dirname); c = filename + strlen(filename); // for(; c>filename && *c != '.' && *c != '/' ; c--); // if(c <= filename || *c=='/') c = filename + strlen(filename); sprintf(c, ".%s", ext); // save image to list, in order: pair_t *pair = malloc(sizeof(pair_t)); #if 0 // let's see if we actually want titles and such to be exported: char *title = NULL, *description = NULL, *tags = NULL; GList *res_title, *res_desc, *res_subj; res_title = dt_metadata_get(imgid, "Xmp.dc.title", NULL); if(res_title) { title = res_title->data; } res_desc = dt_metadata_get(imgid, "Xmp.dc.description", NULL); if(res_desc) { description = res_desc->data; } res_subj = dt_metadata_get(imgid, "Xmp.dc.subject", NULL); if(res_subj) { // don't show the internal tags (darktable|...) res_subj = g_list_first(res_subj); GList *iter = res_subj; while(iter) { GList *next = g_list_next(iter); if(g_str_has_prefix(iter->data, "darktable|")) { g_free(iter->data); res_subj = g_list_delete_link(res_subj, iter); } iter = next; } tags = dt_util_glist_to_str(", ", res_subj); g_list_free_full(res_subj, g_free); } #endif char relfilename[PATH_MAX] = { 0 }; c = filename + strlen(filename); for(; c > filename && *c != '/'; c--) ; if(*c == '/') c++; if(c <= filename) c = filename; snprintf(relfilename, sizeof(relfilename), "%s", c); snprintf(pair->line, sizeof(pair->line), "\\begin{minipage}{\\imgwidth}%%\n" "\\drawtrimcorners%%\n" "\\vskip0pt plus 1filll\n" "\\begin{minipage}{\\imgwidth}%%\n" " \\hfil\\includegraphics[width=\\imgwidth,height=\\imgheight,keepaspectratio]{%s}\\hfil\n" " %% put text under image here\n" "\\end{minipage}\n" "\\end{minipage}\n" "\\newpage\n\n", relfilename); pair->pos = num; // g_list_free_full(res_title, &g_free); // g_list_free_full(res_desc, &g_free); // g_list_free_full(res_subj, &g_free); // g_free(tags); d->l = g_list_insert_sorted(d->l, pair, (GCompareFunc)sort_pos); } // end of critical block dt_pthread_mutex_unlock(&darktable.plugin_threadsafe); /* export image to file */ dt_imageio_export(imgid, filename, format, fdata, high_quality, upscale, FALSE, self, sdata, num, total); printf("[export_job] exported to `%s'\n", filename); char *trunc = filename + strlen(filename) - 32; if(trunc < filename) trunc = filename; dt_control_log(ngettext("%d/%d exported to `%s%s'", "%d/%d exported to `%s%s'", num), num, total, trunc != filename ? ".." : "", trunc); return 0; }
int store(dt_imageio_module_storage_t *self, dt_imageio_module_data_t *sdata, const int imgid, dt_imageio_module_format_t *format, dt_imageio_module_data_t *fdata, const int num, const int total, const gboolean high_quality, const gboolean upscale, dt_colorspaces_color_profile_type_t icc_type, const gchar *icc_filename, dt_iop_color_intent_t icc_intent) { dt_storage_piwigo_gui_data_t *ui = self->gui_data; gint result = 0; const char *ext = format->extension(fdata); // Let's upload image... /* construct a temporary file name */ char fname[PATH_MAX] = { 0 }; dt_loc_get_tmp_dir(fname, sizeof(fname)); g_strlcat(fname, "/darktable.XXXXXX.", sizeof(fname)); g_strlcat(fname, ext, sizeof(fname)); char *caption = NULL; char *description = NULL; char *author = NULL; gint fd = g_mkstemp(fname); if(fd == -1) { dt_control_log("failed to create temporary image for piwigo export"); fprintf(stderr, "failed to create tempfile: %s\n", fname); return 1; } close(fd); const dt_image_t *img = dt_image_cache_get(darktable.image_cache, imgid, 'r'); // If title is not existing, then use the filename without extension. If not, then use title instead GList *title = dt_metadata_get(img->id, "Xmp.dc.title", NULL); if(title != NULL) { caption = g_strdup(title->data); g_list_free_full(title, &g_free); } else { caption = g_path_get_basename(img->filename); (g_strrstr(caption, "."))[0] = '\0'; // chop extension... } GList *desc = dt_metadata_get(img->id, "Xmp.dc.description", NULL); if(desc != NULL) { description = g_strdup(desc->data); g_list_free_full(desc, &g_free); } dt_image_cache_read_release(darktable.image_cache, img); GList *auth = dt_metadata_get(img->id, "Xmp.dc.creator", NULL); if(auth != NULL) { author = g_strdup(auth->data); g_list_free_full(auth, &g_free); } if(dt_imageio_export(imgid, fname, format, fdata, high_quality, upscale, FALSE, icc_type, icc_filename, icc_intent, self, sdata, num, total) != 0) { fprintf(stderr, "[imageio_storage_piwigo] could not export to file: `%s'!\n", fname); dt_control_log(_("could not export to file `%s'!"), fname); result = 1; goto cleanup; } dt_pthread_mutex_lock(&darktable.plugin_threadsafe); { gboolean status = TRUE; dt_storage_piwigo_params_t *p = (dt_storage_piwigo_params_t *)sdata; if(p->export_tags) { GList *tags_list = dt_tag_get_list(imgid); if(p->tags) g_free(p->tags); p->tags = dt_util_glist_to_str(",", tags_list); g_list_free_full(tags_list, g_free); } if(p->new_album) { status = _piwigo_api_create_new_album(p); if(!status) dt_control_log(_("cannot create a new piwigo album!")); } if(status) { status = _piwigo_api_upload_photo(p, fname, author, caption, description); if(!status) { fprintf(stderr, "[imageio_storage_piwigo] could not upload to piwigo!\n"); dt_control_log(_("could not upload to piwigo!")); result = 1; } else if (p->new_album) { // we do not want to create more albums when multiple upload p->new_album = FALSE; _piwigo_refresh_albums(ui, p->album); } } } dt_pthread_mutex_unlock(&darktable.plugin_threadsafe); cleanup: // And remove from filesystem.. g_unlink(fname); g_free(caption); g_free(description); g_free(author); if(!result) { // this makes sense only if the export was successful dt_control_log(ngettext("%d/%d exported to piwigo webalbum", "%d/%d exported to piwigo webalbum", num), num, total); } return result; }