pyxdg - freedesktop.org specifications support
Check out the new site at https://rkblog.dev.
29 November 2008
Comments
pyxdg is a Python library that handles freedesktop.org standards for common desktop operations and components like determining file MIME type, getting icon for a specific file or application, accessing application menu and more. Most Linux/Unix window managers use those specifications (except KDE3 which supports them partially).
Determining file MIMEtype
xdg.Mime module allows us to determine file mime type very accurately using magic number tests. Advantage is that if a file has wrong extension - the test will return correct MIME. Python standard library has also a module called "mimetypes", but it works using lists of mapped file extensions. Here is a code example:from os import listdir
import xdg.Mime
files = listdir('files')
for f in files:
print '%s: %s' % (f, xdg.Mime.get_type('files/%s' % f, name_pri=0))
print
for f in files:
print '%s: %s' % (f, xdg.Mime.get_type_by_name('files/%s' % f))
print
import mimetypes
mimetypes.init()
for f in files:
ext = u'.%s' % f.split('.')[-1]
try:
ext = mimetypes.types_map[ext]
print '%s: %s' % (f, ext)
except:
print '%s: None' % f
file.sql: text/x-sql plikrpm: application/x-rpm file.c: text/x-csrc file.yml: text/plain file.htm: text/html file.html: text/html file.h: text/x-chdr file.cs: text/x-csharp file.pl: application/x-perl file.fortran: text/plain file.js: application/javascript file.css: text/css file.sh: application/x-shellscript file.py: text/x-python file.xml: application/xml file.kaffeine: text/plain file.rb: application/x-ruby plikrpm.txt: application/x-rpm file.diff: text/x-patch file.d: text/x-dsrc file.tk: text/x-tcl file.php: application/x-php file.java: text/x-java file.cpp: text/x-c++src file.tcl: text/x-tcl file.patch: text/x-patch plik.rpm: application/x-rpm file.sql: text/x-sql plikrpm: None file.c: text/x-csrc file.yml: None file.htm: text/html file.html: text/html file.h: text/x-chdr file.cs: text/x-csharp file.pl: application/x-perl file.fortran: None file.js: application/javascript file.css: text/css file.sh: application/x-shellscript file.py: text/x-python file.xml: application/xml file.kaffeine: None file.rb: application/x-ruby plikrpm.txt: text/plain file.diff: text/x-patch file.d: text/x-dsrc file.tk: text/x-tcl file.php: application/x-php file.java: text/x-java file.cpp: text/x-c++src file.tcl: text/x-tcl file.patch: text/x-patch plik.rpm: application/x-rpm file.sql: None plikrpm: None file.c: text/x-csrc file.yml: None file.htm: text/html file.html: text/html file.h: text/x-chdr file.cs: None file.pl: text/x-perl file.fortran: None file.js: application/x-javascript file.css: text/css file.sh: text/x-sh file.py: text/x-python file.xml: application/xml file.kaffeine: None file.rb: None plikrpm.txt: text/plain file.diff: text/plain file.d: None file.tk: text/x-tcl file.php: None file.java: text/x-java file.cpp: text/x-c++src file.tcl: text/x-tcl file.patch: None plik.rpm: application/x-redhat-package-manager
Base Directories
xdg.BaseDirectory module implements Base Directory Specification - a set of variables determining directories for data, configs and cache.- There is a single base directory relative to which user-specific data files should be written. This directory is defined by the environment variable $XDG_DATA_HOME. If unset use $HOME/.local/share.
- There is a single base directory relative to which user-specific configuration files should be written. This directory is defined by the environment variable $XDG_CONFIG_HOME. If unset use $HOME/.config should be used
- There is a set of preference ordered base directories relative to which data files should be searched. This set of directories is defined by the environment variable $XDG_DATA_DIRS. JIf unset use /usr/local/share/:/usr/share/.
- There is a set of preference ordered base directories relative to which configuration files should be searched. This set of directories is defined by the environment variable $XDG_CONFIG_DIRS.
- There is a single base directory relative to which user-specific non-essential (cached) data should be written. This directory is defined by the environment variable $XDG_CACHE_HOME. If unset use $HOME/.cache
import xdg.BaseDirectory as bd
print 'xdg_data_home: %s' % bd.xdg_data_home
print 'xdg_data_dirs: %s' % bd.xdg_data_dirs
print 'xdg_config_home: %s' % bd.xdg_config_home
print 'xdg_config_dirs: %s' % bd.xdg_config_dirs
print 'xdg_cache_home: %s' % bd.xdg_cache_home
xdg_data_home: /home/piotr/.local/share xdg_data_dirs: ['/home/piotr/.local/share', '/usr/kde/3.5/share', '/usr/share', '/usr/local/share'] xdg_config_home: /home/piotr/.config xdg_config_dirs: ['/home/piotr/.config', '/usr/kde/3.5/etc/xdg'] xdg_cache_home: /home/piotr/.cache
.desktop files
xdg.DesktopEntry modules supply us with a class that implements XDG Desktop Entry Specification. Desktop files are used to put an application in the system application menu. Example:import xdg.DesktopEntry as d
de = d.DesktopEntry(filename='openarena.desktop')
print 'getType: %s' % de.getType()
print 'getVersion: %s' % de.getVersion()
print 'getEncoding: %s' % de.getEncoding()
print 'getName: %s' % de.getName()
print 'getGenericName: %s' % de.getGenericName()
print 'getComment: %s' % de.getComment()
print 'getNoDisplay: %s' % de.getNoDisplay()
print 'getIcon: %s' % de.getIcon()
print 'getHidden: %s' % de.getHidden()
print 'getFilePattern: %s' % de.getFilePattern()
print 'getTryExec: %s' % de.getTryExec()
print 'getExec: %s' % de.getExec()
print 'getPath: %s' % de.getPath()
print 'getTerminal: %s' % de.getTerminal()
print 'getSwallowTitle: %s' % de.getSwallowTitle()
print 'getSwallowExec: %s' % de.getSwallowExec()
print 'getActions: %s' % de.getActions()
print 'getMimeType: %s' % de.getMimeType()
print 'getSortOrder: %s' % de.getSortOrder()
print 'getDev: %s' % de.getDev()
print 'getFSType: %s' % de.getFSType()
print 'getMountPoint: %s' % de.getMountPoint()
print 'getReadonly: %s' % de.getReadonly()
print 'getUnmountIcon: %s' % de.getUnmountIcon()
print 'getURL: %s' % de.getURL()
print 'getCategories: %s' % de.getCategories()
print 'getOnlyShowIn: %s' % de.getOnlyShowIn()
print 'getNotShowIn: %s' % de.getNotShowIn()
print 'getStartupNotify: %s' % de.getStartupNotify()
print 'getStartupWMClass: %s' % de.getStartupWMClass()
print 'getServiceTypes: %s' % de.getServiceTypes()
print 'getDocPath: %s' % de.getDocPath()
print 'getKeywords: %s' % de.getKeywords()
print 'getInitialPreference: %s' % de.getInitialPreference()
getType: Application getVersion: 0.0 getEncoding: getName: OpenArena getGenericName: getComment: A Quake3-based FPS Game getNoDisplay: False getIcon: openarena getHidden: False getFilePattern: < _sre.SRE_Pattern object at 0x7f41f98cde70 > getTryExec: getExec: openarena getPath: getTerminal: False getSwallowTitle: getSwallowExec: getActions: [] getMimeType: [] getSortOrder: [] getDev: getFSType: getMountPoint: getReadonly: False getUnmountIcon: getURL: getCategories: ['Game', 'ActionGame'] getOnlyShowIn: [] getNotShowIn: [] getStartupNotify: False getStartupWMClass: getServiceTypes: [] getDocPath: getKeywords: [] getInitialPreference:
Icons and iconset support
Iconsets that are used for example in GNOME or KDE4 follow XDG Icon Spec. xdg.IconTheme module contains a class that implements that specification, and can read iconset informations, or return an icon for application or other element:import xdg.IconTheme as ic
i = ic.IconTheme()
i.parse('/home/piotr/.kde/share/icons/KDEmod-Icons-Tango/index.theme')
print 'getName: %s' % i.getName()
print 'getComment: %s' % i.getComment()
print 'getInherits: %s' % i.getInherits()
print 'getDirectories: %s' % i.getDirectories()
print 'getHidden: %s' % i.getHidden()
print 'getExample: %s' % i.getExample()
print
print 'getSize: %s' % i.getSize('scalable/categories')
print 'getContext: %s' % i.getContext('scalable/categories')
print 'getType: %s' % i.getType('scalable/categories')
print 'getMaxSize: %s' % i.getMaxSize('scalable/categories')
print 'getMinSize: %s' % i.getMinSize('scalable/categories')
print 'getThreshold: %s' % i.getThreshold('scalable/categories')
getName: KDEmod-Icons-Tango getComment: Tango and Tango-like icons for KDEmod getInherits: ['crystalsvg'] getDirectories: ['16x16/actions', '16x16/apps', '16x16/categories', '16x16/devices', '16x16/mimetypes', '22x22/actions', '22x22/apps', '22x22/categories', '22x22/devices', '22x22/mimetypes', '32x32/actions', '32x32/apps', '32x32/categories', '32x32/devices', '32x32/mimetypes', '48x48/actions', '48x48/apps', '48x48/categories', '48x48/devices', '48x48/mimetypes', '64x64/actions', '64x64/apps', '64x64/categories', '64x64/devices', '64x64/mimetypes', '128x128/actions', '128x128/apps', '128x128/categories', '128x128/devices', '128x128/mimetypes', 'scalable/actions', 'scalable/apps', 'scalable/categories', 'scalable/devices', 'scalable/mimetypes', '16x16/filesystems', '22x22/filesystems', '32x32/filesystems', '48x48/filesystems', '64x64/filesystems', '128x128/filesystems'] getHidden: False getExample: folder getSize: 48 getContext: Categories getType: Scalable getMaxSize: 256 getMinSize: 32 getThreshold: 0
print ic.getIconPath("opera")
Recently used files
XDG Recent File Storage Specification describes a file that contain informations about recently used files. xdg.RecentFiles module contains a class that can access such file, and even edit it. Here is an example:import xdg.RecentFiles as rc
i = rc.RecentFiles()
i.parse()
files = i.getFiles()
for f in files:
print f.URI
print f.Timestamp
print f.Groups
print f.MimeType
print
file:///home/piotr/nowe/GAE/echoo-google-app-engine-barcamp-saigon-1-1227167304763656-9.ppt 1227913909 [u'openoffice.org', u'staroffice', u'starsuite'] application/vnd.ms-powerpoint file:///home/piotr/nowe/GAE/starpad-1220394698551686-8.ppt 1227913837 [u'openoffice.org', u'staroffice', u'starsuite'] application/vnd.ms-powerpoint file:///home/piotr/nowe/GAE/ajaxworldwest-1224787694777812-9.ppt 1227913822 [u'openoffice.org', u'staroffice', u'starsuite'] application/vnd.ms-powerpoint
Applications Menu
KDE, GNOME and other WMs have their menu with all installed GUI applications. pyxdg has two modules: xdg.Menu and xdg.MenuEditor. the first one can list elements of the application menu, and the other one can edit it. Here is an example:#!/usr/bin/python
import sys
import xdg.Menu
import xdg.DesktopEntry
def show_menu(menu, depth = 0):
for entry in menu.getEntries():
if isinstance(entry, xdg.Menu.Menu):
show_menu(entry, depth)
elif isinstance(entry, xdg.Menu.MenuEntry):
print menu.getPath() + "/ " + entry.DesktopFileID + " " + entry.DesktopEntry.getFileName()
show_menu(xdg.Menu.parse())
RkBlog
Check out the new site at https://rkblog.dev.
Comment article