gchar * mod_cfg_get_str (GKeyFile *f, const gchar *sec, const gchar *key, sat_cfg_str_e p) { GError *error = NULL; gchar *param; /* check whether parameter is present in GKeyFile */ if (g_key_file_has_key (f, sec, key, NULL)) { param = g_key_file_get_string (f, sec, key, &error); if (error != NULL) { sat_log_log (SAT_LOG_LEVEL_ERROR, _("%s: Failed to read string (%s)"), __FUNCTION__, error->message); g_clear_error (&error); /* get a timeout from global config */ param = sat_cfg_get_str (p); } } /* get value from sat-cfg */ else { param = sat_cfg_get_str (p); /* sat_log_log (SAT_LOG_LEVEL_DEBUG, */ /* _("%s: String not found, using default (%s)"), */ /* __FUNCTION__, param); */ } return param; }
/* AOS/LOS; convert julian date to string */ static void time_cell_data_function (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer column) { gdouble number; gchar buff[TIME_FORMAT_MAX_LENGTH]; gchar *fmtstr; guint coli = GPOINTER_TO_UINT (column); (void) col; /* avoid unused parameter compiler warning */ gtk_tree_model_get (model, iter, coli, &number, -1); if (number == 0.0) { g_object_set (renderer, "text", "--- N/A ---", NULL); } else { /* format the number */ fmtstr = sat_cfg_get_str (SAT_CFG_STR_TIME_FORMAT); daynum_to_str (buff, TIME_FORMAT_MAX_LENGTH, fmtstr, number); g_object_set (renderer, "text", buff, NULL); g_free (fmtstr); } }
/** \brief User pressed cancel. Any changes to config must be cancelled. */ void sat_pref_layout_cancel (GKeyFile *cfg) { gchar *str; str = sat_cfg_get_str (SAT_CFG_STR_MODULE_GRID); gtk_entry_set_text (GTK_ENTRY (gridstr), str); g_free (str); dirty = FALSE; }
/** * Reset settings. * @param button The RESET button. * @param cfg Pointer to the module config or NULL in global mode. * * This function is called when the user clicks on the RESET button. In global mode * (when cfg = NULL) the function will reset the settings to the efault values, while * in "local" mode (when cfg != NULL) the function will reset the module settings to * the global settings. This is done by removing the corresponding key from the GKeyFile. */ static void reset_cb(GtkWidget * button, gpointer cfg) { guint i, sel = PREDEF_NUM - 1; gchar *buffer; (void)button; /* views */ if (cfg == NULL) { /* global mode, get defaults */ buffer = sat_cfg_get_str_def(SAT_CFG_STR_MODULE_GRID); gtk_entry_set_text(GTK_ENTRY(gridstr), buffer); } else { /* local mode, get global value */ buffer = sat_cfg_get_str(SAT_CFG_STR_MODULE_GRID); gtk_entry_set_text(GTK_ENTRY(gridstr), buffer); } /* findcombo box setting */ for (i = 0; i < PREDEF_NUM; i++) { /* check if this layout corresponds to the settings */ if (!g_ascii_strcasecmp(buffer, predef_layout[i][0])) { sel = i; } } gtk_combo_box_set_active(GTK_COMBO_BOX(selector), sel); g_free(buffer); /* window placement settings */ if (cfg == NULL) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mwin), sat_cfg_get_bool_def (SAT_CFG_BOOL_MAIN_WIN_POS)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mod), sat_cfg_get_bool_def (SAT_CFG_BOOL_MOD_WIN_POS)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(state), sat_cfg_get_bool_def (SAT_CFG_BOOL_MOD_STATE)); } /* reset flags */ reset = TRUE; dirty = FALSE; }
/* 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(); }
/** * Read QTH file and add data to list store. * @param liststore The GtkListStore where the data should be stored. * @param filename The full name of the qth file. * @return 1 if read is successful, 0 if an error occurs. * * The function uses the gtk-sat-data infrastructure to read the qth * data from the specified file. * * There is a little challenge here. First, we want to read the data from * the .qth files and store them in the list store. To do this we use a * qth_t structure, which can be populated using gtk_sat_data_read_qth. * Then, when the configuration is finished and the user presses "OK", we * want to write all the data back to the .qth files. To do that, we create * an up-to-date qth_t data structure and pass it to the gtk_sat_data_write_qth * function, which will take care of updating the GKeyFile data structure and * writing the contents to the .qth file. */ static guint read_qth_file(GtkListStore * liststore, gchar * filename) { GtkTreeIter item; /* new item added to the list store */ qth_t *qth; /* qth data structure */ gchar *defqth; gboolean is_default = FALSE; gchar *fname; gint dispalt; /* displayed altitude */ if ((qth = g_try_new0(qth_t, 1)) == NULL) { sat_log_log(SAT_LOG_LEVEL_ERROR, _("%s:%d: Failed to allocate memory!\n"), __FILE__, __LINE__); return FALSE; } /* read data from file */ if (!qth_data_read(filename, qth)) { g_free(qth); return FALSE; } /* calculate QRA locator */ gint retcode; qth->qra = g_malloc(7); retcode = longlat2locator(qth->lon, qth->lat, qth->qra, 3); if (retcode != RIG_OK) { sat_log_log(SAT_LOG_LEVEL_ERROR, _("%s:%d: Could not convert (%.2f,%.2f) to QRA."), __FILE__, __LINE__, qth->lat, qth->lon); qth->qra[0] = '\0'; } else { qth->qra[6] = '\0'; sat_log_log(SAT_LOG_LEVEL_DEBUG, _("%s:%d: QRA locator is %s"), __FILE__, __LINE__, qth->qra); } /* is this the default qth? */ defqth = sat_cfg_get_str(SAT_CFG_STR_DEF_QTH); if (g_str_has_suffix(filename, defqth)) { is_default = TRUE; sat_log_log(SAT_LOG_LEVEL_INFO, _("%s:%d: This appears to be the default QTH."), __FILE__, __LINE__); } g_free(defqth); /* check wehter we are using imperial or metric system; in case of imperial we have to convert altitude from meters to feet. note: the internat data are always kept in metric and only the displayed numbers are converted. Therefore, we use a dedicated var 'dispalt' */ /* NO, ONLY DISPLAY WIDGETS WILL BE AFFECTED BY THIS SETTING */ if (sat_cfg_get_bool(SAT_CFG_BOOL_USE_IMPERIAL)) { dispalt = (gint) M_TO_FT(qth->alt); } else { dispalt = (gint) qth->alt; } /* strip file name; we don't need the whole path */ fname = g_path_get_basename(filename); /* we now have all necessary data in the qth_t structure; add the data to the list store */ gtk_list_store_append(liststore, &item); gtk_list_store_set(liststore, &item, QTH_LIST_COL_NAME, qth->name, QTH_LIST_COL_LOC, qth->loc, QTH_LIST_COL_DESC, qth->desc, QTH_LIST_COL_LAT, qth->lat, QTH_LIST_COL_LON, qth->lon, QTH_LIST_COL_ALT, dispalt, QTH_LIST_COL_QRA, qth->qra, QTH_LIST_COL_WX, qth->wx, QTH_LIST_COL_DEF, is_default, QTH_LIST_COL_TYPE, qth->type, QTH_LIST_COL_GPSD_SERVER, qth->gpsd_server, QTH_LIST_COL_GPSD_PORT, qth->gpsd_port, -1); g_free(fname); /* we are finished with this qth, free it */ qth_data_free(qth); return TRUE; }
/* BBBBB.BBBBBBBB] - Epoch Time -- 2-digit year, followed by 3-digit sequential day of the year, followed by the time represented as the fractional portion of one day, but... we now have the converted fields, tle->epoch_year, tle->epoch_day and tle->epoch_fod */ static gchar *epoch_to_str(sat_t * sat) { GDate *epd; guint h, m, s, sec; gchar *buff; gchar *fmt; struct tm tms; time_t t; guint size; /* http://celestrak.com/columns/v04n03/#FAQ02 ... While talking about the epoch, this is perhaps a good place to answer the other time-related questions. First, how is the epoch time format interpreted? This question is best answered by using an example. An epoch of 98001.00000000 corresponds to 0000 UT on 1998 January 01st in other words, midnight between 1997 December 31 and 1998 January 01. An epoch of 98000.00000000 would actually correspond to the beginning of 1997 December 31st strange as that might seem. Note that the epoch day starts at UT midnight (not noon) and that all times are measured mean solar rather than sidereal time units (the answer to our third question). */ epd = g_date_new_dmy(1, 1, sat->tle.epoch_year); g_date_add_days(epd, sat->tle.epoch_day - 1); /* convert date to struct tm */ g_date_to_struct_tm(epd, &tms); /* add HMS */ sec = (guint) floor(sat->tle.epoch_fod * 86400); /* fraction of day in seconds */ /* hour */ h = (guint) floor(sec / 3600); tms.tm_hour = h; /* minutes */ m = (guint) floor((sec - (h * 3600)) / 60); tms.tm_min = m; s = (guint) floor(sec - (h * 3600) - (m * 60)); tms.tm_sec = s; /* get format string */ fmt = sat_cfg_get_str(SAT_CFG_STR_TIME_FORMAT); /* format either local time or UTC depending on check box */ t = mktime(&tms); buff = g_try_malloc(51); if (sat_cfg_get_bool(SAT_CFG_BOOL_USE_LOCAL_TIME)) size = strftime(buff, 50, fmt, localtime(&t)); else size = strftime(buff, 50, fmt, gmtime(&t)); if (size < 50) buff[size] = '\0'; else buff[50] = '\0'; g_date_free(epd); g_free(fmt); return buff; }
/** \brief Create layout selector. */ static void create_layout_selector (GKeyFile *cfg, GtkTable *table) { GtkWidget *label; gchar *buffer; gchar *thumbfile; guint i,sel=PREDEF_NUM-1; /* get the current settings */ if (cfg != NULL) { buffer = mod_cfg_get_str (cfg, MOD_CFG_GLOBAL_SECTION, MOD_CFG_GRID, SAT_CFG_STR_MODULE_GRID); } else { buffer = sat_cfg_get_str (SAT_CFG_STR_MODULE_GRID); } /* create header */ label = gtk_label_new (_("Select layout:")); gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5); gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_FILL, 5, 0); /* layout selector */ selector = gtk_combo_box_new_text (); gtk_table_attach (GTK_TABLE (table), selector, 1, 3, 0, 1, GTK_FILL, GTK_SHRINK, 0, 0); for (i = 0; i < PREDEF_NUM; i++) { /* append default layout string to combo box */ gtk_combo_box_append_text (GTK_COMBO_BOX (selector), predef_layout[i][1]); /* check if this layout corresponds to the settings */ if (!g_ascii_strcasecmp (buffer, predef_layout[i][0])) { sel = i; } } /* select settings */ gtk_combo_box_set_active (GTK_COMBO_BOX (selector), sel); /* connect signal handler */ g_signal_connect (selector, "changed", G_CALLBACK (layout_selected_cb), NULL); /* layout preview thumbnail */ thumbfile = thumb_file_from_sel (sel); thumb = gtk_image_new_from_file (thumbfile); g_free (thumbfile); gtk_table_attach (GTK_TABLE (table), thumb, 1, 3, 1, 2, GTK_EXPAND, GTK_EXPAND, 0, 5); /* layout string */ label = gtk_label_new (_("Layout code:")); gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5); gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3, GTK_SHRINK | GTK_FILL, GTK_EXPAND | GTK_FILL, 5, 0); gridstr = gtk_entry_new (); gtk_entry_set_text (GTK_ENTRY (gridstr), buffer); g_free (buffer); gtk_widget_set_tooltip_text (gridstr, _("This entry holds the layout code for the module.\n"\ "Consult the user manual for how to create custom layouts "\ "using layout codes.")); /* disable if it is a predefined layout */ if (sel < PREDEF_NUM-1) { gtk_widget_set_sensitive (gridstr, FALSE); } /* connect changed signal handler */ gridstr_sigid = g_signal_connect (gridstr, "changed", G_CALLBACK (layout_code_changed), NULL); gtk_table_attach_defaults (GTK_TABLE (table), gridstr, 1, 4, 2, 3); }
/** \brief Create and initialise module manger. * \return The main module container widget (GtkNotebook). * * This function creates and initialises the module manager widget, which * consist of a GtkNotebook container. Before returning the container to the * caller, the function checks whether any modules should be restored (ie. * openend), if yes, it creates them and adds them to the notebook. * */ GtkWidget * mod_mgr_create (void) { gchar *openmods = NULL; gchar **mods; gint count,i; GtkWidget *module; gchar *modfile; gchar *confdir; /* create notebook */ nbook = gtk_notebook_new (); gtk_notebook_set_scrollable (GTK_NOTEBOOK (nbook), TRUE); gtk_notebook_popup_enable (GTK_NOTEBOOK (nbook)); g_object_set (G_OBJECT (nbook), "homogeneous", TRUE, NULL); g_signal_connect (G_OBJECT (nbook), "switch-page", G_CALLBACK (switch_page_cb), NULL); /* get list of modules which should be open */ openmods = sat_cfg_get_str (SAT_CFG_STR_OPEN_MODULES); if (openmods) { mods = g_strsplit (openmods, ";", 0); count = g_strv_length (mods); for (i = 0; i < count; i++) { /* get data file name */ confdir = get_modules_dir (); modfile = g_strconcat (confdir, G_DIR_SEPARATOR_S, mods[i], ".mod", NULL); g_free (confdir); /* create module */ module = gtk_sat_module_new (modfile); if (IS_GTK_SAT_MODULE (module)) { /* if module state was window or user does not want to restore the state of the modules, pack the module into the notebook */ if ((GTK_SAT_MODULE (module)->state == GTK_SAT_MOD_STATE_DOCKED) || !sat_cfg_get_bool (SAT_CFG_BOOL_MOD_STATE)) { mod_mgr_add_module (module, TRUE); } else { mod_mgr_add_module (module, FALSE); create_module_window (module); } } else { sat_log_log (SAT_LOG_LEVEL_ERROR, _("%s: Failed to restore %s"), __FUNCTION__, mods[i]); } g_free (modfile); } g_strfreev (mods); g_free (openmods); /* disable tabs if only one page in notebook */ if ((gtk_notebook_get_n_pages (GTK_NOTEBOOK(nbook))) == 1) { gtk_notebook_set_show_tabs (GTK_NOTEBOOK (nbook), FALSE); } else { gtk_notebook_set_show_tabs (GTK_NOTEBOOK (nbook), TRUE); } } else { sat_log_log (SAT_LOG_LEVEL_MSG, _("%s: No modules have to be restored."), __FUNCTION__); } return nbook; }
/** \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); }
/** \brief Create and initialise widgets. * */ GtkWidget *sat_pref_help_create () { GtkWidget *vbox; /* vbox containing the list part and the details part */ GtkWidget *table; GtkWidget *label; guint i; gint idx; vbox = gtk_vbox_new (FALSE, 10); gtk_container_set_border_width (GTK_CONTAINER (vbox), 20); /* header */ label = gtk_label_new (NULL); gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); gtk_label_set_markup (GTK_LABEL (label), _("<b>Html Browser:</b>")); gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 0); /* table for combo box and command string */ table = gtk_table_new (2, 2, TRUE); gtk_table_set_col_spacings (GTK_TABLE (table), 10); gtk_table_set_row_spacings (GTK_TABLE (table), 10); gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0); /* browser type */ label = gtk_label_new (_("Browser type:")); gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 0); combo = gtk_combo_box_new_text (); for (i = 0; i < BROWSER_TYPE_NUM; i++) gtk_combo_box_append_text (GTK_COMBO_BOX (combo), sat_help[i].type); gtk_table_attach (GTK_TABLE (table), combo, 1, 2, 0, 1, GTK_FILL, GTK_FILL, 0, 0); g_signal_connect (combo, "changed", G_CALLBACK (browser_changed_cb), NULL); /* command string */ label = gtk_label_new (_("Command string:")); gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 0, 0); entry = gtk_entry_new (); gtk_entry_set_max_length (GTK_ENTRY (entry), 100); gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 1, 2, GTK_FILL, GTK_FILL, 0, 0); /* get curreent browser */ idx = sat_cfg_get_int (SAT_CFG_INT_WEB_BROWSER_TYPE); /* some sanity check before accessing the arrays ;-) */ if ((idx < BROWSER_TYPE_NONE) || (idx >= BROWSER_TYPE_NUM)) { idx = BROWSER_TYPE_NONE; } gtk_combo_box_set_active (GTK_COMBO_BOX (combo), idx); if (idx == BROWSER_TYPE_OTHER) gtk_entry_set_text (GTK_ENTRY (entry), sat_cfg_get_str (SAT_CFG_STR_WEB_BROWSER)); /** FIXME */ gtk_widget_set_sensitive (vbox, FALSE); dirty = FALSE; return vbox; }
/** * Update TRSP 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 trsp_update_from_network(gboolean silent, GtkWidget * progress, GtkWidget * label1, GtkWidget * label2) { static GMutex trsp_in_progress; gchar *server; gchar *proxy = NULL; gchar *freq_file; gchar *file_url; gchar *locfile_trsp; gchar *userconfdir; CURL *curl; CURLcode res; gdouble fraction; FILE *outfile; gchar *cache; gchar *text; guint success = 0; /* no. of successfull downloads */ /* bail out if we are already in an update process */ if (g_mutex_trylock(&trsp_in_progress) == FALSE) { sat_log_log(SAT_LOG_LEVEL_ERROR, _("%s: A frequency update process is already running"), __func__); return; } /* get list with modes */ modes_update_from_network(); /* get server, proxy, and list of files */ //server = sprintf("%stransmitters/?format=json", sat_cfg_get_str(SAT_CFG_STR_TRSP_SERVER)); server = sat_cfg_get_str(SAT_CFG_STR_TRSP_SERVER); proxy = sat_cfg_get_str(SAT_CFG_STR_TRSP_PROXY); freq_file = sat_cfg_get_str(SAT_CFG_STR_TRSP_FREQ_FILE); /* 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 */ /* set URL */ file_url = g_strconcat(server, freq_file, NULL); curl_easy_setopt(curl, CURLOPT_URL, file_url); sat_log_log(SAT_LOG_LEVEL_INFO, _("%s: Ready to fetch transponder list from %s"), __func__, file_url); /* set activity message */ if (!silent && (label1 != NULL)) { text = g_strdup_printf(_("Fetching %s"), "transmitters.json"); 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_trsp = g_strconcat(userconfdir, G_DIR_SEPARATOR_S, "trsp", G_DIR_SEPARATOR_S, "transmitters.json", NULL); sat_log_log(SAT_LOG_LEVEL_INFO, _("%s: File to open %s "), __func__, locfile_trsp); outfile = g_fopen(locfile_trsp, "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)"), __func__, file_url, curl_easy_strerror(res)); } else { sat_log_log(SAT_LOG_LEVEL_INFO, _("%s: Successfully fetched %s"), __func__, file_url); success++; } fclose(outfile); } else { sat_log_log(SAT_LOG_LEVEL_INFO, _("%s: Failed to open %s preventing update"), __func__, locfile_trsp); } /* update progress indicator */ if (!silent && (progress != NULL)) { /* complete download corresponds to 50% */ fraction = 1; 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(file_url); g_free(server); g_free(freq_file); g_free(proxy); 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..."), __func__, success); /* call update_from_files */ cache = sat_file_name("cache"); trsp_update_files(locfile_trsp); g_free(cache); } else { sat_log_log(SAT_LOG_LEVEL_ERROR, _("%s: Could not fetch frequency files from network"), __func__); } g_mutex_unlock(&trsp_in_progress); }
/** Update MODES files from network. */ void modes_update_from_network() { gchar *server; gchar *proxy = NULL; gchar *modes_file; gchar *file_url; gchar *locfile; gchar *userconfdir; CURL *curl; CURLcode res; FILE *outfile; guint success = 0; /* no. of successfull downloads */ server = sat_cfg_get_str(SAT_CFG_STR_TRSP_SERVER); proxy = sat_cfg_get_str(SAT_CFG_STR_TRSP_PROXY); modes_file = sat_cfg_get_str(SAT_CFG_STR_TRSP_MODE_FILE); /* 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 */ /* set URL */ file_url = g_strconcat(server, modes_file, NULL); curl_easy_setopt(curl, CURLOPT_URL, file_url); sat_log_log(SAT_LOG_LEVEL_INFO, _("%s: Ready to fetch modes list from %s"), __func__, file_url); /* create local cache file */ userconfdir = get_user_conf_dir(); locfile = g_strconcat(userconfdir, G_DIR_SEPARATOR_S, "trsp", G_DIR_SEPARATOR_S, "modes.json", NULL); sat_log_log(SAT_LOG_LEVEL_INFO, _("%s: File to open %s "), __func__, locfile); 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)"), __func__, file_url, curl_easy_strerror(res)); } else { sat_log_log(SAT_LOG_LEVEL_INFO, _("%s: Successfully fetched %s"), __func__, file_url); success++; } fclose(outfile); } else { sat_log_log(SAT_LOG_LEVEL_INFO, _("%s: Failed to open %s preventing update"), __func__, locfile); } g_free(userconfdir); g_free(file_url); g_free(server); g_free(proxy); g_free(modes_file); 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..."), __func__, success); //here we can get the modes json file into memory as hashmap.. //g_free(cache); } else { sat_log_log(SAT_LOG_LEVEL_ERROR, _("%s: Could not fetch frequency files from network"), __func__); } }