Найти имя приложения по умолчанию для данного файла - PullRequest
7 голосов
/ 26 марта 2011

В Linux, есть ли способ спросить какие-либо службы xdg или службы gtk, какое приложение является приложением по умолчанию для данного файла?

Я понимаю, что xdg-open будетна самом деле, запустите правильное приложение.Тем не менее, я хочу иметь возможность отображать имя приложения в контекстном меню.Так что, когда пользователь нажимает на элемент меню, он запускает xdg-open, который запускает это приложение.

В OSX я могу использовать LaunchServices для этого:

def getDefaultDarwinApplication(path):
    import LaunchServices
    import CoreData
    import urllib

    url = CoreData.CFURLRef.URLWithString_("file://"+urllib.quote(path))
    os_status, app_ref, appurl = LaunchServices.LSGetApplicationForURL(url, LaunchServices.kLSRolesAll, None, None)
    if os_status != 0:
        return ""
    apppath = app_ref.as_pathname()
    name = os.path.basename(apppath).replace(".app", "")
    return name

надеюсь, что есть что-то похожее на Linux, я могу использовать.Лучше всего был бы встроенный модуль Python, но сработал бы даже скребок экрана.

Ответы [ 3 ]

7 голосов
/ 26 марта 2011

Используйте команду xdg-mime.Это позволяет вам запрашивать mimetype, а затем связывать программу, не выполняя ее.

Обратите внимание, что при этом возвращается имя связанного файла .desktop.Затем вам нужно найти фактический файл и затем проанализировать его, чтобы получить реальное имя программы, даже локализованное на любом языке, который вы хотите, путь двоичного файла на диске и т. Д.

Вот полный код:

import os
import subprocess
import codecs
import ConfigParser

class XDGError(Exception): pass
class FileNotFoundError(Exception): pass

def _get_app_paths():
    paths = os.environ.get('XDG_DATA_HOME', 
        os.path.expanduser('~/.local/share/')).split(os.path.pathsep)
    paths.extend(os.environ.get('XDG_DATA_DIRS', 
        '/usr/local/share/:/usr/share/').split(os.path.pathsep))
    return paths

def xdg_query(command, parameter):
    p = subprocess.Popen(['xdg-mime', 'query', command, parameter], 
            stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    output, errors = p.communicate()
    if p.returncode or errors:
        raise XDGError('xdg-mime returned error code %d: %s' % 
            (p.returncode, errors.strip()))
    return output.strip()

def locate_desktop_file(filename, mode='r', encoding='utf-8', 
        _paths=_get_app_paths()):
    for path in _paths:
        for thispath, dirs, files in os.walk(os.path.join(path, 'applications')):
            if filename not in files:
                continue
            fullname = os.path.join(thispath, filename)
            try:
                return codecs.open(fullname, mode, encoding)
            except IOError:
                pass
    else:
        raise FileNotFoundError(filename)

def get_defaults(filename):
    filetype = xdg_query('filetype', filename)
    desktop_filename = xdg_query('default', filetype)
    with locate_desktop_file(desktop_filename) as desktop_file:
        parser = ConfigParser.ConfigParser()
        parser.readfp(desktop_file, desktop_filename)
    return dict(parser.items(parser.sections()[0]))

Пример использования:

p = get_defaults('index.html')
print p['name'], p['comment']
4 голосов
/ 31 августа 2011

Еще лучше я нашел официальный способ гнома , чтобы сделать это.

import gio
mime_type = gio.content_type_guess('foo.txt')
app_infos = gio.gio.app_info_get_all_for_type(mime_type)
for app_info in app_infos:
    print app_info.get_name(), app_info.get_executable(), app_info.get_icon()
# pure bliss
1 голос
/ 28 марта 2011

Вот немного более компактная версия, использующая некоторые методы из официального модуля Python xdg и использующая отличный код из @nosklo:

import os
import subprocess

from xdg import BaseDirectory
from xdg import DesktopEntry

class XDGError(Exception): pass

def xdg_query(command, parameter):
    p = subprocess.Popen(['xdg-mime', 'query', command, parameter],
            stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    output, errors = p.communicate()
    if p.returncode or errors:
        raise XDGError('xdg-mime returned error code %d: %s' %
            (p.returncode, errors.strip()))
    return output.strip()


def get_default(filename):
    try:
        filetype = xdg_query('filetype', filename)
        desktop_filename = xdg_query('default', filetype)
    except XDGError:
        return None

    try:
        res = BaseDirectory.load_data_paths('applications', desktop_filename)
        if not res:
           return None
        desktop_file = res.next()
    except StopIteration:
        return None

    if not os.path.exists(desktop_file):
        return None
    return DesktopEntry.DesktopEntry(desktop_file)

И пример того, как его использовать:

entry = get_default("index.html")
if not entry:
    print "no default application found"
else:
    application_name = entry.getName()
    application_path = entry.getExec()
    application_icon = entry.getIcon()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...