/* Update TLE from local files */ static void menubar_tle_local_cb(GtkWidget * widget, gpointer data) { gchar *dir; /* selected directory */ GtkWidget *dir_chooser; /* directory chooser button */ GtkWidget *dialog; /* dialog window */ GtkWidget *label; /* misc labels */ GtkWidget *progress; /* progress indicator */ GtkWidget *label1, *label2; /* activitity and stats labels */ GtkWidget *box; gint response; /* dialog response */ gboolean doupdate = FALSE; (void)widget; (void)data; /* get last used directory */ dir = sat_cfg_get_str(SAT_CFG_STR_TLE_FILE_DIR); /* if there is no last used dir fall back to $HOME */ if (dir == NULL) { dir = g_strdup(g_get_home_dir()); } /* create file chooser */ dir_chooser = gtk_file_chooser_button_new(_("Select directory"), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER); gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dir_chooser), dir); g_free(dir); /* create label */ label = gtk_label_new(_("Select TLE directory:")); /* pack label and chooser into a hbox */ box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_set_homogeneous(GTK_BOX(box), FALSE); gtk_box_pack_start(GTK_BOX(box), label, TRUE, TRUE, 5); gtk_box_pack_start(GTK_BOX(box), dir_chooser, TRUE, TRUE, 5); gtk_widget_show_all(box); /* create the dalog */ dialog = gtk_dialog_new_with_buttons(_("Update TLE from files"), GTK_WINDOW(app), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, "_Cancel", GTK_RESPONSE_REJECT, "_OK", GTK_RESPONSE_ACCEPT, NULL); gtk_box_pack_start(GTK_BOX (gtk_dialog_get_content_area(GTK_DIALOG(dialog))), box, TRUE, TRUE, 30); response = gtk_dialog_run(GTK_DIALOG(dialog)); if (response == GTK_RESPONSE_ACCEPT) doupdate = TRUE; else doupdate = FALSE; /* get directory before we destroy the dialog */ dir = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dir_chooser)); /* nuke the dialog */ gtk_widget_destroy(dialog); if (doupdate) { sat_log_log(SAT_LOG_LEVEL_INFO, _("%s: Running TLE update from %s"), __func__, dir); /* store last used TLE dir */ sat_cfg_set_str(SAT_CFG_STR_TLE_FILE_DIR, dir); /* create new dialog with progress indicator */ dialog = gtk_dialog_new_with_buttons(_("TLE Update"), GTK_WINDOW(app), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, "_Close", GTK_RESPONSE_ACCEPT, NULL); gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT, FALSE); /* create a vbox */ box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_box_set_homogeneous(GTK_BOX(box), FALSE); gtk_container_set_border_width(GTK_CONTAINER(box), 20); /* add static label */ label = gtk_label_new(NULL); g_object_set(label, "xalign", 0.5, "yalign", 0.5, NULL); gtk_label_set_markup(GTK_LABEL(label), _("<b>Updating TLE files from files</b>")); gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0); /* activity label */ label1 = gtk_label_new("..."); g_object_set(label1, "xalign", 0.5, "yalign", 0.5, NULL); gtk_box_pack_start(GTK_BOX(box), label1, FALSE, FALSE, 0); /* add progress bar */ progress = gtk_progress_bar_new(); gtk_box_pack_start(GTK_BOX(box), progress, FALSE, FALSE, 10); /* statistics */ label2 = gtk_label_new(_("Satellites updated:\t 0\n" "Satellites skipped:\t 0\n" "Missing Satellites:\t 0\n")); gtk_box_pack_start(GTK_BOX(box), label2, TRUE, TRUE, 0); /* finalise dialog */ gtk_container_add(GTK_CONTAINER (gtk_dialog_get_content_area(GTK_DIALOG(dialog))), box); g_signal_connect_swapped(dialog, "response", G_CALLBACK(gtk_widget_destroy), dialog); gtk_widget_show_all(dialog); /* Force the drawing queue to be processed otherwise the dialog may not appear before we enter the TLE updating func - see Gtk+ FAQ http://www.gtk.org/faq/#AEN602 */ while (g_main_context_iteration(NULL, FALSE)); /* update TLE */ tle_update_from_files(dir, NULL, FALSE, progress, label1, label2); /* set progress bar to 100% */ gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress), 1.0); gtk_label_set_text(GTK_LABEL(label1), _("Finished")); /* enable close button */ gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT, TRUE); } if (dir) g_free(dir); /* reload satellites */ mod_mgr_reload_sats(); }
/** \brief Update TLE files from network. * \param silent TRUE if function should execute without graphical status indicator. * \param progress Pointer to a GtkProgressBar progress indicator (can be NULL) * \param label1 GtkLabel for activity string. * \param label2 GtkLabel for statistics string. */ void tle_update_from_network (gboolean silent, GtkWidget *progress, GtkWidget *label1, GtkWidget *label2) { static GMutex tle_in_progress; gchar *server; gchar *proxy = NULL; gchar *files_tmp; gchar **files; guint numfiles,i; gchar *curfile; gchar *locfile; gchar *userconfdir; CURL *curl; CURLcode res; gdouble fraction,start=0; FILE *outfile; GDir *dir; gchar *cache; const gchar *fname; gchar *text; GError *err = NULL; guint success = 0; /* no. of successfull downloads */ /* bail out if we are already in an update process */ if (g_mutex_trylock(&tle_in_progress) == FALSE) { sat_log_log (SAT_LOG_LEVEL_ERROR, _("%s: A TLE update process is already running. Aborting."), __FUNCTION__); return; } /* get server, proxy, and list of files */ server = sat_cfg_get_str (SAT_CFG_STR_TLE_SERVER); proxy = sat_cfg_get_str (SAT_CFG_STR_TLE_PROXY); files_tmp = sat_cfg_get_str (SAT_CFG_STR_TLE_FILES); files = g_strsplit (files_tmp, ";", 0); numfiles = g_strv_length (files); if (numfiles < 1) { sat_log_log (SAT_LOG_LEVEL_ERROR, _("%s: No files to fetch from network."), __FUNCTION__); /* set activity string, so user knows why nothing happens */ if (!silent && (label1 != NULL)) { gtk_label_set_text (GTK_LABEL (label1), _("No files to fetch from network")); } } else { /* initialise progress bar */ if (!silent && (progress != NULL)) start = gtk_progress_bar_get_fraction (GTK_PROGRESS_BAR (progress)); /* initialise curl */ curl = curl_easy_init(); if (proxy != NULL) curl_easy_setopt (curl, CURLOPT_PROXY, proxy); curl_easy_setopt (curl, CURLOPT_USERAGENT, "gpredict/curl"); curl_easy_setopt (curl, CURLOPT_CONNECTTIMEOUT, 10); /* get files */ for (i = 0; i < numfiles; i++) { /* set URL */ curfile = g_strconcat (server, files[i], NULL); curl_easy_setopt (curl, CURLOPT_URL, curfile); /* set activity message */ if (!silent && (label1 != NULL)) { text = g_strdup_printf (_("Fetching %s"), files[i]); gtk_label_set_text (GTK_LABEL (label1), text); g_free (text); /* Force the drawing queue to be processed otherwise there will not be any visual feedback, ie. frozen GUI - see Gtk+ FAQ http://www.gtk.org/faq/#AEN602 */ while (g_main_context_iteration (NULL, FALSE)); } /* create local cache file */ userconfdir = get_user_conf_dir (); locfile = g_strconcat (userconfdir, G_DIR_SEPARATOR_S, "satdata", G_DIR_SEPARATOR_S, "cache", G_DIR_SEPARATOR_S, files[i], NULL); outfile = g_fopen (locfile, "wb"); if (outfile != NULL) { curl_easy_setopt (curl, CURLOPT_WRITEDATA, outfile); curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, my_write_func); /* get file */ res = curl_easy_perform (curl); if (res != CURLE_OK) { sat_log_log (SAT_LOG_LEVEL_ERROR, _("%s: Error fetching %s (%s)"), __FUNCTION__, curfile, curl_easy_strerror (res)); } else { sat_log_log (SAT_LOG_LEVEL_INFO, _("%s: Successfully fetched %s"), __FUNCTION__, curfile); success++; } fclose (outfile); } else { sat_log_log (SAT_LOG_LEVEL_INFO, _("%s: Failed to open %s preventing update"), __FUNCTION__, locfile); } /* update progress indicator */ if (!silent && (progress != NULL)) { /* complete download corresponds to 50% */ fraction = start + (0.5-start) * i / (1.0 * numfiles); gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progress), fraction); /* Force the drawing queue to be processed otherwise there will not be any visual feedback, ie. frozen GUI - see Gtk+ FAQ http://www.gtk.org/faq/#AEN602 */ while (g_main_context_iteration (NULL, FALSE)); } g_free (userconfdir); g_free (curfile); g_free (locfile); } curl_easy_cleanup (curl); /* continue update if we have fetched at least one file */ if (success > 0) { sat_log_log (SAT_LOG_LEVEL_INFO, _("%s: Fetched %d files from network; updating..."), __FUNCTION__, success); /* call update_from_files */ cache = sat_file_name ("cache"); tle_update_from_files (cache, NULL, silent, progress, label1, label2); g_free (cache); } else { sat_log_log (SAT_LOG_LEVEL_ERROR, _("%s: Could not fetch any new TLE files from network; aborting..."), __FUNCTION__); } } /* clear cache and memory */ g_free (server); g_strfreev (files); g_free (files_tmp); if (proxy != NULL) g_free (proxy); /* open cache */ cache = sat_file_name ("cache"); dir = g_dir_open (cache, 0, &err); if (err != NULL) { /* send an error message */ sat_log_log (SAT_LOG_LEVEL_ERROR, _("%s: Error opening %s (%s)"), __FUNCTION__, dir, err->message); g_clear_error (&err); } else { /* delete files in cache one by one */ while ((fname = g_dir_read_name (dir)) != NULL) { locfile = g_strconcat (cache, G_DIR_SEPARATOR_S, fname, NULL); g_remove (locfile); g_free (locfile); } /* close cache */ g_dir_close (dir); } g_free (cache); g_mutex_unlock(&tle_in_progress); }