<commit_before>/* GIO - GLib Input, Output and Streaming Library
 *
 * Copyright (C) 2006-2007 Red Hat, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * Author: <NAME> <<EMAIL>>
 */

#include <config.h>

#include <glib.h>
#include <glib/gi18n.h>
#include <glib/gstdio.h>
#include <stdlib.h>
#include <dbus/dbus.h>
#include "gdbusutils.h"
#include "metatree.h"
#include "gvfsdaemonprotocol.h"

#define WRITEOUT_TIMEOUT_SECS 60

typedef struct {
  char *filename;
  MetaTree *tree;
  guint writeout_timeout;
} TreeInfo;

static GHashTable *tree_infos = NULL;

static void
tree_info_free (TreeInfo *info)
{
  g_free (info->filename);
  meta_tree_unref (info->tree);
  if (info->writeout_timeout)
    g_source_remove (info->writeout_timeout);

  g_free (info);
}

static gboolean
writeout_timeout (gpointer data)
{
  TreeInfo *info = data;

  meta_tree_flush (info->tree);
  info->writeout_timeout = 0;

  return FALSE;
}

static void
tree_info_schedule_writeout (TreeInfo *info)
{
  if (info->writeout_timeout == 0)
    info->writeout_timeout =
      g_timeout_add_seconds (WRITEOUT_TIMEOUT_SECS,
			     writeout_timeout, info);
}

static TreeInfo *
tree_info_new (const char *filename)
{
  TreeInfo *info;
  MetaTree *tree;

  tree = meta_tree_open (filename, TRUE);
  if (tree == NULL)
    return NULL;

  info = g_new0 (TreeInfo, 1);
  info->filename = g_strdup (filename);
  info->tree = tree;
  info->writeout_timeout = 0;

  return info;
}

static TreeInfo *
tree_info_lookup (const char *filename)
{
  TreeInfo *info;

  info = g_hash_table_lookup (tree_infos, filename);
  if (info)
    return info;

  info = tree_info_new (filename);
  if (info)
    g_hash_table_insert (tree_infos,
			 info->filename,
			 info);
  return info;
}

static gboolean
metadata_set (const char *treefile,
	      const char *path,
	      DBusMessageIter *iter,
	      DBusError *derror)
{
  TreeInfo *info;
  const char *str;
  char **strv;
  gboolean res;
  const char *key;
  int n_elements;

  info = tree_info_lookup (treefile);
  if (info == NULL)
    {
      dbus_set_error (derror,
		      DBUS_ERROR_FILE_NOT_FOUND,
		      _("Can't find metadata file %s"),
		      treefile);
      return FALSE;
    }

  res = TRUE;
  while (dbus_message_iter_get_arg_type (iter) != 0)
    {
      if (!_g_dbus_message_iter_get_args (iter, derror,
					  DBUS_TYPE_STRING, &key,
					  0))
	{
	  res = FALSE;
	  break;
	}

      if (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_ARRAY)
	{
	  /* stringv */
	  if (!_g_dbus_message_iter_get_args (iter, derror,
					      DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &strv, &n_elements,
					      0))
	    {
	      res = FALSE;
	      break;
	    }
	  if (!meta_tree_set_stringv (info->tree, path, key, strv))
	    {
	      dbus_set_error (derror,
			      DBUS_ERROR_FAILED,
			      _("Unable to set metadata key"));
	      res = FALSE;
	    }
	  g_strfreev (strv);
	}
      else
	{
	  /* string */
	  if (!_g_dbus_message_iter_get_args (iter, derror,
					      DBUS_TYPE_STRING, &str,
					      0))
	    {
	      res = FALSE;
	      break;
	    }
	  if (!meta_tree_set_string (info->tree, path, key, str))
	    {
	      dbus_set_error (derror,
			      DBUS_ERROR_FAILED,
			      _("Unable to set metadata key"));
	      res = FALSE;
	    }
	}<commit_msg>Allow unsetting keys with the standard Set dbus operation<commit_after>/* GIO - GLib Input, Output and Streaming Library
 *
 * Copyright (C) 2006-2007 Red Hat, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * Author: <NAME> <<EMAIL>>
 */

#include <config.h>

#include <glib.h>
#include <glib/gi18n.h>
#include <glib/gstdio.h>
#include <stdlib.h>
#include <dbus/dbus.h>
#include "gdbusutils.h"
#include "metatree.h"
#include "gvfsdaemonprotocol.h"

#define WRITEOUT_TIMEOUT_SECS 60

typedef struct {
  char *filename;
  MetaTree *tree;
  guint writeout_timeout;
} TreeInfo;

static GHashTable *tree_infos = NULL;

static void
tree_info_free (TreeInfo *info)
{
  g_free (info->filename);
  meta_tree_unref (info->tree);
  if (info->writeout_timeout)
    g_source_remove (info->writeout_timeout);

  g_free (info);
}

static gboolean
writeout_timeout (gpointer data)
{
  TreeInfo *info = data;

  meta_tree_flush (info->tree);
  info->writeout_timeout = 0;

  return FALSE;
}

static void
tree_info_schedule_writeout (TreeInfo *info)
{
  if (info->writeout_timeout == 0)
    info->writeout_timeout =
      g_timeout_add_seconds (WRITEOUT_TIMEOUT_SECS,
			     writeout_timeout, info);
}

static TreeInfo *
tree_info_new (const char *filename)
{
  TreeInfo *info;
  MetaTree *tree;

  tree = meta_tree_open (filename, TRUE);
  if (tree == NULL)
    return NULL;

  info = g_new0 (TreeInfo, 1);
  info->filename = g_strdup (filename);
  info->tree = tree;
  info->writeout_timeout = 0;

  return info;
}

static TreeInfo *
tree_info_lookup (const char *filename)
{
  TreeInfo *info;

  info = g_hash_table_lookup (tree_infos, filename);
  if (info)
    return info;

  info = tree_info_new (filename);
  if (info)
    g_hash_table_insert (tree_infos,
			 info->filename,
			 info);
  return info;
}

static gboolean
metadata_set (const char *treefile,
	      const char *path,
	      DBusMessageIter *iter,
	      DBusError *derror)
{
  TreeInfo *info;
  const char *str;
  char **strv;
  gboolean res;
  const char *key;
  int n_elements;
  char c;

  info = tree_info_lookup (treefile);
  if (info == NULL)
    {
      dbus_set_error (derror,
		      DBUS_ERROR_FILE_NOT_FOUND,
		      _("Can't find metadata file %s"),
		      treefile);
      return FALSE;
    }

  res = TRUE;
  while (dbus_message_iter_get_arg_type (iter) != 0)
    {
      if (!_g_dbus_message_iter_get_args (iter, derror,
					  DBUS_TYPE_STRING, &key,
					  0))
	{
	  res = FALSE;
	  break;
	}

      if (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_ARRAY)
	{
	  /* stringv */
	  if (!_g_dbus_message_iter_get_args (iter, derror,
					      DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &strv, &n_elements,
					      0))
	    {
	      res = FALSE;
	      break;
	    }
	  if (!meta_tree_set_stringv (info->tree, path, key, strv))
	    {
	      dbus_set_error (derror,
			      DBUS_ERROR_FAILED,
			      _("Unable to set metadata key"));
	      res = FALSE;
	    }
	  g_strfreev (strv);
	}
      else if (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_STRING)
	{
	  /* string */
	  if (!_g_dbus_message_iter_get_args (iter, derror,
					      DBUS_TYPE_STRING, &str,
					      0))
	    {
	      res = FALSE;
	      break;
	    }
	  if (!meta_tree_set_string (info->tree, path, key, str))
	    {
	      dbus_set_error (derror,
			      DBUS_ERROR_FAILED,
			      _("Unable to set metadata key"));
	      res = FALSE;
	    }
	}
      else if (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_BYTE)
	{
	  /* Unset */
	  if (!_g_dbus_message_iter_get_args (iter, derror,
					      DBUS_TYPE_BYTE, &c,
					      0))
	    {
	      res = FALSE;
	      break;
	    }
	  if (!meta_tree_unset (info->tree, path, key))
	    {
	      dbus_set_error (derror,
			      DBUS_ERROR_FAILED,
			      _("Unable to unset metadata key"));
	      res = FALSE;
	    }
	}
{'fraction_non_alphanumeric': 0.10380460310004697, 'fraction_numerical': 0.008572099577266323, 'mean_word_length': 2.9985915492957744, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 50, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6575340', 'n_tokens_mistral': 3219, 'n_tokens_neox': 2944, 'n_words': 827}