After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 397742 - Shouldn't use xdg.DesktopEntry for launcher names
Shouldn't use xdg.DesktopEntry for launcher names
Status: RESOLVED FIXED
Product: sabayon
Classification: Deprecated
Component: general
2.17.x
Other All
: Urgent blocker
: GNOME 2.18.0
Assigned To: Maintainers of sabayon
Maintainers of sabayon
Depends on:
Blocks:
 
 
Reported: 2007-01-17 19:50 UTC by Federico Mena Quintero
Modified: 2009-08-30 12:31 UTC
See Also:
GNOME target: ---
GNOME version: 2.17/2.18


Attachments
Alternative approach using ConfigParser (858 bytes, patch)
2007-01-18 07:01 UTC, Sayamindu Dasgupta
needs-work Details | Review
Update of previous patch, with l10n issues properly handled. (1.19 KB, patch)
2007-02-02 06:41 UTC, Sayamindu Dasgupta
needs-work Details | Review
updated patch (1.37 KB, patch)
2007-02-21 18:18 UTC, Sayamindu Dasgupta
needs-work Details | Review
sabayon-397742-temporary-fix.diff (1.39 KB, patch)
2007-03-12 19:49 UTC, Federico Mena Quintero
none Details | Review
Patch based on port of g_get_language_names() (1.91 KB, patch)
2007-03-15 20:59 UTC, Sayamindu Dasgupta
none Details | Review
More robust version of the previous patch (3.41 KB, patch)
2007-03-16 16:07 UTC, Sayamindu Dasgupta
none Details | Review

Description Federico Mena Quintero 2007-01-17 19:50:17 UTC
In sabayon/lib/sources/paneldelegate.py we use the python-xdg module for xdg.DesktopEntry.  Not all distributions carry python-xdg yet.

We should simply be able to use GKeyFile, load the .desktop file directly, and get the "Name" key out of it (or its localized version, of course).
Comment 1 Sayamindu Dasgupta 2007-01-17 20:25:08 UTC
I'm not sure whether there is any binding for GKeyFile in Python. However, the following code snippet seems to work in my own system, though I think it needs to be slightly more robust (what if the entry is the form "Name = blahApp" or something like that.

f = open(desktop_file)
for line in f:
    if line[:5] == "Name=":
        appname = line[5:]
Comment 2 John Dennis 2007-01-17 22:07:05 UTC
You're right, that code is not robust, it's also awkward (counting the number of characters).

Regular expressions are much more elegant and robust. Example:

key_value_re = re.compile("(\w+)\s*=\s*(\S+)")
try:
    f = open(desktop_file)
except IOError, e:
    # return something meaningful

for line in f.readlines():
    match = key_value_re.search(line)
    if match:
        key = match.group(1)
        value = match.group(2)

        if key == 'Name':
            appname = value

You may have to adjust your regular expression for what you expect to parse, but with regexp's you won't be confused by white space formatting, illegal formatting, etc. I'm not sure if the file format allows comments or not but if so you should probably also strip out comments first, something like this (assuming comments are #):

comment_re = re.compile('#.*')
for line in f.readlines():
    line = comment_re.sub('', line)
    line = line.strip()
    if line:
 
Comment 3 Sayamindu Dasgupta 2007-01-18 06:35:19 UTC
Hmmm - regular expressions are definitely the way to go. However, I looked at how Alacarte does the parsing - and it uses the ConfigParser module built into Python (arrggh!! should have thought of this earlier). The following code snippet seems to work - will come up with a patch by tonight (IST).

from ConfigParser import ConfigParser
c = ConfigParser()
c.read(['/usr/share/applications/gedit.desktop'])
appname = c.get('Desktop Entry', 'name')

ConfigParser probably uses regexp internally.
Comment 4 Sayamindu Dasgupta 2007-01-18 07:01:34 UTC
Created attachment 80567 [details] [review]
Alternative approach using ConfigParser

ConfigParser should be available in all recent versions of Python.
Comment 5 Federico Mena Quintero 2007-01-23 03:30:57 UTC
Comment on attachment 80567 [details] [review]
Alternative approach using ConfigParser

Thanks!  One thing I noticed - doing 

  name_from_desktop_file + " launcher"

is not very i18n-friendly.  It should be something like

  "%s launcher" % name

instead.

Also, is it possible to extract the localized name from the desktop file instead of the English one?
Comment 6 Federico Mena Quintero 2007-01-23 16:25:36 UTC
Marking as blocker for the 2.18 release, since this keeps Sabayon from running on distros.
Comment 7 Sayamindu Dasgupta 2007-02-02 06:41:46 UTC
Created attachment 81737 [details] [review]
Update of previous patch, with l10n issues properly handled.

This should work. I did not use the getdefaultlocale() method of the locale module in Python for getting the locale, since I get the following error when I used bn_IN

In [1]: import locale

In [2]: locale.getdefaultlocale()
---------------------------------------------------------------------------
exceptions.ValueError                                Traceback (most recent call last)

