static void
_push_dir_cb (GFile             *file,
              GAsyncResult      *res,
              MpdStorageDevice  *self)
{
  MpdStorageDevicePrivate *priv = GET_PRIVATE (self);
  GFileEnumerator *enumerator;
  GError          *error = NULL;

  g_return_if_fail (G_IS_FILE (file));

  /* Debug */
  char *indent = g_strnfill (g_slist_length (priv->dir_stack), ' ');
  char *path = g_file_get_path (file);
  g_debug ("%s%s", indent, path);
  g_free (path);
  g_free (indent);

  enumerator = g_file_enumerate_children_finish (file, res, &error);
  if (error)
  {
    g_critical ("%s : %s", G_STRLOC, error->message);
    g_clear_error (&error);
    return;
  }

  /* g_file_enumerator_get_container () fails on us. */
  g_object_set_data_full (G_OBJECT (enumerator), "path",
                          g_file_get_path (file), g_free);
  priv->dir_stack = g_slist_prepend (priv->dir_stack,
                                     g_object_ref (enumerator));
  enumerate_dir (self);
  g_object_unref (enumerator);
}
Beispiel #2
0
static int process_suffix(const char *prefixes, const char *suffix) {
        const char *p;
        char *f;
        Hashmap *top, *bottom=NULL;
        int r = 0, k;
        Iterator i;
        int n_found = 0;

        assert(prefixes);
        assert(suffix);

        top = hashmap_new(string_hash_func, string_compare_func);
        if (!top) {
                r = -ENOMEM;
                goto finish;
        }

        bottom = hashmap_new(string_hash_func, string_compare_func);
        if (!bottom) {
                r = -ENOMEM;
                goto finish;
        }

        NULSTR_FOREACH(p, prefixes) {
                _cleanup_free_ char *t = NULL;

                t = strjoin(p, "/", suffix, NULL);
                if (!t) {
                        r = -ENOMEM;
                        goto finish;
                }

                k = enumerate_dir(top, bottom, t);
                if (k < 0)
                        r = k;

                log_debug("Looking at %s", t);
        }
static void
enumerate_dir (MpdStorageDevice  *self)
{
  MpdStorageDevicePrivate *priv = GET_PRIVATE (self);
  GFileEnumerator *enumerator;
  GFileInfo       *info;
  GError          *error = NULL;

  g_return_if_fail (priv->dir_stack);
  enumerator = G_FILE_ENUMERATOR (priv->dir_stack->data);
  g_return_if_fail (G_IS_FILE_ENUMERATOR (enumerator));

  while (NULL !=
         (info = g_file_enumerator_next_file (enumerator, NULL, &error)))
  {
    char const *content_type = g_file_info_get_content_type (info);
    char const *name = g_file_info_get_name (info);

    /* Debug */
    char *indent = g_strnfill (g_slist_length (priv->dir_stack), ' ');
    g_debug ("%s%s %s", indent, name, content_type);
    g_free (indent);

    /* Do not recurse into "dot" directories, they are use for trash. */
    if (0 == g_strcmp0 ("inode/directory", content_type) &&
        name[0] != '.')
    {
      char const *path = g_object_get_data (G_OBJECT (enumerator), "path");
      char *subpath = g_build_filename (path, name, NULL);
      GFile *subdir = file_new_for_path (subpath);

      /* Push and recurse. */
      push_dir_async (self, subdir);

      file_destroy (subdir);
      g_free (subpath);
      break;

    } else if (g_str_has_prefix (content_type, "audio/") ||
               g_str_has_prefix (content_type, "image/") ||
               g_str_has_prefix (content_type, "video/")) {

      /* Media found. */
      char const *path = g_object_get_data (G_OBJECT (enumerator), "path");
      char *filename = g_build_filename (path, name, NULL);
      priv->media_files = g_slist_prepend (priv->media_files, filename);
      priv->media_files_size += g_file_info_get_size (info);
    }

    g_object_unref (info);
  }

  if (info)
  {
    /* Broke out of loop, not done yet. */
    g_object_unref (info);

  } else {

    /* Directory finished, pop. */
    g_object_unref (enumerator);
    priv->dir_stack = g_slist_delete_link (priv->dir_stack, priv->dir_stack);
    if (priv->dir_stack)
    {
      enumerate_dir (self);
    } else {
      /* Done iterating. */
      g_signal_emit_by_name (self, "has-media", (bool) priv->media_files);
    }
  }

  if (error)
  {
    g_critical ("%s : %s", G_STRLOC, error->message);
    g_clear_error (&error);
  }
}