Implement 'Preferred languages' preference, ACCEPT_LANGUAGE header
This commit is contained in:
parent
e126271ad8
commit
b5b32495f9
5 changed files with 149 additions and 0 deletions
|
@ -1116,6 +1116,34 @@ soup_session_settings_notify_ident_string_cb (MidoriWebSettings* settings,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void
|
||||||
|
midori_soup_session_settings_accept_language_cb (SoupSession* session,
|
||||||
|
SoupMessage* msg,
|
||||||
|
MidoriWebSettings* settings)
|
||||||
|
{
|
||||||
|
gchar* languages = katze_object_get_string (settings, "preferred-languages");
|
||||||
|
gchar* accpt;
|
||||||
|
|
||||||
|
/* Empty, use the system locales */
|
||||||
|
if (!(languages && *languages))
|
||||||
|
accpt = sokoke_accept_languages (g_get_language_names ());
|
||||||
|
/* No =, no ., looks like a list of language names */
|
||||||
|
else if (!(strchr (languages, '=') && strchr (languages, '.')))
|
||||||
|
{
|
||||||
|
gchar ** lang_names = g_strsplit_set (languages, ",; ", -1);
|
||||||
|
accpt = sokoke_accept_languages ((const gchar* const *)lang_names);
|
||||||
|
g_strfreev (lang_names);
|
||||||
|
}
|
||||||
|
/* Presumably a well formatted list including priorities */
|
||||||
|
else
|
||||||
|
accpt = languages;
|
||||||
|
|
||||||
|
if (accpt != languages)
|
||||||
|
g_free (languages);
|
||||||
|
soup_message_headers_append (msg->request_headers, "ACCEPT_LANGUAGE", accpt);
|
||||||
|
g_free (accpt);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
midori_soup_session_debug (SoupSession* session)
|
midori_soup_session_debug (SoupSession* session)
|
||||||
{
|
{
|
||||||
|
@ -1150,6 +1178,9 @@ midori_soup_session_prepare (SoupSession* session,
|
||||||
G_CALLBACK (soup_session_settings_notify_ident_string_cb), session);
|
G_CALLBACK (soup_session_settings_notify_ident_string_cb), session);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
g_signal_connect (session, "request-queued",
|
||||||
|
G_CALLBACK (midori_soup_session_settings_accept_language_cb), settings);
|
||||||
|
|
||||||
config_file = build_config_filename ("logins");
|
config_file = build_config_filename ("logins");
|
||||||
feature = g_object_new (KATZE_TYPE_HTTP_AUTH, "filename", config_file, NULL);
|
feature = g_object_new (KATZE_TYPE_HTTP_AUTH, "filename", config_file, NULL);
|
||||||
g_free (config_file);
|
g_free (config_file);
|
||||||
|
|
|
@ -495,6 +495,11 @@ midori_preferences_set_settings (MidoriPreferences* preferences,
|
||||||
INDENTED_ADD (label);
|
INDENTED_ADD (label);
|
||||||
button = katze_property_proxy (settings, "identify-as", "custom-ident-string");
|
button = katze_property_proxy (settings, "identify-as", "custom-ident-string");
|
||||||
SPANNED_ADD (button);
|
SPANNED_ADD (button);
|
||||||
|
label = katze_property_label (settings, "preferred-languages");
|
||||||
|
INDENTED_ADD (label);
|
||||||
|
entry = katze_property_proxy (settings, "preferred-languages", NULL);
|
||||||
|
SPANNED_ADD (entry);
|
||||||
|
|
||||||
|
|
||||||
/* Page "Privacy" */
|
/* Page "Privacy" */
|
||||||
PAGE_NEW (GTK_STOCK_INDEX, _("Privacy"));
|
PAGE_NEW (GTK_STOCK_INDEX, _("Privacy"));
|
||||||
|
|
|
@ -86,6 +86,7 @@ struct _MidoriWebSettings
|
||||||
gboolean remember_last_downloaded_files;
|
gboolean remember_last_downloaded_files;
|
||||||
|
|
||||||
gchar* http_proxy;
|
gchar* http_proxy;
|
||||||
|
gchar* http_accept_language;
|
||||||
gboolean auto_detect_proxy;
|
gboolean auto_detect_proxy;
|
||||||
MidoriIdentity identify_as;
|
MidoriIdentity identify_as;
|
||||||
gchar* ident_string;
|
gchar* ident_string;
|
||||||
|
@ -170,6 +171,7 @@ enum
|
||||||
PROP_AUTO_DETECT_PROXY,
|
PROP_AUTO_DETECT_PROXY,
|
||||||
PROP_IDENTIFY_AS,
|
PROP_IDENTIFY_AS,
|
||||||
PROP_IDENT_STRING,
|
PROP_IDENT_STRING,
|
||||||
|
PROP_PREFERRED_LANGUAGES,
|
||||||
|
|
||||||
PROP_CLEAR_PRIVATE_DATA
|
PROP_CLEAR_PRIVATE_DATA
|
||||||
};
|
};
|
||||||
|
@ -1048,6 +1050,22 @@ midori_web_settings_class_init (MidoriWebSettingsClass* class)
|
||||||
NULL,
|
NULL,
|
||||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MidoriWebSettings:preferred-languages:
|
||||||
|
*
|
||||||
|
* A comma separated list of languages preferred for rendering multilingual webpages.
|
||||||
|
*
|
||||||
|
* Since: 0.2.3
|
||||||
|
*/
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_PREFERRED_LANGUAGES,
|
||||||
|
g_param_spec_string (
|
||||||
|
"preferred-languages",
|
||||||
|
_("Preferred languages"),
|
||||||
|
_("A comma separated list of languages preferred for rendering multilingual webpages, for example \"de\", \"ru,nl\" or \"en-us;q=1.0, fr-fr;q=0.667\""),
|
||||||
|
NULL,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MidoriWebSettings:clear-private-data:
|
* MidoriWebSettings:clear-private-data:
|
||||||
*
|
*
|
||||||
|
@ -1462,6 +1480,9 @@ midori_web_settings_set_property (GObject* object,
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case PROP_PREFERRED_LANGUAGES:
|
||||||
|
katze_assign (web_settings->http_accept_language, g_value_dup_string (value));
|
||||||
|
break;
|
||||||
case PROP_CLEAR_PRIVATE_DATA:
|
case PROP_CLEAR_PRIVATE_DATA:
|
||||||
web_settings->clear_private_data = g_value_get_int (value);
|
web_settings->clear_private_data = g_value_get_int (value);
|
||||||
break;
|
break;
|
||||||
|
@ -1677,6 +1698,9 @@ midori_web_settings_get_property (GObject* object,
|
||||||
}
|
}
|
||||||
g_value_set_string (value, web_settings->ident_string);
|
g_value_set_string (value, web_settings->ident_string);
|
||||||
break;
|
break;
|
||||||
|
case PROP_PREFERRED_LANGUAGES:
|
||||||
|
g_value_set_string (value, web_settings->http_accept_language);
|
||||||
|
break;
|
||||||
case PROP_CLEAR_PRIVATE_DATA:
|
case PROP_CLEAR_PRIVATE_DATA:
|
||||||
g_value_set_int (value, web_settings->clear_private_data);
|
g_value_set_int (value, web_settings->clear_private_data);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1633,3 +1633,89 @@ sokoke_prefetch_uri (const char* uri)
|
||||||
soup_uri_free (s_uri);
|
soup_uri_free (s_uri);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Provide a new way for SoupSession to assume an 'Accept-Language'
|
||||||
|
string automatically from the return value of g_get_language_names(),
|
||||||
|
properly formatted according to RFC2616.
|
||||||
|
Copyright (C) 2009 Mario Sanchez Prada <msanchez@igalia.com>
|
||||||
|
Copyright (C) 2009 Dan Winship <danw@gnome.org>
|
||||||
|
Mostly copied from libSoup 2.29, coding style adjusted */
|
||||||
|
|
||||||
|
/* Converts a language in POSIX format and to be RFC2616 compliant */
|
||||||
|
/* Based on code from epiphany-webkit (ephy_langs_append_languages()) */
|
||||||
|
static gchar *
|
||||||
|
sokoke_posix_lang_to_rfc2616 (const gchar *language)
|
||||||
|
{
|
||||||
|
if (!strchr (language, '.') && !strchr (language, '@') && language[0] != 'C')
|
||||||
|
/* change to lowercase and '_' to '-' */
|
||||||
|
return g_strdelimit (g_ascii_strdown (language, -1), "_", '-');
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Adds a quality value to a string (any value between 0 and 1). */
|
||||||
|
static gchar *
|
||||||
|
sokoke_add_quality_value (const gchar *str,
|
||||||
|
float qvalue)
|
||||||
|
{
|
||||||
|
if ((qvalue >= 0.0) && (qvalue <= 1.0))
|
||||||
|
{
|
||||||
|
int qv_int = (qvalue * 1000 + 0.5);
|
||||||
|
return g_strdup_printf ("%s;q=%d.%d",
|
||||||
|
str, (int) (qv_int / 1000), qv_int % 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
return g_strdup (str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns a RFC2616 compliant languages list from system locales */
|
||||||
|
gchar *
|
||||||
|
sokoke_accept_languages (const gchar* const * lang_names)
|
||||||
|
{
|
||||||
|
GArray *langs_garray = NULL;
|
||||||
|
char *cur_lang = NULL;
|
||||||
|
char *prev_lang = NULL;
|
||||||
|
char **langs_array;
|
||||||
|
char *langs_str;
|
||||||
|
float delta;
|
||||||
|
int i, n_lang_names;
|
||||||
|
|
||||||
|
/* Calculate delta for setting the quality values */
|
||||||
|
n_lang_names = g_strv_length ((gchar **)lang_names);
|
||||||
|
delta = 0.999 / (n_lang_names - 1);
|
||||||
|
|
||||||
|
/* Build the array of languages */
|
||||||
|
langs_garray = g_array_new (TRUE, FALSE, sizeof (char*));
|
||||||
|
for (i = 0; lang_names[i] != NULL; i++)
|
||||||
|
{
|
||||||
|
cur_lang = sokoke_posix_lang_to_rfc2616 (lang_names[i]);
|
||||||
|
|
||||||
|
/* Apart from getting a valid RFC2616 compliant
|
||||||
|
language, also get rid of extra variants */
|
||||||
|
if (cur_lang && (!prev_lang ||
|
||||||
|
(!strcmp (prev_lang, cur_lang) || !strstr (prev_lang, cur_lang))))
|
||||||
|
{
|
||||||
|
|
||||||
|
gchar *qv_lang = NULL;
|
||||||
|
|
||||||
|
/* Save reference for further comparison */
|
||||||
|
prev_lang = cur_lang;
|
||||||
|
|
||||||
|
/* Add the quality value and append it */
|
||||||
|
qv_lang = sokoke_add_quality_value (cur_lang, 1 - i * delta);
|
||||||
|
g_array_append_val (langs_garray, qv_lang);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fallback: add "en" if list is empty */
|
||||||
|
if (langs_garray->len == 0)
|
||||||
|
{
|
||||||
|
gchar* fallback = g_strdup ("en");
|
||||||
|
g_array_append_val (langs_garray, fallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
langs_array = (char **) g_array_free (langs_garray, FALSE);
|
||||||
|
langs_str = g_strjoinv (", ", langs_array);
|
||||||
|
|
||||||
|
return langs_str;
|
||||||
|
}
|
||||||
|
|
|
@ -204,4 +204,7 @@ sokoke_file_chooser_dialog_new (const gchar* title,
|
||||||
gboolean
|
gboolean
|
||||||
sokoke_prefetch_uri (const char* uri);
|
sokoke_prefetch_uri (const char* uri);
|
||||||
|
|
||||||
|
gchar *
|
||||||
|
sokoke_accept_languages (const gchar* const * lang_names);
|
||||||
|
|
||||||
#endif /* !__SOKOKE_H__ */
|
#endif /* !__SOKOKE_H__ */
|
||||||
|
|
Loading…
Reference in a new issue