RkBlog

Hardware, programming and astronomy tutorials and reviews.

pyxdg - obsługa standardów freedesktop.org

Obsługa zestawów ikon, menu aplikacji, określanie typów MIME, czy też listy ostatnio otwieranych plików z poziomu Pythona.

pyxdg to biblioteka Pythona zawierająca zbiór funkcji i klas do obsługi standardów freedesktop.org - określania typów MIME plików, obsługa menu aplikacij, plików desktop, zestawów ikon i innych operacji związanych z uniksowym pulpitem. Standardy freedesktop wykorzystywane są przez większość środowisk graficznych, za wyjątkiem KDE3, które obsługuje te standardy tylko częściowo.

Określanie typów mime

Moduł xdg.Mime umożliwia określanie typów mime podanych plików. W odróżnieniu od znajdującego się w bibliotece standardowej modułu mimetypes potrafi odgadywać typy mime, a nie tylko określać je na bazie zmapowanych rozszerzeń plików. Oto przykład:
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
Funkcja get_type wykorzystuje m.in. test liczb magicznych, dzięki czemu potrafi określić typ MIME plików o nietypowych, błędnych rozszerzeniach (lub ich braku). Argument "name_pri" oznacza priorytet nazwy nad testem liczb magicznych w określaniu typu MIME. Wartość 100 oznacza pominięcie testu na rzecz nazwy pliku. Funkcja get_type_by_name ogranicza się do określania typu MIME po nazwie pliku. Oto przykładowy wynik dla listy różnych plików:
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
Do testu użyto pustych plików "file.*", oraz przykładowy pakiet RPM (plik.rpm) zapisany także jako "plikrpm" i "plikrpm.txt". Tylko xdg.Mime.get_type poprawnie rozpoznało typ MIME pakietu RPM ukrytego pod tymi nazwami.

Katalogi podstawowe

Moduł xdg.BaseDirectory implementuje obsługę Base Directory Specification, czyli zbioru katalogów, w których należy szukać, umieszczać pliki związane z pulpitem i ustawieniami użytkownika. Specyfikacja definiuje zbiór zmiennych systemowych: Moduł xdg.BaseDirectory umożliwia dostęp do tych zmiennych:
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
Co da wynik typu:
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

Obsługa plików .desktop

Moduł xdg.DesktopEntry dostarcza klasę implementującą XDG Desktop Entry Specification w wersji 0.9.4, czyli obsługę plików *.desktop odpowiedzialnych za umieszczanie danej aplikacji w menu aplikacji środowiska graficznego. Oto przykład:
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:

Obsługa zestawów ikon

Każdy systemowy zestaw ikon posiada plik konfiguracyjny o strukturze opisanej w XDG Icon Spec. Moduł xdg.IconTheme oferuje klasę implementującą tą specyfikację. Oto przykład:
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')
Co da wynik typu:
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
By pobrac ikonę dla danej aplikacji, elementu wystarczy:
print ic.getIconPath("opera")

Ostatnio otwierane pliki

Specyfikacja XDG Recent File Storage Specification określa format pliku przechowującego informacje o ostatnio otwieranych plikach. Domyślnie dane te przetrzymywane sa w pliku .recently-used, w katalogu domowym użytkownika. Moduł xdg.RecentFiles oferuje klasę implementująca tą specyfikację i umożliwiającą pobieranie listy ostatnio otwieranych plików, jak i opcje dodawania i edytowania plików do listy. Oto przykład pobierania listy plików wraz z dodatkowymi informacjami:
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

Obsługa menu aplikacji

Każde praktycznie środowisko graficzne ma swoje "menu" zawierające listę zainstalowanych aplikacji wraz z dodatkami jak ustawienia itp. Tego typu menu opisuje specyfikacja XDG Menu Specification, a w pyxdg znajdziemy moduł xdg.Menu do pobierania informacji, oraz xdg.MenuEditor do edycji menu. Oto przykład pobierania zawartości menu:
#!/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

29 November 2008;

Comment article