Ejemplo n.º 1
0
/*
 * call-seq: Notmuch::Database.new(path [, {:create => false, :mode => Notmuch::MODE_READ_ONLY}]) => DB
 *
 * Create or open a notmuch database using the given path.
 *
 * If :create is +true+, create the database instead of opening.
 *
 * The argument :mode specifies the open mode of the database.
 */
VALUE
notmuch_rb_database_initialize (int argc, VALUE *argv, VALUE self)
{
    const char *path;
    int create, mode;
    VALUE pathv, hashv;
    VALUE modev;
    notmuch_database_t *database;
    notmuch_status_t ret;

    /* Check arguments */
    rb_scan_args (argc, argv, "11", &pathv, &hashv);

    SafeStringValue (pathv);
    path = RSTRING_PTR (pathv);

    if (!NIL_P (hashv)) {
	Check_Type (hashv, T_HASH);
	create = RTEST (rb_hash_aref (hashv, ID2SYM (ID_db_create)));
	modev = rb_hash_aref (hashv, ID2SYM (ID_db_mode));
	if (NIL_P (modev))
	    mode = NOTMUCH_DATABASE_MODE_READ_ONLY;
	else if (!FIXNUM_P (modev))
	    rb_raise (rb_eTypeError, ":mode isn't a Fixnum");
	else {
	    mode = FIX2INT (modev);
	    switch (mode) {
	    case NOTMUCH_DATABASE_MODE_READ_ONLY:
	    case NOTMUCH_DATABASE_MODE_READ_WRITE:
		break;
	    default:
		rb_raise ( rb_eTypeError, "Invalid mode");
	    }
	}
    } else {
	create = 0;
	mode = NOTMUCH_DATABASE_MODE_READ_ONLY;
    }

    Check_Type (self, T_DATA);
    if (create)
	ret = notmuch_database_create (path, &database);
    else
	ret = notmuch_database_open (path, mode, &database);
    notmuch_rb_status_raise (ret);

    DATA_PTR (self) = database;

    return self;
}
Ejemplo n.º 2
0
/*
 * call-seq: Notmuch::Database.new(path [, {:create => false, :mode => Notmuch::MODE_READ_ONLY}]) => DB
 *
 * Create or open a notmuch database using the given path.
 *
 * If :create is +true+, create the database instead of opening.
 *
 * The argument :mode specifies the open mode of the database.
 */
