Exemple #1
0
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);

}
Exemple #2
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;
}
Exemple #3
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;

}
Exemple #4
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)
{
  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;
}
Exemple #5
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;
  
}
Exemple #6
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);
}
Exemple #7
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(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;

}
Exemple #8
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;
}
Exemple #9
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)
{
  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;
}
Exemple #10
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;
}
Exemple #11
0
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;
}
Exemple #12
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;
}
Exemple #13
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;
}
Exemple #14
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;
}
Exemple #15
0
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;
}