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).
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
Function
get_type can use magic number test (if name_pri set to less than 100) to determine the MIME of a file. Function
get_type_by_name uses filename to guess the mime. Sample result can look like this:
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
All "file.*" are empty files. "plik.*" files are RPM package (note incorrect .txt extension, and no extension at all).
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
xdg.BaseDirectory module offers easy access to those variables:
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
Sample output:
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
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:
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')
That can give an output like:
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
To get an icon for a application use:
print ic.getIconPath("opera")
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
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() + "/\t" + entry.DesktopFileID + "\t" + entry.DesktopEntry.getFileName()
show_menu(xdg.Menu.parse())
- Added: 29.11.2008 by riklaunim