/home/sayamindu/Development/sabayon/lib/sources/<ipython console> 

/home/sayamindu/Development/sabayon/lib/sources/locale.py in getdefaultlocale(envvars)
    344     else:
    345         localename = 'C'
--> 346     return _parse_localename(localename)
    347 
    348 

/home/sayamindu/Development/sabayon/lib/sources/locale.py in _parse_localename(localename)
    276     elif code == 'C':
    277         return None, None
--> 278     raise ValueError, 'unknown locale: %s' % localename
    279 
    280 def _build_localename(localetuple):

ValueError: unknown locale: bn_IN
Comment 8 Federico Mena Quintero 2007-02-12 21:32:00 UTC
Comment on attachment 81737 [details] [review]
Update of previous patch, with l10n issues properly handled.

Which distribution are you using?  Python doesn't throw an exception for me with locale.getdefaultlocale() if I use LANG=bn_IN.UTF-8.

Using ConfigParser is fine, but we need to support fallbacks for key files which don't have all the locales in them.  For example, the translation for "bn" may be suitable if one for a more explicit "bn_IN" is not found.

You can steal this logic from g_key_file_get_locale_string().  It calls g_get_language_names() to find all the possibilities for the current language.  I'm not sure if the pygtk bindings expose that function; you may need to port that code from glib/gutils.c to Python.
Comment 9 Theppitak Karoonboonyanan 2007-02-13 05:14:15 UTC
L10n issue has been resolved in bug #402089 before string freeze. Please update your patch, and sorry for interruption.
Comment 10 Sayamindu Dasgupta 2007-02-16 18:41:22 UTC
I'm using Ubuntu 6.10. Looking into g_key_file_get_locale_string() and g_get_language_names()....
Comment 11 Sayamindu Dasgupta 2007-02-21 18:18:30 UTC
Created attachment 83054 [details] [review]
updated patch

This version first tries language_territory for the launcher name, then tries language, and if unsuccessful, falls back to the default name.
Comment 12 Federico Mena Quintero 2007-03-12 19:02:57 UTC
Comment on attachment 83054 [details] [review]
updated patch

But this is not robust at all.  Read the code for g_get_language_names()  (in glib/glib/gutils.c) and its helper function, guess_category_value().  You have to use a series of fallbacks:

- LANGUAGE
- LC_ALL
- LC_MESSAGES (as passed to guess_category_value())
- LANG

Also, each of those may contain multiple fallbacks in turn, like

  LC_MESSAGES=es_MX.UTF-8:en_GB.UTF-8

which means, "use Mexican Spanish if available, otherwise try British English if available".
Comment 13 Federico Mena Quintero 2007-03-12 19:11:31 UTC
For 2.18.0, I think we should just keep the existing _("%s launcher") string and print the .desktop file name:

  calculator.desktop launcher

instead of the nicer name

  Calculator launcher

We can fix this correctly after 2.18.0.
Comment 14 Federico Mena Quintero 2007-03-12 19:49:39 UTC
Created attachment 84444 [details] [review]
sabayon-397742-temporary-fix.diff
Comment 15 Sayamindu Dasgupta 2007-03-15 20:59:46 UTC
Created attachment 84676 [details] [review]
Patch based on port of g_get_language_names()

Ok - here's a patch based on the function at http://sayamindu.randomink.org/misc/get_language_names2.pytxt. I compared its output with http://sayamindu.randomink.org/misc/test_get_language_names.c (which uses the g_get_language_names() from glib) and the outputs match. The patch is against the gnome-2-18 branch.
Comment 16 Sayamindu Dasgupta 2007-03-16 16:07:07 UTC
Created attachment 84724 [details] [review]
More robust version of the previous patch

Based on our IRC discussion yesterday, I'm attaching a new patch. The only difference between this one's output and that of g_get_language_names is in case of situations where LANGUAGE looks like "en_US:en".
In this case the python function returns 
en_US
en
C

while g_get_language_names() returns
en_US
en
en
C

..in simpler words, the list returned by the python function does not have any duplicate entries :-).
Comment 17 Sayamindu Dasgupta 2007-03-16 21:07:33 UTC
(In reply to comment #0)
> In sabayon/lib/sources/paneldelegate.py we use the python-xdg module for
> xdg.DesktopEntry.  Not all distributions carry python-xdg yet.
> 

doh.. I'm so stupid. Federico - could you see if your distribution has the gnomedesktop module installed (import gnomedesktop).
In that case, extracting the name becomes as simple as:

import gnomedesktop

item = gnomedesktop.item_new_from_file(filename, gnomedesktop.LOAD_ONLY_IF_EXISTS)
name = item.get_localestring(gnomedesktop.KEY_NAME)



I feel like kicking myself :-(

Comment 18 Federico Mena Quintero 2009-04-23 16:48:19 UTC
These days Sabayon actually checks for python-xdg at configure time, so I'll close this bug.