VALUE
notmuch_rb_database_initialize(int argc, VALUE *argv, VALUE self)
{
    const char *path;
    int create, mode;
    VALUE pathv, hashv;
    VALUE modev;

#if !defined(RSTRING_PTR)
#define RSTRING_PTR(v) (RSTRING((v))->ptr)
#endif /* !defined(RSTRING_PTR) */

    /* Check arguments */
    rb_scan_args(argc, argv, "11", &pathv, &hashv);

    SafeStringValue(pathv);
    path = RSTRING_PTR(pathv);

    if (!NIL_P(hashv)) {
        Check_Type(hashv, T_HASH);
        create = RTEST(rb_hash_aref(hashv, ID2SYM(ID_db_create)));
        modev = rb_hash_aref(hashv, ID2SYM(ID_db_mode));
        if (NIL_P(modev))
            mode = NOTMUCH_DATABASE_MODE_READ_ONLY;
        else if (!FIXNUM_P(modev))
            rb_raise(rb_eTypeError, ":mode isn't a Fixnum");
        else {
            mode = FIX2INT(modev);
            switch (mode) {
            case NOTMUCH_DATABASE_MODE_READ_ONLY:
            case NOTMUCH_DATABASE_MODE_READ_WRITE:
                break;
            default:
                rb_raise(rb_eTypeError, "Invalid mode");
            }
        }
    }
    else {
        create = 0;
        mode = NOTMUCH_DATABASE_MODE_READ_ONLY;
    }

    Check_Type(self, T_DATA);
    DATA_PTR(self) = create ? notmuch_database_create(path) : notmuch_database_open(path, mode);
    if (!DATA_PTR(self))
        rb_raise(notmuch_rb_eDatabaseError, "Failed to open database");

    return self;
}
Ejemplo n.º 3
0
int
notmuch_new_command (void *ctx, int argc, char *argv[])
{
    notmuch_config_t *config;
    notmuch_database_t *notmuch;
    add_files_state_t add_files_state;
    double elapsed;
    struct timeval tv_now, tv_start;
    int ret = 0;
    struct stat st;
    const char *db_path;
    char *dot_notmuch_path;
    struct sigaction action;
    _filename_node_t *f;
    int renamed_files, removed_files;
    notmuch_status_t status;
    int i;
    notmuch_bool_t timer_is_active = FALSE;

    add_files_state.verbose = 0;
    add_files_state.output_is_a_tty = isatty (fileno (stdout));

    for (i = 0; i < argc && argv[i][0] == '-'; i++) {
	if (STRNCMP_LITERAL (argv[i], "--verbose") == 0) {
	    add_files_state.verbose = 1;
	} else {
	    fprintf (stderr, "Unrecognized option: %s\n", argv[i]);
	    return 1;
	}
    }
    config = notmuch_config_open (ctx, NULL, NULL);
    if (config == NULL)
	return 1;

    add_files_state.new_tags = notmuch_config_get_new_tags (config, &add_files_state.new_tags_length);
    add_files_state.synchronize_flags = notmuch_config_get_maildir_synchronize_flags (config);
    add_files_state.message_ids_to_sync = _filename_list_create (ctx);
    db_path = notmuch_config_get_database_path (config);

    dot_notmuch_path = talloc_asprintf (ctx, "%s/%s", db_path, ".notmuch");

    if (stat (dot_notmuch_path, &st)) {
	int count;

	count = 0;
	count_files (db_path, &count);
	if (interrupted)
	    return 1;

	printf ("Found %d total files (that's not much mail).\n", count);
	notmuch = notmuch_database_create (db_path);
	add_files_state.total_files = count;
    } else {
	notmuch = notmuch_database_open (db_path,
					 NOTMUCH_DATABASE_MODE_READ_WRITE);
	if (notmuch == NULL)
	    return 1;

	if (notmuch_database_needs_upgrade (notmuch)) {
	    printf ("Welcome to a new version of notmuch! Your database will now be upgraded.\n");
	    gettimeofday (&add_files_state.tv_start, NULL);
	    notmuch_database_upgrade (notmuch, upgrade_print_progress,
				      &add_files_state);
	    printf ("Your notmuch database has now been upgraded to database format version %u.\n",
		    notmuch_database_get_version (notmuch));
	}

	add_files_state.total_files = 0;
    }

    if (notmuch == NULL)
	return 1;

    /* Setup our handler for SIGINT. We do this after having
     * potentially done a database upgrade we this interrupt handler
     * won't support. */
    memset (&action, 0, sizeof (struct sigaction));
    action.sa_handler = handle_sigint;
    sigemptyset (&action.sa_mask);
    action.sa_flags = SA_RESTART;
    sigaction (SIGINT, &action, NULL);

    talloc_free (dot_notmuch_path);
    dot_notmuch_path = NULL;

    add_files_state.processed_files = 0;
    add_files_state.added_messages = 0;
    gettimeofday (&add_files_state.tv_start, NULL);

    add_files_state.removed_files = _filename_list_create (ctx);
    add_files_state.removed_directories = _filename_list_create (ctx);

    if (! debugger_is_active () && add_files_state.output_is_a_tty
	&& ! add_files_state.verbose) {
	setup_progress_printing_timer ();
	timer_is_active = TRUE;
    }

    ret = add_files (notmuch, db_path, &add_files_state);

    removed_files = 0;
    renamed_files = 0;
    gettimeofday (&tv_start, NULL);
    for (f = add_files_state.removed_files->head; f; f = f->next) {
	status = notmuch_database_remove_message (notmuch, f->filename);
	if (status == NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID)
	    renamed_files++;
	else
	    removed_files++;
	if (do_print_progress) {
	    do_print_progress = 0;
	    generic_print_progress ("Cleaned up", "messages",
		tv_start, removed_files + renamed_files,
		add_files_state.removed_files->count);
	}
    }

    gettimeofday (&tv_start, NULL);
    for (f = add_files_state.removed_directories->head, i = 0; f; f = f->next, i++) {
	_remove_directory (ctx, notmuch, f->filename,
			   &renamed_files, &removed_files);
	if (do_print_progress) {
	    do_print_progress = 0;
	    generic_print_progress ("Cleaned up", "directories",
		tv_start, i,
		add_files_state.removed_directories->count);
	}
    }

    talloc_free (add_files_state.removed_files);
    talloc_free (add_files_state.removed_directories);

    /* Now that removals are done (hence the database is aware of all
     * renames), we can synchronize maildir_flags to tags for all
     * messages that had new filenames appear on this run. */
    gettimeofday (&tv_start, NULL);
    if (add_files_state.synchronize_flags) {
	_filename_node_t *node;
	notmuch_message_t *message;
	for (node = add_files_state.message_ids_to_sync->head, i = 0;
	     node;
	     node = node->next, i++)
	{
	    message = notmuch_database_find_message (notmuch, node->filename);
	    notmuch_message_maildir_flags_to_tags (message);
	    notmuch_message_destroy (message);
	    if (do_print_progress) {
		do_print_progress = 0;
		generic_print_progress (
		    "Synchronized tags for", "messages",
		    tv_start, i, add_files_state.message_ids_to_sync->count);
	    }
	}
    }

    talloc_free (add_files_state.message_ids_to_sync);
    add_files_state.message_ids_to_sync = NULL;

    if (timer_is_active)
	stop_progress_printing_timer ();

    gettimeofday (&tv_now, NULL);
    elapsed = notmuch_time_elapsed (add_files_state.tv_start,
				    tv_now);

    if (add_files_state.processed_files) {
	printf ("Processed %d %s in ", add_files_state.processed_files,
		add_files_state.processed_files == 1 ?
		"file" : "total files");
	notmuch_time_print_formatted_seconds (elapsed);
	if (elapsed > 1) {
	    printf (" (%d files/sec.).\033[K\n",
		    (int) (add_files_state.processed_files / elapsed));
	} else {
	    printf (".\033[K\n");
	}
    }

    if (add_files_state.added_messages) {
	printf ("Added %d new %s to the database.",
		add_files_state.added_messages,
		add_files_state.added_messages == 1 ?
		"message" : "messages");
    } else {
	printf ("No new mail.");
    }

    if (removed_files) {
	printf (" Removed %d %s.",
		removed_files,
		removed_files == 1 ? "message" : "messages");
    }

    if (renamed_files) {
	printf (" Detected %d file %s.",
		renamed_files,
		renamed_files == 1 ? "rename" : "renames");
    }

    printf ("\n");

    if (ret) {
	printf ("\nNote: At least one error was encountered: %s\n",
		notmuch_status_to_string (ret));
    }

    notmuch_database_close (notmuch);

    return ret || interrupted;
}
int main (int argc, char** argv) {
  GFile              *db_dir, *db_file;
  notmuch_status_t    status;
  notmuch_database_t *db   = NULL;
  notmuch_query_t *query = NULL;
  notmuch_messages_t *messages = NULL;
  notmuch_message_t *message = NULL;
  GMainLoop          *loop = NULL;

  const char *query_string = "date:2014-02-01..";

  if (argc != 2)
  {
    g_warning ("Usage: %s EVOLUTION_MAILDIR", argv[0]);
    return 1;
  }

  db_dir = g_file_new_for_path (argv[1]);
  db_file = g_file_get_child (db_dir, ".notmuch");

  if (!g_file_query_exists (db_dir, NULL))
  {
    g_object_unref (db_dir);
    g_object_unref (db_file);
    g_error ("directory %s does not exists");
    return 2;
  }

  if (!g_file_query_exists (db_file, NULL))
    status = notmuch_database_create (argv[1], &db);
  else
    status = notmuch_database_open (argv[1], NOTMUCH_DATABASE_MODE_READ_WRITE, &db);

  if (status)
  {
    g_error ("Could not open database: %d", status);
    g_object_unref (db_dir);
    g_object_unref (db_file);
    notmuch_database_destroy (db);
    return 3;
  }


  scan_directory (db, db_dir);
  //loop = g_main_loop_new (NULL, FALSE);
  //g_main_loop_run (loop);

  query = notmuch_query_create (db, query_string);

  if (!query) {
    g_error ("Could not create query from string = \"%s\"", query_string);
    notmuch_database_destroy (db);
    g_object_unref (db_file);
    g_object_unref (db_dir);
    return 4;
  }

  g_message ("Query results -\n\n");

  for (messages = notmuch_query_search_messages (query);
         notmuch_messages_valid (messages);
         notmuch_messages_move_to_next (messages)) {

    message = notmuch_messages_get (messages);

    g_message ("Message file: %s", notmuch_message_get_filename (message));
    g_message ("Message ID: %s", notmuch_message_get_message_id (message));
    g_message ("Message Sender: %s", notmuch_message_get_header (message, "from"));
    g_message ("Message Recipients: %s", notmuch_message_get_header (message, "to"));
    g_message ("Message Subject: %s", notmuch_message_get_header (message, "subject"));
    g_message ("Message date: %s\n", notmuch_message_get_header (message, "date"));

    notmuch_message_destroy (message);
  }

  notmuch_query_destroy (query);

  notmuch_database_destroy (db);
  g_object_unref (db_file);
  g_object_unref (db_dir);
  return 0;
}