void gui_init(dt_lib_module_t *self) { /* initialize ui widgets */ dt_lib_snapshots_t *d = (dt_lib_snapshots_t *)g_malloc(sizeof(dt_lib_snapshots_t)); self->data = (void *)d; memset(d,0,sizeof(dt_lib_snapshots_t)); /* initialize snapshot storages */ d->size = 4; d->snapshot = (dt_lib_snapshot_t *)g_malloc(sizeof(dt_lib_snapshot_t)*d->size); d->vp_xpointer = 0.5; d->vp_ypointer = 0.5; d->vertical = TRUE; memset(d->snapshot,0,sizeof(dt_lib_snapshot_t)*d->size); /* initialize ui containers */ self->widget = gtk_vbox_new(FALSE,2); d->snapshots_box = gtk_vbox_new(FALSE,0); /* create take snapshot button */ GtkWidget *button = gtk_button_new_with_label(_("take snapshot")); d->take_button = button; g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(_lib_snapshots_add_button_clicked_callback), self); g_object_set(button, "tooltip-text", _("take snapshot to compare with another image or the same image at another stage of development"), (char *)NULL); /* * initialize snapshots */ char wdname[32]= {0}; char localtmpdir[4096]= {0}; dt_loc_get_tmp_dir (localtmpdir, sizeof(localtmpdir)); for (int k=0; k<d->size; k++) { /* create snapshot button */ d->snapshot[k].button = dtgtk_togglebutton_new_with_label (wdname,NULL,CPF_STYLE_FLAT); g_signal_connect(G_OBJECT ( d->snapshot[k].button), "clicked", G_CALLBACK (_lib_snapshots_toggled_callback), self); /* assign snapshot number to widget */ g_object_set_data(G_OBJECT(d->snapshot[k].button),"snapshot",GINT_TO_POINTER(k+1)); /* setup filename for snapshot */ snprintf(d->snapshot[k].filename, sizeof(d->snapshot[k].filename), "%s/dt_snapshot_%d.png",localtmpdir,k); /* add button to snapshot box */ gtk_box_pack_start(GTK_BOX(d->snapshots_box),d->snapshot[k].button,TRUE,TRUE,0); /* prevent widget to show on external show all */ gtk_widget_set_no_show_all(d->snapshot[k].button, TRUE); } /* add snapshot box and take snapshot button to widget ui*/ gtk_box_pack_start(GTK_BOX(self->widget), d->snapshots_box,TRUE,TRUE,0); gtk_box_pack_start(GTK_BOX(self->widget), button, TRUE,TRUE,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_imageio_email_t *d = (dt_imageio_email_t *)sdata; _email_attachment_t *attachment = (_email_attachment_t *)g_malloc(sizeof(_email_attachment_t)); attachment->imgid = imgid; /* construct a temporary file name */ char tmpdir[PATH_MAX] = { 0 }; dt_loc_get_tmp_dir(tmpdir, sizeof(tmpdir)); char dirname[PATH_MAX] = { 0 }; gboolean from_cache = FALSE; dt_image_full_path(imgid, dirname, sizeof(dirname), &from_cache); gchar *filename = g_path_get_basename(dirname); g_strlcpy(dirname, filename, sizeof(dirname)); dt_image_path_append_version(imgid, dirname, sizeof(dirname)); gchar *end = g_strrstr(dirname, ".") + 1; if(end) *end = '\0'; g_strlcat(dirname, format->extension(fdata), sizeof(dirname)); // set exported filename attachment->file = g_build_filename(tmpdir, dirname, (char *)NULL); if(dt_imageio_export(imgid, attachment->file, format, fdata, high_quality, upscale, FALSE, icc_type, icc_filename, icc_intent, self, sdata, num, total) != 0) { fprintf(stderr, "[imageio_storage_email] could not export to file: `%s'!\n", attachment->file); dt_control_log(_("could not export to file `%s'!"), attachment->file); g_free(attachment); g_free(filename); return 1; } char *trunc = attachment->file + strlen(attachment->file) - 32; if(trunc < attachment->file) trunc = attachment->file; dt_control_log(ngettext("%d/%d exported to `%s%s'", "%d/%d exported to `%s%s'", num), num, total, trunc != filename ? ".." : "", trunc); #ifdef _OPENMP // store can be called in parallel, so synch access to shared memory #pragma omp critical #endif d->images = g_list_append(d->images, attachment); g_free(filename); return 0; }
static int store_wrapper(struct dt_imageio_module_storage_t *self,struct dt_imageio_module_data_t *self_data, 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) { /* construct a temporary file name */ char tmpdir[DT_MAX_PATH_LEN]= {0}; gboolean from_cache = FALSE; dt_loc_get_tmp_dir (tmpdir,DT_MAX_PATH_LEN); char dirname[DT_MAX_PATH_LEN]; dt_image_full_path(imgid, dirname, DT_MAX_PATH_LEN, &from_cache); const gchar * filename = g_path_get_basename( dirname ); gchar * end = g_strrstr( filename,".")+1; g_strlcpy( end, format->extension(fdata), sizeof(dirname)-(end-dirname)); gchar* complete_name = g_build_filename( tmpdir, filename, (char *)NULL ); if(dt_imageio_export(imgid, complete_name, format, fdata, high_quality) != 0) { fprintf(stderr, "[%s] could not export to file: `%s'!\n", self->name(self),complete_name); g_free(complete_name); return 1; } lua_storage_t *d = (lua_storage_t*) self_data; d->imgids = g_list_prepend(d->imgids,(void*)(intptr_t)imgid); d->file_names = g_list_prepend(d->file_names,complete_name); lua_State *L =darktable.lua_state; lua_getfield(L,LUA_REGISTRYINDEX,"dt_lua_storages"); lua_getfield(L,-1,self->plugin_name); lua_getfield(L,-1,"store"); if(lua_isnil(L,-1)) { lua_pop(L,3); return 1; } luaA_push_typeid(L,self->parameter_lua_type,self_data); luaA_push(L,dt_lua_image_t,&imgid); luaA_push_typeid(L,format->parameter_lua_type,fdata); lua_pushstring(L,complete_name); lua_pushnumber(L,num); lua_pushnumber(L,total); lua_pushboolean(L,high_quality); lua_pushlightuserdata(L,self_data); lua_gettable(L,LUA_REGISTRYINDEX); dt_lua_do_chunk(L,8,1); int result = lua_toboolean(L,-1); lua_pop(L,2); return result; }
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) { dt_imageio_email_t *d = (dt_imageio_email_t *)sdata; _email_attachment_t *attachment = ( _email_attachment_t *)g_malloc(sizeof(_email_attachment_t)); attachment->imgid = imgid; /* construct a temporary file name */ char tmpdir[4096]= {0}; dt_loc_get_tmp_dir (tmpdir,4096); char dirname[4096]; dt_image_full_path(imgid, dirname, 1024); const gchar * filename = g_path_get_basename( dirname ); gchar * end = g_strrstr( filename,".")+1; g_strlcpy( end, format->extension(fdata), sizeof(dirname)-(end-dirname)); attachment->file = g_build_filename( tmpdir, filename, (char *)NULL ); if(dt_imageio_export(imgid, attachment->file, format, fdata, high_quality) != 0) { fprintf(stderr, "[imageio_storage_email] could not export to file: `%s'!\n", attachment->file); dt_control_log(_("could not export to file `%s'!"), attachment->file); g_free(attachment); return 1; } char *trunc = attachment->file + strlen(attachment->file) - 32; if(trunc < attachment->file) trunc = attachment->file; dt_control_log(_("%d/%d exported to `%s%s'"), num, total, trunc != filename ? ".." : "", trunc); #ifdef _OPENMP // store can be called in parallel, so synch access to shared memory #pragma omp critical #endif d->images = g_list_append( d->images, attachment ); return 0; }
int dt_lua_init_configuration(lua_State*L){ char tmp_path[PATH_MAX]; dt_lua_push_darktable_lib(L); dt_lua_goto_subtable(L,"configuration"); // build the table containing the configuration info lua_pushstring(L,"tmp_dir"); dt_loc_get_tmp_dir(tmp_path, PATH_MAX); lua_pushstring(L,tmp_path); lua_settable(L,-3); lua_pushstring(L,"config_dir"); dt_loc_get_user_config_dir(tmp_path, PATH_MAX); lua_pushstring(L,tmp_path); lua_settable(L,-3); lua_pushstring(L,"cache_dir"); dt_loc_get_user_cache_dir(tmp_path, PATH_MAX); lua_pushstring(L,tmp_path); lua_settable(L,-3); lua_pushstring(L,"version"); lua_pushstring(darktable.lua_state,PACKAGE_VERSION); lua_settable(L,-3); lua_pushstring(L,"verbose"); lua_pushboolean(L,darktable.unmuted & DT_DEBUG_LUA); lua_settable(L,-3); lua_pushstring(L,"has_gui"); lua_pushboolean(L,darktable.gui != NULL); lua_settable(L,-3); lua_pop(L,-1); //remove the configuration table from the stack return 0; }
void dt_print_file(const int32_t imgid, const char *filename, const char *job_title, const dt_print_info_t *pinfo) { // first for safety check that filename exists and is readable if (!g_file_test(filename, G_FILE_TEST_IS_REGULAR)) { dt_control_log(_("file `%s' to print not found for image %d on `%s'"), filename, imgid, pinfo->printer.name); return; } cups_option_t *options = NULL; int num_options = 0; // for turboprint drived printer, use the turboprint dialog if (pinfo->printer.is_turboprint) { const char *tp_intent_name[] = { "perception_0", "colorimetric-relative_1", "saturation_1", "colorimetric-absolute_1" }; char tmpfile[PATH_MAX] = { 0 }; dt_loc_get_tmp_dir(tmpfile, sizeof(tmpfile)); g_strlcat(tmpfile, "/dt_cups_opts_XXXXXX", sizeof(tmpfile)); gint fd = g_mkstemp(tmpfile); if(fd == -1) { dt_control_log(_("failed to create temporary file for printing options")); fprintf(stderr, "failed to create temporary pdf for printing options\n"); return; } close(fd); // ensure that intent is in the range, may happen if at some point we add new intent in the list const int intent = (pinfo->printer.intent < 4) ? pinfo->printer.intent : 0; // spawn turboprint command gchar * argv[15] = { 0 }; argv[0] = "turboprint"; argv[1] = g_strdup_printf("--printer=%s", pinfo->printer.name); argv[2] = "--options"; argv[3] = g_strdup_printf("--output=%s", tmpfile); argv[4] = "-o"; argv[5] = "copies=1"; argv[6] = "-o"; argv[7] = g_strdup_printf("PageSize=%s", pinfo->paper.common_name); argv[8] = "-o"; argv[9] = "InputSlot=AutoSelect"; argv[10] = "-o"; argv[11] = g_strdup_printf("zedoIntent=%s", tp_intent_name[intent]); argv[12] = "-o"; argv[13] = g_strdup_printf("MediaType=%s", pinfo->medium.name); argv[14] = NULL; gint exit_status = 0; g_spawn_sync (NULL, argv, NULL, G_SPAWN_SEARCH_PATH | G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, NULL, NULL, NULL, NULL, &exit_status, NULL); g_free(argv[1]); g_free(argv[3]); g_free(argv[7]); g_free(argv[11]); g_free(argv[13]); if (exit_status==0) { FILE *stream = g_fopen(tmpfile, "rb"); while(1) { char optname[100]; char optvalue[100]; const int ropt = fscanf(stream, "%*s %[^= ]=%s", optname, optvalue); // if we parsed an option name=value if (ropt==2) { char *v = optvalue; // remove possible single quote around value if (*v == '\'') v++; if (v[strlen(v)-1] == '\'') v[strlen(v)-1] = '\0'; num_options = cupsAddOption(optname, v, num_options, &options); } else if (ropt == EOF) break; } fclose(stream); g_unlink(tmpfile); } else { dt_print(DT_DEBUG_PRINT, "[print] command fails with %d, cancel printing\n", exit_status); return; } } else { cups_dest_t *dests; int num_dests = cupsGetDests(&dests); cups_dest_t *dest = cupsGetDest(pinfo->printer.name, NULL, num_dests, dests); for (int j = 0; j < dest->num_options; j ++) if (cupsGetOption(dest->options[j].name, num_options, options) == NULL) num_options = cupsAddOption(dest->options[j].name, dest->options[j].value, num_options, &options); cupsFreeDests(num_dests, dests); // if we have a profile, disable cm on CUPS, this is important as dt does the cm num_options = cupsAddOption("cm-calibration", *pinfo->printer.profile ? "true" : "false", num_options, &options); // media to print on num_options = cupsAddOption("media", pinfo->paper.name, num_options, &options); // the media type to print on num_options = cupsAddOption("MediaType", pinfo->medium.name, num_options, &options); // never print two-side num_options = cupsAddOption("sides", "one-sided", num_options, &options); // and a single image per page num_options = cupsAddOption("number-up", "1", num_options, &options); // if the printer has no hardward margins activate the borderless mode if (pinfo->printer.hw_margin_top == 0 || pinfo->printer.hw_margin_bottom == 0 || pinfo->printer.hw_margin_left == 0 || pinfo->printer.hw_margin_right == 0) { // there is many variant for this parameter num_options = cupsAddOption("StpFullBleed", "true", num_options, &options); num_options = cupsAddOption("STP_FullBleed", "true", num_options, &options); num_options = cupsAddOption("Borderless", "true", num_options, &options); } num_options = cupsAddOption("landscape", pinfo->page.landscape ? "true" : "false", num_options, &options); } // print lp options dt_print(DT_DEBUG_PRINT, "[print] printer options (%d)\n", num_options); for (int k=0; k<num_options; k++) dt_print(DT_DEBUG_PRINT, "[print] %2d %s=%s\n", k+1, options[k].name, options[k].value); const int job_id = cupsPrintFile(pinfo->printer.name, filename, job_title, num_options, options); if (job_id == 0) dt_control_log(_("error while printing `%s' on `%s'"), job_title, pinfo->printer.name); else dt_control_log(_("printing `%s' on `%s'"), job_title, pinfo->printer.name); cupsFreeOptions (num_options, options); }
int dt_lua_init_configuration(lua_State*L) { char tmp_path[PATH_MAX]; dt_lua_push_darktable_lib(L); dt_lua_goto_subtable(L,"configuration"); // build the table containing the configuration info lua_pushstring(L,"tmp_dir"); dt_loc_get_tmp_dir(tmp_path, PATH_MAX); lua_pushstring(L,tmp_path); lua_settable(L,-3); lua_pushstring(L,"config_dir"); dt_loc_get_user_config_dir(tmp_path, PATH_MAX); lua_pushstring(L,tmp_path); lua_settable(L,-3); lua_pushstring(L,"cache_dir"); dt_loc_get_user_cache_dir(tmp_path, PATH_MAX); lua_pushstring(L,tmp_path); lua_settable(L,-3); lua_pushstring(L,"version"); lua_pushstring(L,PACKAGE_VERSION); lua_settable(L,-3); lua_pushstring(L,"verbose"); lua_pushboolean(L,darktable.unmuted & DT_DEBUG_LUA); lua_settable(L,-3); lua_pushstring(L,"has_gui"); lua_pushboolean(L,darktable.gui != NULL); lua_settable(L,-3); lua_pushstring(L,"api_version_major"); lua_pushnumber(L,API_VERSION_MAJOR); lua_settable(L,-3); lua_pushstring(L,"api_version_minor"); lua_pushnumber(L,API_VERSION_MINOR); lua_settable(L,-3); lua_pushstring(L,"api_version_patch"); lua_pushnumber(L,API_VERSION_PATCH); lua_settable(L,-3); lua_pushstring(L,"api_version_suffix"); lua_pushstring(L,API_VERSION_SUFFIX); lua_settable(L,-3); lua_pushstring(L,"api_version_string"); if (strcmp(API_VERSION_SUFFIX, "") == 0) { lua_pushfstring(L,"%d.%d.%d",API_VERSION_MAJOR,API_VERSION_MINOR,API_VERSION_PATCH); } else { lua_pushfstring(L,"%d.%d.%d-%s",API_VERSION_MAJOR,API_VERSION_MINOR,API_VERSION_PATCH,API_VERSION_SUFFIX); } lua_settable(L,-3); lua_pop(L,1); //remove the configuration table from the stack 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) { gint result=1; dt_storage_flickr_params_t *p=(dt_storage_flickr_params_t *)sdata; flickcurl_upload_status *photo_status; gint tags=0; const char *ext = format->extension(fdata); // Let's upload image... /* construct a temporary file name */ char fname[4096]= {0}; dt_loc_get_tmp_dir (fname,4096); g_strlcat (fname,"/darktable.XXXXXX.",4096); g_strlcat(fname,ext,4096); char *caption = NULL; char *description = NULL; gint fd=g_mkstemp(fname); fprintf(stderr,"tempfile: %s\n",fname); if(fd==-1) { dt_control_log("failed to create temporary image for flickr export"); return 1; } close(fd); const dt_image_t *img = dt_image_cache_read_get(darktable.image_cache, imgid); // 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 = desc->data; } dt_image_cache_read_release(darktable.image_cache, img); if(dt_imageio_export(imgid, fname, format, fdata, high_quality) != 0) { fprintf(stderr, "[imageio_storage_flickr] could not export to file: `%s'!\n", fname); dt_control_log(_("could not export to file `%s'!"), fname); result = 0; goto cleanup; } #ifdef _OPENMP #pragma omp critical #endif { //TODO: Check if this could be done in threads, so we enhance export time by using // upload time for one image to export another image to disk. // Upload image // Do we export tags? if( p->export_tags == TRUE ) tags = imgid; photo_status = _flickr_api_upload_photo( p, fname, caption, description, tags ); } if( !photo_status ) { result=0; goto cleanup; } // int fail = 0; // A photoset is only created if we have an album title set if( p->flickr_api->current_album == NULL && p->flickr_api->new_album == TRUE) { char *photoset_id; photoset_id = _flickr_api_create_photoset(p->flickr_api, photo_status->photoid); if( photoset_id == NULL) { dt_control_log("failed to create flickr album"); // fail = 1; } else { // p->flickr_api->new_album = FALSE; p->flickr_api->current_album = flickcurl_photosets_getInfo(p->flickr_api->fc,photoset_id); } } // if(fail) return 1; // TODO: What to do if photoset creation fails? // Add to gallery, if needed if (p->flickr_api->current_album != NULL && p->flickr_api->new_album != TRUE) { flickcurl_photosets_addPhoto (p->flickr_api->fc, p->flickr_api->current_album->id, photo_status->photoid); // TODO: Check for errors adding photo to gallery } else { if (p->flickr_api->current_album != NULL && p->flickr_api->new_album == TRUE) { p->flickr_api->new_album = FALSE; } } cleanup: // And remove from filesystem.. unlink( fname ); g_free( caption ); if(desc) g_list_free_full(desc, &g_free); if (result) { //this makes sense only if the export was successful dt_control_log(_("%d/%d exported to flickr webalbum"), num, total ); } return result; }
/* this actually does the work */ int store(dt_imageio_module_storage_t *self, struct 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) { gint result = 1; dt_storage_facebook_param_t *p = (dt_storage_facebook_param_t*)sdata; const char *ext = format->extension(fdata); char fname[4096]= {0}; dt_loc_get_tmp_dir(fname,4096); g_strlcat (fname,"/darktable.XXXXXX.",4096); g_strlcat(fname,ext,4096); gint fd=g_mkstemp(fname); if(fd==-1) { dt_control_log("failed to create temporary image for facebook export"); return 1; } close(fd); //get metadata const dt_image_t *img = dt_image_cache_read_get(darktable.image_cache, imgid); char *caption = NULL; GList *title = NULL; GList *desc = NULL; title = dt_metadata_get(img->id, "Xmp.dc.title", NULL); if(title != NULL) { caption = title->data; } if (caption == NULL) { desc = dt_metadata_get(img->id, "Xmp.dc.description", NULL); if(desc != NULL) { caption = desc->data; } } dt_image_cache_read_release(darktable.image_cache, img); //facebook doesn't allow pictures bigger than FB_IMAGE_MAX_SIZExFB_IMAGE_MAX_SIZE px if (fdata->max_height == 0 || fdata->max_height > FB_IMAGE_MAX_SIZE) fdata->max_height = FB_IMAGE_MAX_SIZE; if (fdata->max_width == 0 || fdata->max_width > FB_IMAGE_MAX_SIZE) fdata->max_width = FB_IMAGE_MAX_SIZE; if(dt_imageio_export(imgid, fname, format, fdata, high_quality) != 0) { g_printerr("[facebook] could not export to file: `%s'!\n", fname); dt_control_log(_("could not export to file `%s'!"), fname); result = 0; goto cleanup; } if (p->facebook_ctx->album_id == NULL) { if (p->facebook_ctx->album_title == NULL) { dt_control_log(_("unable to create album, no title provided")); result = 0; goto cleanup; } const gchar *album_id = fb_create_album(p->facebook_ctx, p->facebook_ctx->album_title, p->facebook_ctx->album_summary, p->facebook_ctx->album_permission); if (album_id == NULL) { dt_control_log(_("unable to create album")); result = 0; goto cleanup; } p->facebook_ctx->album_id = g_strdup(album_id); } const char *photoid = fb_upload_photo_to_album(p->facebook_ctx, p->facebook_ctx->album_id, fname, caption); if (photoid == NULL) { dt_control_log(_("unable to export photo to webalbum")); result = 0; goto cleanup; } cleanup: unlink( fname ); g_free( caption ); if(desc) { //no need to free desc->data as caption points to it g_list_free(desc); } if (result) { //this makes sense only if the export was successful dt_control_log(_("%d/%d exported to facebook webalbum"), num, total ); } return 0; }
static int store_wrapper(struct dt_imageio_module_storage_t *self, struct dt_imageio_module_data_t *self_data, 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) { /* construct a temporary file name */ char tmpdir[PATH_MAX] = { 0 }; gboolean from_cache = FALSE; dt_loc_get_tmp_dir(tmpdir, sizeof(tmpdir)); char dirname[PATH_MAX] = { 0 }; dt_image_full_path(imgid, dirname, sizeof(dirname), &from_cache); dt_image_path_append_version(imgid, dirname, sizeof(dirname)); gchar *filename = g_path_get_basename(dirname); gchar *end = g_strrstr(filename, ".") + 1; g_strlcpy(end, format->extension(fdata), sizeof(dirname) - (end - dirname)); gchar *complete_name = g_build_filename(tmpdir, filename, (char *)NULL); if(dt_imageio_export(imgid, complete_name, format, fdata, high_quality, upscale, FALSE, self, self_data, num, total) != 0) { fprintf(stderr, "[%s] could not export to file: `%s'!\n", self->name(self), complete_name); g_free(complete_name); g_free(filename); return 1; } lua_storage_t *d = (lua_storage_t *)self_data; dt_lua_lock(); lua_State *L = darktable.lua_state.state; push_lua_data(L,d); dt_lua_goto_subtable(L,"files"); luaA_push(L, dt_lua_image_t, &(imgid)); lua_pushstring(L, complete_name); lua_settable(L, -3); lua_pop(L,1); lua_getfield(L, LUA_REGISTRYINDEX, "dt_lua_storages"); lua_getfield(L, -1, self->plugin_name); lua_getfield(L, -1, "store"); if(lua_isnil(L, -1)) { lua_pop(L, 3); dt_lua_unlock(); g_free(filename); return 0; } luaA_push_type(L, self->parameter_lua_type, self_data); luaA_push(L, dt_lua_image_t, &imgid); luaA_push_type(L, format->parameter_lua_type, fdata); lua_pushstring(L, complete_name); lua_pushnumber(L, num); lua_pushnumber(L, total); lua_pushboolean(L, high_quality); push_lua_data(L,d); dt_lua_goto_subtable(L,"extra"); dt_lua_treated_pcall(L,8,0); lua_pop(L, 2); dt_lua_unlock(); g_free(filename); return false; }
int dt_lua_init_configuration(lua_State *L) { char tmp_path[PATH_MAX] = { 0 }; dt_lua_push_darktable_lib(L); dt_lua_goto_subtable(L, "configuration"); // build the table containing the configuration info lua_pushstring(L, "tmp_dir"); dt_loc_get_tmp_dir(tmp_path, sizeof(tmp_path)); lua_pushstring(L, tmp_path); lua_settable(L, -3); lua_pushstring(L, "config_dir"); dt_loc_get_user_config_dir(tmp_path, sizeof(tmp_path)); lua_pushstring(L, tmp_path); lua_settable(L, -3); lua_pushstring(L, "cache_dir"); dt_loc_get_user_cache_dir(tmp_path, sizeof(tmp_path)); lua_pushstring(L, tmp_path); lua_settable(L, -3); lua_pushstring(L, "version"); lua_pushstring(L, darktable_package_version); lua_settable(L, -3); lua_pushstring(L, "verbose"); lua_pushboolean(L, darktable.unmuted & DT_DEBUG_LUA); lua_settable(L, -3); lua_pushstring(L, "has_gui"); lua_pushboolean(L, darktable.gui != NULL); lua_settable(L, -3); lua_pushstring(L, "api_version_major"); lua_pushinteger(L, LUA_API_VERSION_MAJOR); lua_settable(L, -3); lua_pushstring(L, "api_version_minor"); lua_pushinteger(L, LUA_API_VERSION_MINOR); lua_settable(L, -3); lua_pushstring(L, "api_version_patch"); lua_pushinteger(L, LUA_API_VERSION_PATCH); lua_settable(L, -3); lua_pushstring(L, "api_version_suffix"); lua_pushstring(L, LUA_API_VERSION_SUFFIX); lua_settable(L, -3); lua_pushstring(L, "api_version_string"); if(LUA_API_VERSION_SUFFIX[0] == '\0') { lua_pushfstring(L, "%d.%d.%d", LUA_API_VERSION_MAJOR, LUA_API_VERSION_MINOR, LUA_API_VERSION_PATCH); } else { lua_pushfstring(L, "%d.%d.%d-%s", LUA_API_VERSION_MAJOR, LUA_API_VERSION_MINOR, LUA_API_VERSION_PATCH, LUA_API_VERSION_SUFFIX); } lua_settable(L, -3); lua_pushstring(L, "check_version"); lua_pushcfunction(L, check_version); lua_settable(L, -3); luaA_enum(L, lua_os_type); luaA_enum_value_name(L, lua_os_type, os_windows, "windows"); luaA_enum_value_name(L, lua_os_type, os_macos, "macos"); luaA_enum_value_name(L, lua_os_type, os_linux, "linux"); luaA_enum_value_name(L, lua_os_type, os_unix, "unix"); lua_pushstring(L, "running_os"); luaA_push(L, lua_os_type, &cur_os); lua_settable(L, -3); lua_pop(L, 1); // remove the configuration table from the stack return 0; }
/* this actually does the work */ int store(dt_imageio_module_storage_t *self, struct 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_gphoto_gui_data_t *ui = self->gui_data; gint result = 1; dt_gphoto_context_t *ctx = (dt_gphoto_context_t *)sdata; const char *ext = format->extension(fdata); 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)); gint fd = g_mkstemp(fname); if(fd == -1) { dt_control_log("failed to create temporary image for google photos export"); return 1; } close(fd); // get metadata const dt_image_t *img = dt_image_cache_get(darktable.image_cache, imgid, 'r'); char *title = NULL; char *summary = NULL; GList *meta_title = NULL; title = g_path_get_basename(img->filename); (g_strrstr(title, "."))[0] = '\0'; // Chop extension... meta_title = dt_metadata_get(img->id, "Xmp.dc.title", NULL); summary = meta_title != NULL ? meta_title->data : ""; dt_image_cache_read_release(darktable.image_cache, img); if(dt_imageio_export(imgid, fname, format, fdata, high_quality, upscale, FALSE, icc_type, icc_filename, icc_intent, self, sdata, num, total) != 0) { g_printerr("[gphoto] could not export to file: `%s'!\n", fname); dt_control_log(_("could not export to file `%s'!"), fname); result = 0; goto cleanup; } if(!*(ctx->album_id)) { if(ctx->album_title == NULL) { dt_control_log(_("unable to create album, no title provided")); result = 0; goto cleanup; } const gchar *album_id = gphoto_create_album(ui, ctx, ctx->album_title); if(album_id == NULL) { dt_control_log(_("unable to create album")); result = 0; goto cleanup; } g_snprintf(ctx->album_id, sizeof(ctx->album_id), "%s", album_id); } const char *photoid = gphoto_upload_photo_to_album(ctx, ctx->album_id, fname, title, summary, imgid); if(photoid == NULL) { dt_control_log(_("unable to export to google photos album")); result = 0; goto cleanup; } cleanup: g_unlink(fname); g_free(title); g_list_free_full(meta_title, &g_free); if(result) { // this makes sense only if the export was successful dt_control_log(ngettext("%d/%d exported to google photos album", "%d/%d exported to google photos album", num), num, total); } return 0; }
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) { gint tags = 0; int result=1; dt_storage_picasa_params_t *p=(dt_storage_picasa_params_t *)sdata; int fail = 0; #ifdef _OPENMP // synch parallel store #pragma omp critical #endif if( p->picasa_api->current_album == NULL ) if( _picasa_api_create_album( p->picasa_api ) != 201 ) { dt_control_log("failed to create picasa album"); fail = 1; } if(fail) return 1; const char *ext = format->extension(fdata); // Let's upload image... /* construct a temporary file name */ char fname[4096]= {0}; dt_loc_get_tmp_dir (fname,4096); g_strlcat (fname,"/darktable.XXXXXX.",4096); g_strlcat(fname,ext,4096); char *caption="a image"; char *description=""; char *mime="image/jpeg"; // Ok, maybe a dt_imageio_export_to_buffer would suit here !? gint fd=g_mkstemp(fname); fprintf(stderr,"tempfile: %s\n",fname); if(fd==-1) { dt_control_log("failed to create temporary image for picasa export"); return 1; } close(fd); const dt_image_t *img = dt_image_cache_read_get(darktable.image_cache, imgid); caption = g_path_get_basename( img->filename ); (g_strrstr(caption,"."))[0]='\0'; // Shop extension... GList *desc = dt_metadata_get(img->id, "Xmp.dc.description", NULL); if(desc != NULL) { description = desc->data; } dt_image_cache_read_release(darktable.image_cache, img); if(dt_imageio_export(imgid, fname, format, fdata, high_quality) != 0) { fprintf(stderr, "[imageio_storage_picasa] could not export to file: `%s'!\n", fname); dt_control_log(_("could not export to file `%s'!"), fname); result = 1; goto cleanup; } // Open the temp file and read image to memory GMappedFile *imgfile = g_mapped_file_new(fname,FALSE,NULL); int size = g_mapped_file_get_length( imgfile ); gchar *data =g_mapped_file_get_contents( imgfile ); #ifdef _OPENMP #pragma omp critical #endif { // Fetch the attached tags of image id if exported.. if( p->export_tags == TRUE ) tags = imgid; // Upload image to picasa if( _picasa_api_upload_photo( p->picasa_api, mime , data, size , caption, description, tags ) == 201 ) result=0; } // Unreference the memorymapped file... g_mapped_file_unref( imgfile ); // And remove from filesystem.. unlink( fname ); cleanup: g_free( caption ); if(desc) { g_free(desc->data); g_list_free(desc); } if(!result) dt_control_log(_("%d/%d exported to picasa webalbum"), num, total ); return result; }
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; }
static int _piwigo_api_post_internal(_piwigo_api_context_t *ctx, GList *args, char *filename, gboolean isauth) { curl_mime *form = NULL; GString *url = g_string_new(ctx->url); // send the requests GString *response = g_string_new(""); dt_curl_init(ctx->curl_ctx, piwigo_EXTRA_VERBOSE); curl_easy_setopt(ctx->curl_ctx, CURLOPT_URL, url->str); curl_easy_setopt(ctx->curl_ctx, CURLOPT_POST, 1); curl_easy_setopt(ctx->curl_ctx, CURLOPT_WRITEFUNCTION, curl_write_data_cb); curl_easy_setopt(ctx->curl_ctx, CURLOPT_WRITEDATA, response); if(isauth) { /* construct a temporary file name */ char cookie_fmt[PATH_MAX] = { 0 }; dt_loc_get_tmp_dir(cookie_fmt, sizeof(cookie_fmt)); g_strlcat(cookie_fmt, "/cookies.%.4lf.txt", sizeof(cookie_fmt)); ctx->cookie_file = g_strdup_printf(cookie_fmt, dt_get_wtime()); // not that this is safe as the cookie file is written only when the curl context is finalized. // At this stage we unlink the file. curl_easy_setopt(ctx->curl_ctx, CURLOPT_COOKIEJAR, ctx->cookie_file); } else { curl_easy_setopt(ctx->curl_ctx, CURLOPT_COOKIEFILE, ctx->cookie_file); } if(filename) { curl_mimepart *field = NULL; form = curl_mime_init(ctx->curl_ctx); GList *a = args; while (a) { _curl_args_t *ca = (_curl_args_t *)a->data; field = curl_mime_addpart(form); curl_mime_name(field, ca->name); curl_mime_data(field, ca->value, CURL_ZERO_TERMINATED); a = g_list_next(a); } field = curl_mime_addpart(form); curl_mime_name(field, "image"); curl_mime_filedata(field, filename); curl_easy_setopt(ctx->curl_ctx, CURLOPT_MIMEPOST, form); } else { GString *gargs = g_string_new(""); GList *a = args; while (a) { _curl_args_t *ca = (_curl_args_t *)a->data; if(a!=args) g_string_append(gargs, "&"); g_string_append(gargs, ca->name); g_string_append(gargs, "="); g_string_append(gargs, ca->value); a = g_list_next(a); } curl_easy_setopt(ctx->curl_ctx, CURLOPT_COPYPOSTFIELDS, gargs->str); g_string_free(gargs, TRUE); } int res = curl_easy_perform(ctx->curl_ctx); #if piwigo_EXTRA_VERBOSE == TRUE g_printf("curl_easy_perform status %d\n", res); #endif if(filename) curl_mime_free(form); g_string_free(url, TRUE); ctx->response = NULL; if(res == CURLE_OK) { GError *error = NULL; gboolean ret = json_parser_load_from_data(ctx->json_parser, response->str, response->len, &error); if(!ret) goto cleanup; JsonNode *root = json_parser_get_root(ctx->json_parser); // we should always have a dict if(json_node_get_node_type(root) != JSON_NODE_OBJECT) goto cleanup; ctx->response = json_node_get_object(root); const char *status = json_object_get_string_member(ctx->response, "stat"); ctx->error_occured = (status && (strcmp(status,"fail")==0)); } else ctx->error_occured = TRUE; cleanup: g_string_free(response, TRUE); return res; }