diff --git a/src/puzzle-downloader.c b/src/puzzle-downloader.c index 772f94428a33ab8da2e9e06d93428240a920f309..e819435a0b68e89a85d05f3977f87fe9528c57db 100644 --- a/src/puzzle-downloader.c +++ b/src/puzzle-downloader.c @@ -641,6 +641,45 @@ run_command (PuzzleDownloader *downloader, * Input Dialogs */ +static DownloaderFormat +file_format_from_file (GFile *file) +{ + g_autofree gchar *contents = NULL; + g_autoptr (GError) error = NULL; + + if (!g_file_load_contents (file, NULL, &contents, NULL, NULL, &error)) + { + g_warning ("Could not read file: %s\n", error->message); + return DOWNLOADER_FORMAT_UNKNOWN; + } + + /* IPUZ files specify their IPUZ version with a URL to the spec. */ + if (strstr (contents, "http://ipuz.org/v2") != NULL) + return DOWNLOADER_FORMAT_IPUZ; + /* PUZ files contain a null-terminated magic string, "ACROSS&DOWN". */ + /* Because it's null-terminated, we can use g_strcmp0. */ + else if ((strlen (contents) == 13) + && (g_strcmp0 (contents + 2, "ACROSS&DOWN") == 0)) + return DOWNLOADER_FORMAT_PUZ; + /* JPZ files begin with an XML header. */ + else if (g_ascii_strncasecmp (contents, "cancel_dialog, adw_dialog_close); + downloader->format = file_format_from_file (source); + if (downloader->format == DOWNLOADER_FORMAT_IPUZ) { g_autofree gchar *uri = NULL; @@ -678,15 +719,12 @@ start_file_import (PuzzleDownloader *downloader) /* We can short circuit the download/conversion step if the file is * local and it's a .ipuz file. */ - /* FIXME(mime): It would be nice to do mime-sniffing here for puz - * files, at least */ /* FIXME(gio): g_file_query_filesystem_info might be a better * way to find out if it's local */ if (strcmp (g_uri_peek_scheme (downloader->import_target_uri), "file") == 0) { - g_autofree char *filename = NULL; - filename = g_filename_from_uri (downloader->import_target_uri, NULL, NULL); - if (filename != NULL && g_str_has_suffix (filename, ".ipuz")) + downloader->format = file_format_from_uri (downloader->import_target_uri); + if (downloader->format == DOWNLOADER_FORMAT_IPUZ) { g_signal_emit (downloader, obj_signals [FINISHED], 0, downloader->import_target_uri, FALSE); g_clear_pointer (&downloader->import_target_uri, g_free); @@ -704,22 +742,9 @@ start_file_import (PuzzleDownloader *downloader) g_warning ("Unable to create a tmp file: %s", error->message); return; } - /* FIXME(mime): we really need to add sniffing */ - basename = g_file_get_basename (source); - if (g_str_has_suffix (basename, ".puz")) - downloader->format = DOWNLOADER_FORMAT_PUZ; - else if (g_str_has_suffix (basename, ".jpz") || - g_str_has_suffix (basename, ".xml")) - downloader->format = DOWNLOADER_FORMAT_JPZ; - else if (g_str_has_suffix (basename, ".xd")) - downloader->format = DOWNLOADER_FORMAT_XD; - else - downloader->format = DOWNLOADER_FORMAT_IPUZ; - - if (downloader->format != DOWNLOADER_FORMAT_IPUZ) - downloader->temp_file = g_file_get_path (destination); downloader_cancel_timeout_add (downloader, 2000, (GSourceFunc) downloader_cancel_timeout_cb); + downloader->temp_file = g_file_get_path (destination); downloader->wait_cancellable = g_cancellable_new (); flags = G_FILE_COPY_OVERWRITE; @@ -776,6 +801,7 @@ run_file_dialog (PuzzleDownloader *downloader) gtk_file_filter_add_pattern (filter, "*.puz"); gtk_file_filter_add_pattern (filter, "*.xml"); gtk_file_filter_add_pattern (filter, "*.jpz"); + gtk_file_filter_add_pattern (filter, "*.jpuz"); gtk_file_filter_add_pattern (filter, "*.xd"); g_list_store_append (filters, filter); gtk_file_dialog_set_default_filter (file_dialog, filter); @@ -806,6 +832,12 @@ run_file_dialog (PuzzleDownloader *downloader) g_list_store_append (filters, filter); g_object_unref (filter); + filter = gtk_file_filter_new(); + gtk_file_filter_set_name(filter, "All Files"); + gtk_file_filter_add_pattern(filter, "*"); + g_list_store_append (filters, filter); + g_object_unref (filter); + gtk_file_dialog_set_filters (file_dialog, G_LIST_MODEL (filters)); gtk_file_dialog_open (file_dialog, downloader->parent_window, NULL,