Switch to using complete URLs for TLE update

This changes from storing one server and a number of files to storing complete
URLs, allowing to use more than one server. An attempt has been made to import
existing config records so that existing users shouldn't notice any difference.

New users will only have the single AMSAT source we are switching to.

On the UI side we switch to using a list for the URLs instead of direct display
of the ";" separated list.
This commit is contained in:
Alexandru Csete 2017-01-18 21:05:01 +01:00
parent 0829add35f
commit a06e9cd2ea
4 changed files with 270 additions and 108 deletions

View file

@ -3,8 +3,6 @@
Copyright (C) 2001-2017 Alexandru Csete, OZ9AEC.
Authors: Alexandru Csete <oz9aec@gmail.com>
Comments, questions and bugreports should be submitted via
http://sourceforge.net/projects/gpredict/
More details can be found at the project home page:
@ -139,8 +137,8 @@ sat_cfg_bool_t sat_cfg_bool[SAT_CFG_BOOL_NUM] = {
/** Array containing the integer configuration parameters */
sat_cfg_int_t sat_cfg_int[SAT_CFG_INT_NUM] = {
{"VERSION", "MAJOR", 0},
{"VERSION", "MINOR", 0},
{"VERSION", "MAJOR", 1},
{"VERSION", "MINOR", 3},
{"MODULES", "DATA_TIMEOUT", 300},
{"MODULES", "LAYOUT", 2}, /* FIXME */
{"MODULES", "VIEW_1", GTK_SAT_MOD_VIEW_MAP}, /* FIXME */
@ -234,6 +232,8 @@ sat_cfg_str_t sat_cfg_str[SAT_CFG_STR_NUM] = {
"sarsat.txt;sbas.txt;science.txt;tdrss.txt;tle-new.txt;visual.txt;weather.txt;"
"x-comm.txt"},
{"TLE", "PROXY", NULL},
{"TLE", "URLS",
"http://www.amsat.org/amsat/ftp/keps/current/nasabare.txt"},
{"TLE", "FILE_DIR", NULL},
{"PREDICT", "SAVE_DIR", NULL}
};
@ -294,7 +294,45 @@ guint sat_cfg_load()
{
sat_cfg_reset_str(SAT_CFG_STR_TLE_FILES);
sat_cfg_set_int(SAT_CFG_INT_VERSION_MAJOR, 1);
sat_cfg_set_int(SAT_CFG_INT_VERSION_MINOR, 1);
sat_cfg_set_int(SAT_CFG_INT_VERSION_MINOR, 4);
}
else if (cfg_ver < 0x0104)
{
/* Version 1.4 replaces TLE_SERVER and TLE_FILES with TLE_URLS,
* so import TLE_SERVER and FILES if they exist.
*/
gchar *urls = NULL;
gchar *buff;
gchar *tle_srv = sat_cfg_get_str(SAT_CFG_STR_TLE_SERVER);
gchar *tle_fstr = sat_cfg_get_str(SAT_CFG_STR_TLE_FILES);
gchar **tle_fvec = g_strsplit(tle_fstr, ";", 0);
int i;
for (i = 0; i < g_strv_length(tle_fvec); i++)
{
if (i > 0)
{
buff = g_strdup_printf("%s;%s/%s", urls, tle_srv, tle_fvec[i]);
g_free(urls);
}
else
{
buff = g_strdup_printf("%s/%s", tle_srv, tle_fvec[i]);
}
urls = g_strdup(buff);
g_free(buff);
}
if (urls)
sat_cfg_set_str(SAT_CFG_STR_TLE_URLS, urls);
//sat_cfg_reset_str(SAT_CFG_STR_TLE_SERVER);
//sat_cfg_reset_str(SAT_CFG_STR_TLE_FILES);
g_free(urls);
g_free(tle_srv);
g_free(tle_fstr);
g_strfreev(tle_fvec);
sat_cfg_set_int(SAT_CFG_INT_VERSION_MAJOR, 1);
sat_cfg_set_int(SAT_CFG_INT_VERSION_MINOR, 4);
}
return 0;

View file

@ -3,8 +3,6 @@
Copyright (C) 2001-2017 Alexandru Csete, OZ9AEC.
Authors: Alexandru Csete <oz9aec@gmail.com>
Comments, questions and bugreports should be submitted via
http://sourceforge.net/projects/gpredict/
More details can be found at the project home page:
@ -147,9 +145,10 @@ typedef enum {
SAT_CFG_STR_TRSP_FREQ_FILE, /*!< The file with frequency data on the server (since 1.4) */
SAT_CFG_STR_TRSP_MODE_FILE, /*!< The file with mode descriptions on the server (since 1.4) */
SAT_CFG_STR_TRSP_PROXY, /*!< Proxy server. */
SAT_CFG_STR_TLE_SERVER, /*!< Server for TLE updates. */
SAT_CFG_STR_TLE_FILES, /*!< ; separated list of files on server. */
SAT_CFG_STR_TLE_SERVER, /*!< Server for TLE updates (replaced in 1.4 by TLE_URLS) */
SAT_CFG_STR_TLE_FILES, /*!< ; separated list of files on server (replaced in 1.4 by TLE_URLS) */
SAT_CFG_STR_TLE_PROXY, /*!< Proxy server. */
SAT_CFG_STR_TLE_URLS, /*!< ; separated list of TLE file URLs (since 1.4) */
SAT_CFG_STR_TLE_FILE_DIR, /*!< Local directory from which tle were last updated. */
SAT_CFG_STR_PRED_SAVE_DIR, /*!< Last used save directory for pass predictions */
SAT_CFG_STR_NUM /*!< Number of string parameters */

View file

@ -1,9 +1,7 @@
/*
Gpredict: Real-time satellite tracking and orbit prediction program
Copyright (C) 2001-2009 Alexandru Csete, OZ9AEC.
Authors: Alexandru Csete <oz9aec@gmail.com>
Copyright (C) 2001-2017 Alexandru Csete, OZ9AEC.
Comments, questions and bugreports should be submitted via
http://sourceforge.net/projects/gpredict/
@ -31,10 +29,13 @@
#include <gtk/gtk.h>
#include "sat-cfg.h"
#include "sat-log.h"
#include "sat-pref-tle.h"
#include "tle-update.h"
extern GtkWidget *window; /* dialog window defined in sat-pref.c */
/* Update frequency widget */
static GtkWidget *freq;
@ -42,7 +43,7 @@ static GtkWidget *freq;
static GtkWidget *warn, *autom;
/* internet updates */
static GtkWidget *server, *proxy, *files;
static GtkWidget *proxy, *tle_url_view, *add_tle, *del_tle;
/* add new sats */
static GtkWidget *addnew;
@ -60,10 +61,6 @@ static void create_reset_button(GtkBox * vbox);
static void reset_cb(GtkWidget * button, gpointer data);
static void value_changed_cb(GtkWidget * widget, gpointer data);
#if 0
static void create_local(GtkWidget * vbox);
#endif
/** Create and initialise widgets for the locations TLE update tab. */
GtkWidget *sat_pref_tle_create()
@ -81,26 +78,20 @@ GtkWidget *sat_pref_tle_create()
gtk_box_pack_start(GTK_BOX(vbox), gtk_hseparator_new(), FALSE, TRUE, 0);
create_misc(vbox);
#if 0
create_local(vbox);
#endif
/* create RESET button */
create_reset_button(GTK_BOX(vbox));
return vbox;
}
/** \brief User pressed cancel. Any changes to config must be cancelled.
*/
/** User pressed cancel. Any changes to config must be cancelled. */
void sat_pref_tle_cancel()
{
dirty = FALSE;
reset = FALSE;
}
/** \brief User pressed OK. Any changes should be stored in config.
*/
/** User pressed OK. Any changes should be stored in config. */
void sat_pref_tle_ok()
{
if (dirty)
@ -119,22 +110,47 @@ void sat_pref_tle_ok()
sat_cfg_set_int(SAT_CFG_INT_TLE_AUTO_UPD_ACTION,
TLE_AUTO_UPDATE_NOTIFY);
/* server */
sat_cfg_set_str(SAT_CFG_STR_TLE_SERVER,
gtk_entry_get_text(GTK_ENTRY(server)));
/* proxy */
sat_cfg_set_str(SAT_CFG_STR_TLE_PROXY,
gtk_entry_get_text(GTK_ENTRY(proxy)));
/* files */
sat_cfg_set_str(SAT_CFG_STR_TLE_FILES,
gtk_entry_get_text(GTK_ENTRY(files)));
/* URLS */
gsize num;
guint i;
gchar *url, *buff, *all_urls = NULL;
GtkTreeModel *model;
GtkTreeIter iter;
/* add new sats */
sat_cfg_set_bool(SAT_CFG_BOOL_TLE_ADD_NEW,
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON
(addnew)));
model = gtk_tree_view_get_model(GTK_TREE_VIEW(tle_url_view));
num = gtk_tree_model_iter_n_children(model, NULL);
for (i = 0; i < num; i++)
{
if (gtk_tree_model_iter_nth_child(model, &iter, NULL, i))
{
gtk_tree_model_get(model, &iter, 0, &url, -1);
if (i > 0)
{
buff = g_strdup_printf("%s;%s", all_urls, url);
g_free(all_urls);
}
else
{
buff = g_strdup_printf("%s", url);
}
all_urls = g_strdup(buff);
g_free(buff);
g_free(url);
}
else
{
sat_log_log(SAT_LOG_LEVEL_ERROR,
_("%s:%s: Error fetching entry %d in URL list"),
__FILE__, __func__, i);
}
}
sat_cfg_set_str(SAT_CFG_STR_TLE_URLS, all_urls);
g_free(all_urls);
dirty = FALSE;
}
@ -143,9 +159,8 @@ void sat_pref_tle_ok()
/* use sat_cfg_reset */
sat_cfg_reset_int(SAT_CFG_INT_TLE_AUTO_UPD_FREQ);
sat_cfg_reset_int(SAT_CFG_INT_TLE_AUTO_UPD_ACTION);
sat_cfg_reset_str(SAT_CFG_STR_TLE_SERVER);
sat_cfg_reset_str(SAT_CFG_STR_TLE_PROXY);
sat_cfg_reset_str(SAT_CFG_STR_TLE_FILES);
sat_cfg_reset_str(SAT_CFG_STR_TLE_URLS);
sat_cfg_reset_bool(SAT_CFG_BOOL_TLE_ADD_NEW);
reset = FALSE;
@ -206,11 +221,140 @@ static void create_auto_update(GtkWidget * vbox)
g_signal_connect(autom, "toggled", G_CALLBACK(value_changed_cb), NULL);
}
/* Calback function called when an URL entry in the list has been edited */
static void url_edited_cb(GtkCellRendererText * renderer, gchar * path,
gchar * new_text, GtkListStore * tle_store)
{
GtkTreeIter iter;
gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(tle_store), &iter,
path);
gtk_list_store_set(tle_store, &iter, 0, new_text, -1);
dirty = TRUE;
}
/* Add TLE button clicked */
static void add_tle_cb(GtkWidget * button, GtkListStore * tle_store)
{
GtkTreeView *tv = GTK_TREE_VIEW(tle_url_view);
GtkTreePath *path;
GtkTreeIter iter;
GtkTreeSelection *selection;
gtk_list_store_append(tle_store, &iter);
gtk_list_store_set(tle_store, &iter, 0, "http://server.com/file.txt", -1);
/* activate the newly added row */
path = gtk_tree_model_get_path(GTK_TREE_MODEL(tle_store), &iter);
selection = gtk_tree_view_get_selection(tv);
gtk_tree_selection_select_path(selection, path);
gtk_tree_view_scroll_to_cell(tv, path, NULL, FALSE, 0.0, 0.0);
/* TODO: Enable editing on row */
dirty = TRUE;
}
/* Delete TLE button clicked */
static void del_tle_cb(GtkWidget * button, gpointer data)
{
(void)button;
(void)data;
GtkTreeView *tv = GTK_TREE_VIEW(tle_url_view);
GtkTreeModel *model = gtk_tree_view_get_model(tv);
GtkTreeModel *selmod;
GtkTreeSelection *selection;
GtkTreeIter iter;
/* if this is the only entry, tell user that it is not possible to delete */
if (gtk_tree_model_iter_n_children(model, NULL) < 2)
{
GtkWidget *dialog;
dialog = gtk_message_dialog_new(GTK_WINDOW(window),
GTK_DIALOG_MODAL |
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_OK,
_("Can not delete TLE source!\n\n"
"You should have at least one TLE source configured, "
"otherwise Gpredict may not work correctly.\n\n"
"If you want to modify the TLE source, click twice "
"on the row to edit it."));
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
}
else
{
/* get selected row
FIXME: do we really need to work with two models?
*/
selection = gtk_tree_view_get_selection(tv);
if (gtk_tree_selection_get_selected(selection, &selmod, &iter))
gtk_list_store_remove(GTK_LIST_STORE(selmod), &iter);
dirty = TRUE;
}
}
static GtkWidget *create_tle_buttons(GtkListStore * tle_store)
{
GtkWidget *box;
add_tle = gtk_button_new_with_label(_("Add TLE source"));
gtk_widget_set_tooltip_text(add_tle,
_("Add a new TLE source to the list"));
g_signal_connect(add_tle, "clicked", (GCallback) add_tle_cb, tle_store);
del_tle = gtk_button_new_with_label(_("Delete TLE source"));
gtk_widget_set_tooltip_text(del_tle, _("Delete the selected TLE source"));
g_signal_connect(del_tle, "clicked", (GCallback) del_tle_cb, NULL);
box = gtk_hbutton_box_new();
gtk_button_box_set_layout(GTK_BUTTON_BOX(box), GTK_BUTTONBOX_START);
gtk_container_add(GTK_CONTAINER(box), add_tle);
gtk_container_add(GTK_CONTAINER(box), del_tle);
return box;
}
/* Update TLE URL view with URLs from tle_url_str */
static void set_tle_urls(const gchar * tle_url_str)
{
if (!tle_url_str)
return;
gchar **tle_url_strv = g_strsplit(tle_url_str, ";", -1);
if (g_strv_length(tle_url_strv) > 0)
{
GtkTreeIter iter;
GtkListStore *tle_store;
int i;
tle_store =
GTK_LIST_STORE(gtk_tree_view_get_model
(GTK_TREE_VIEW(tle_url_view)));
gtk_list_store_clear(tle_store);
for (i = 0; i < g_strv_length(tle_url_strv); i++)
{
gtk_list_store_append(tle_store, &iter);
gtk_list_store_set(tle_store, &iter, 0, tle_url_strv[i], -1);
}
}
g_strfreev(tle_url_strv);
}
/** Create widgets for network update configuration */
static void create_network(GtkWidget * vbox)
{
GtkWidget *swin;
GtkWidget *label;
GtkWidget *table;
GtkCellRenderer *renderer;
GtkTreeViewColumn *column;
GtkListStore *tle_store;
/* auto update */
label = gtk_label_new(NULL);
@ -220,36 +364,14 @@ static void create_network(GtkWidget * vbox)
gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, TRUE, 0);
/* create table */
table = gtk_table_new(3, 3, FALSE);
GtkWidget *table;
table = gtk_table_new(2, 4, FALSE);
gtk_table_set_row_spacings(GTK_TABLE(table), 5);
gtk_table_set_col_spacings(GTK_TABLE(table), 5);
/* server */
label = gtk_label_new(_("Remote server:"));
gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, GTK_FILL, GTK_FILL,
0, 0);
server = gtk_entry_new();
if (sat_cfg_get_str(SAT_CFG_STR_TLE_SERVER))
gtk_entry_set_text(GTK_ENTRY(server),
sat_cfg_get_str(SAT_CFG_STR_TLE_SERVER));
gtk_widget_set_tooltip_text(server,
_
("Enter URL for remote server including directory, i.e.\n"
"protocol://servername/directory\n"
"Protocol can be both http and ftp."));
g_signal_connect(server, "changed", G_CALLBACK(value_changed_cb), NULL);
gtk_table_attach(GTK_TABLE(table), server, 1, 2, 0, 1,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
/* proxy */
label = gtk_label_new(_("Proxy server:"));
gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, GTK_FILL, GTK_FILL,
0, 0);
proxy = gtk_entry_new();
if (sat_cfg_get_str(SAT_CFG_STR_TLE_PROXY))
@ -259,29 +381,53 @@ static void create_network(GtkWidget * vbox)
_("Enter URL for local proxy server. e.g.\n"
"http://my.proxy.com"));
g_signal_connect(proxy, "changed", G_CALLBACK(value_changed_cb), NULL);
gtk_table_attach(GTK_TABLE(table), proxy, 1, 2, 1, 2,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1,
GTK_FILL, GTK_FILL, 0, 0);
gtk_table_attach(GTK_TABLE(table), proxy, 1, 2, 0, 1,
GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
/* Files */
label = gtk_label_new(_("Files to fetch:"));
gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 2, 3, GTK_FILL, GTK_FILL,
0, 0);
/* URLs */
label = gtk_label_new(_("TLE sources:"));
gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.0);
files = gtk_entry_new();
if (sat_cfg_get_str(SAT_CFG_STR_TLE_FILES))
gtk_entry_set_text(GTK_ENTRY(files),
sat_cfg_get_str(SAT_CFG_STR_TLE_FILES));
gtk_widget_set_tooltip_text(files,
tle_store = gtk_list_store_new(1, G_TYPE_STRING);
tle_url_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(tle_store));
g_object_unref(tle_store);
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tle_url_view), FALSE);
gtk_widget_set_tooltip_text(tle_url_view,
_
("Enter list of files to fetch from remote server.\n"
"The files should be separated with ; (semicolon)"));
g_signal_connect(files, "changed", G_CALLBACK(value_changed_cb), NULL);
gtk_table_attach(GTK_TABLE(table), files, 1, 2, 2, 3,
("List of files with TLE data to retrieve from "
"the Internet\nClick twice on a row to edit"));
renderer = gtk_cell_renderer_text_new();
g_object_set(renderer, "editable", TRUE, NULL);
g_signal_connect(renderer, "edited", G_CALLBACK(url_edited_cb), tle_store);
column = gtk_tree_view_column_new_with_attributes("Invisible title :)",
renderer, "text", 0,
NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(tle_url_view), column);
/* set URL data */
gchar *tle_url_str = sat_cfg_get_str(SAT_CFG_STR_TLE_URLS);
set_tle_urls(tle_url_str);
g_free(tle_url_str);
/* scrolled window to contain the URL list */
swin = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_container_add(GTK_CONTAINER(swin), tle_url_view);
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2,
GTK_FILL, GTK_FILL, 0, 0);
gtk_table_attach(GTK_TABLE(table), swin, 1, 2, 1, 3,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
/* put table into vbox */
gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, TRUE, 0);
gtk_table_attach(GTK_TABLE(table), create_tle_buttons(tle_store),
1, 2, 3, 4, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 0);
}
/** Create widgets for network update configuration */
@ -292,32 +438,15 @@ static void create_misc(GtkWidget * vbox)
("Add new satellites to local database"));
gtk_widget_set_tooltip_text(addnew,
_
("Note that new satellites will be added to a group called Other"));
("New satellites will be added to a group called Other"));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(addnew),
sat_cfg_get_bool(SAT_CFG_BOOL_TLE_ADD_NEW));
g_signal_connect(addnew, "toggled", G_CALLBACK(value_changed_cb), NULL);
gtk_box_pack_start(GTK_BOX(vbox), addnew, FALSE, TRUE, 0);
}
#if 0
/** Create widgets for local update configuration */
static void create_local(GtkWidget * vbox)
{
GtkWidget *label;
/* auto update */
label = gtk_label_new(NULL);
gtk_label_set_markup(GTK_LABEL(label),
_("<b>Update from Local Files:</b>"));
gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, TRUE, 0);
}
#endif
/**
* Create RESET button.
* @param cfg Config data or NULL in global mode.
@ -375,17 +504,15 @@ static void reset_cb(GtkWidget * button, gpointer data)
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(warn), TRUE);
}
/* server */
gtk_entry_set_text(GTK_ENTRY(server),
sat_cfg_get_str_def(SAT_CFG_STR_TLE_SERVER));
/* proxy */
gtk_entry_set_text(GTK_ENTRY(proxy), "");
/* files */
gtk_entry_set_text(GTK_ENTRY(files),
sat_cfg_get_str_def(SAT_CFG_STR_TLE_FILES));
/* URLS */
gchar *tle_url_str = sat_cfg_get_str_def(SAT_CFG_STR_TLE_URLS);
set_tle_urls(tle_url_str);
g_free(tle_url_str);
/* add new sats */
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(addnew),

View file

@ -3,8 +3,6 @@
Copyright (C) 2001-2009 Alexandru Csete, OZ9AEC.
Authors: Alexandru Csete <oz9aec@gmail.com>
Comments, questions and bugreports should be submitted via
http://sourceforge.net/projects/gpredict/
More details can be found at the project home page: