Skip to content

Commit

Permalink
Merge branch 'release-v1' into 'develop'
Browse files Browse the repository at this point in the history
Resolve "Release-V1"

See merge request rchaput/xdgprefs!9
  • Loading branch information
rchaput committed Oct 25, 2019
2 parents 312bdb3 + 6265602 commit 2e87583
Show file tree
Hide file tree
Showing 21 changed files with 223 additions and 24 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@
.idea

**/.cache
build/**
dist/**
XDG_Prefs.egg-info/**
126 changes: 123 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,124 @@
# xdg-prefs
# XDG-Prefs
> Remy Chaput <[email protected]>
Program that allows you to change the default application on your Linux system,
using the [XDG standard](https://specifications.freedesktop.org/mime-apps-spec/mime-apps-spec-1.0.html).
On GNU/Linux systems, each file has an associated MIME Type (or Media Type)
that represents the kind of content (for example, *image/jpeg*).
Your system uses a database to list your preferences for default applications
(for example, to use *eog* as default application for *image/jpeg*).

*XDG-Prefs* uses the [XDG Specifications][xdg-spec] to read and modify this
database, allowing you to change your preferred default applications for
each MIME type. The [XDG Specifications][xdg-spec] is the reference
specification for MIME types and default applications, meaning that the
preferences you will set in *XDG-Prefs* will be recognized by all other
XDG-compliant softwares (such as `xdg-open`, which is typically used when
you double-click on a file).

Usually, Desktop Environments (such as *Gnome*, or *KDE*) provide some kind of
tool to manage these preferences ; this software works on every Window Manager
(including those that are not Desktop Environments, such as *i3wm*).

*Note*: *XDG-Prefs* is not associated with the
[Freedesktop Organization][freedesktop], and is not an official software of the
[XDG Specifications][xdg-spec].

## Getting started

Download the Wheel (.whl) file in the [releases] section and install it using
`pip install XDG_Prefs-<version>-py3-none-any.whl` (replace `<version>` with
the number of the version you downloaded, such as `0.1`:
`XDG_Prefs-0.1-py3-none-any.whl`).
Please note that you must use Python3.5 or later (you might need to replace
`pip` with `pip3` on some distributions, such as Debian).

Alternatively, you can clone this project on your computer and run
`python setup.py install`. This is recommended if you want to contribute.
Again, you will need to use Python3.5 or later (you might need to replace
`python` with `python3` on some distributions, such as Debian).

This will install the required files and create a `xdg-prefs` executable.

## How to use

Launch `xdg-prefs` (for example from the command line). On the interface you
will see 3 panels (each associated to a tab):
1. **Associations**: allows you to see the current default application for each
MIME Type.
Simply click on the list, on the left of a given MIME Type to see the list
of possible applications. Click on one of them to set it as the default
application.
2. **List MIME Types**: allows you to see the list of known MIME types on your
computer, and to search for specifics MIME types. Even MIME types which do
not have an associated default application are listed here.
3. **List Applications**: allows you to see the list of known applications on
your computer (that is, those with a *.desktop* file). You can see the list
of MIME types each application is able to handle, and a description of the
application.

*XDG-Prefs* will print logs on the bottom of the interface, especially when
you set a new default application.

## Features

* Python implementation of multiples XDG Specifications.
Directly reads the files that compose each of the following databases:
* [Shared MIME Database][mime-spec] (list of all MIME types)
* [Desktop Entry][apps-spec] (list of applications)
* [MIME Applications Associations][xdg-spec] (preferences for default
applications)
* Qt5 interface
* allows to see and filter list of MIME types
* allows to see and filter list of applications
* allows to see and change the default application associated to each MIME type
* Works with every window manager

## Dependencies

This project only depends on
* Python3.5 (should work with later versions)
* PySide2 (Qt5 for Python ; tested with version 5.9.0a1)
* configparser (Python standard library to read config files)
* [future_fstrings](https://pypi.org/project/future-fstrings/)
(in order to use PEP498's F-strings in Python3.5)
* Uses code from https://github.com/wor/desktop_file_parser
(in order to parse [Desktop files][apps-spec])

## Contributing

This is an Open-Source projects, your contributions are very welcome.

If you have an idea for a new feature, an optimization or if you notice a bug,
feel free to [open an issue][issues].

You are also welcome to contribute to the code directly, in this case please
refer to the [Contributing guidelines][contrib].

## Related projects

Here's a list of other projects related to the [XDG Specifications][xdg-spec]
and/or the setting of default applications on GNU/Linux:

* [PyXDG](https://www.freedesktop.org/wiki/Software/pyxdg/)
* [xdg-utils](https://www.freedesktop.org/wiki/Software/xdg-utils/), including:
* [xdg-mime](http://portland.freedesktop.org/doc/xdg-mime.html)
* [xdg-open](http://portland.freedesktop.org/doc/xdg-open.html)
* gnome-default-applications-properties

## Licensing

This project is licensed under the [Apache License][license].

Basically, this means that you are allowed to modify and distribute this
project, but you must include the [License][license] file and state the
changes you've made (please refer to the [License][license] file or the
https://choosealicense.com/licenses/apache-2.0/ website for the full
list of permissions, conditions and limitations).

[issues]:issues/new
[releases]:releases/
[xdg-spec]:https://www.freedesktop.org/wiki/Specifications/mime-apps-spec/
[freedesktop]:https://www.freedesktop.org/wiki/
[mime-spec]:https://www.freedesktop.org/wiki/Specifications/shared-mime-info-spec/
[apps-spec]:https://www.freedesktop.org/wiki/Specifications/desktop-entry-spec/
[contrib]:./CONTRIBUTING
[license]:./LICENSE
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pyside2
future_fstrings
44 changes: 44 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import os
from setuptools import setup


def read(fname):
return open(os.path.join(os.path.dirname(__file__), fname)).read()


setup(
name='XDG-Prefs',
version='0.1',

packages=['xdgprefs', 'xdgprefs.core', 'xdgprefs.gui'],
install_requires=['PySide2', 'future-fstrings'],

entry_points={
'gui_scripts': [
'xdg-prefs = xdgprefs.__main__:main'
]
},


author='Remy Chaput',
author_email='[email protected]',
description='A GUI program to view and change your default programs\' '
'preferences (which program should open which type of file), '
'using the XDG Specifications',
long_description=read('README.md'),
long_description_content_type='text/markdown',

license='Apache',
keywords='GUI MIME preferences XDG',
platforms=['GNU/Linux'],
classifiers=[
'Development Status :: 4 - Beta',
'Environment :: X11 Applications',
'Intended Audience :: End Users/Desktop',
'License :: OSI Approved :: Apache Software License',
'Natural Language :: English',
'Operating System :: Unix',
'Programming Language :: Python :: 3.5',
'Topic :: Utilities'
]
)
20 changes: 20 additions & 0 deletions xdgprefs/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
"""
Entry-point of the xdg-prefs software.
"""


import sys
from PySide2.QtWidgets import QApplication

from xdgprefs.gui.main_window import MainWindow


def main():
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())


if __name__ == '__main__':
main()
6 changes: 1 addition & 5 deletions xdgprefs/core/app_database.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# -*- coding: future_fstrings -*-
"""
This module defines functions and class to handle the Application Database
(i.e. the list of Desktop Entries that represent applications).
Expand All @@ -6,10 +7,8 @@

import os
import logging
from typing import Dict

from xdgprefs.core.os_env import xdg_data_dirs
from xdgprefs.core.desktop_entry import DesktopEntry
from xdgprefs.core import desktop_entry_parser as parser


Expand All @@ -34,9 +33,6 @@ def app_dirs(only_existing=True):

class AppDatabase(object):

logger: logging.Logger
apps: Dict[str, DesktopEntry]

def __init__(self):
self.logger = logging.getLogger('AppDatabase')
self.apps = {}
Expand Down
11 changes: 5 additions & 6 deletions xdgprefs/core/associations_database.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# -*- coding: future_fstrings -*-
"""
This module defines the database that lists associations between
MIME Types and Applications (represented by Desktop Entries).
Expand Down Expand Up @@ -91,9 +92,9 @@ def cache_files(only_existing=True):
dirs = [os.path.join(d, 'applications') for d in dirs]

files = []
for dir in dirs:
for _dir in dirs:
for prefix in prefixes:
file = os.path.join(dir, prefix + 'mimeinfo.cache')
file = os.path.join(_dir, prefix + 'mimeinfo.cache')
files.append(file)

if only_existing:
Expand Down Expand Up @@ -134,7 +135,8 @@ class AssociationsDatabase(object):
def __init__(self):
self.logger = logging.getLogger('AssociationsDatabase')
self.associations = defaultdict(Associations)
self.config_path = os.path.join(os_env.xdg_config_home(), 'mimeapps.list')
self.config_path = os.path.join(os_env.xdg_config_home(),
'mimeapps.list')
self.config = parse_mimeapps(self.config_path)

self._build_db()
Expand Down Expand Up @@ -174,9 +176,6 @@ def get_apps_for_mimetype(self, mimetype):
return assoc.default
return []

def get_mimetypes_for_app(self, app):
return []

def set_app_for_mimetype(self, mimetype, app):
section = self.config[DEFAULT]
apps = section.get(mimetype, fallback=[])
Expand Down
1 change: 1 addition & 0 deletions xdgprefs/core/desktop_entry.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# -*- coding: future_fstrings -*-
"""
This module defines code relative to Desktop Entries, i.e. applications
which are compliant with the XDG specifications.
Expand Down
1 change: 1 addition & 0 deletions xdgprefs/core/desktop_entry_parser.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# -*- coding: future_fstrings -*-
"""
Desktop file tokenizer and parser.
Source: https://github.com/wor/desktop_file_parser
Expand Down
4 changes: 1 addition & 3 deletions xdgprefs/core/mime_database.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# -*- coding: future_fstrings -*-
"""
This module provides functions and classes used to handle the Mime Database
(i.e. the set of known MIME Types, with associated meta information).
Expand Down Expand Up @@ -42,9 +43,6 @@ class MimeDatabase(object):
It is used to build the database in a first step, and then query it.
"""

logger: logging.Logger
types: Dict[str, MimeType]

def __init__(self):
self.logger = logging.getLogger('MimeDatabase')
self.types = {}
Expand Down
1 change: 1 addition & 0 deletions xdgprefs/core/mime_type.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# -*- coding: future_fstrings -*-
"""
This module defines the MimeType class as well as a MimeTypeParser (used
to parse media types from their XML files).
Expand Down
1 change: 1 addition & 0 deletions xdgprefs/core/os_env.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# -*- coding: future_fstrings -*-
"""
This module allows access to various environment variables of the Operating
System, such as XDG configuration values, the current Desktop Environment,
Expand Down
6 changes: 4 additions & 2 deletions xdgprefs/core/xdg_mime_wrapper.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# -*- coding: future_fstrings -*-
"""
This module defines wrapper functions for the `xdg-mime` software.
Expand Down Expand Up @@ -40,8 +41,9 @@ def _try_path(path):
"""Try an absolute or relative path for the `xdg-mime` executable."""
try:
res = subprocess.run([path, '--version'],
capture_output=True,
text=True)
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True)
if res.returncode is not 0:
logger.warning(f'Unknown error for path {path} ({res.returncode}):'
f' {res.stderr}')
Expand Down
1 change: 1 addition & 0 deletions xdgprefs/gui/app_item.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# -*- coding: future_fstrings -*-
"""
This module defines a single Application Item in the AppsPanel.
"""
Expand Down
1 change: 1 addition & 0 deletions xdgprefs/gui/apps_panel.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# -*- coding: future_fstrings -*-
"""
This module defines Qt Widgets that allow to view the list of applications
as a Qt List (using a custom widget for the layout).
Expand Down
3 changes: 2 additions & 1 deletion xdgprefs/gui/association_item.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# -*- coding: future_fstrings -*-
"""
This module defines a single AssociationItem in the AssociationsPanel.
"""
Expand All @@ -24,7 +25,7 @@ def __init__(self, mime_type, apps, main_window, listview):

self.hbox.addWidget(self.selector, 2)

def _on_selected(self, text):
def _on_selected(self, _):
mime = self.mime_type.identifier
app = self.selector.currentText()
self.main_window.status.showMessage(f'Setting {mime} to {app}...')
Expand Down
7 changes: 5 additions & 2 deletions xdgprefs/gui/associations_panel.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# -*- coding: future_fstrings -*-
"""
This modules defines widgets that allow to view the associations between
MIME Types and Applications as a Qt List, and to modify the associated
Expand Down Expand Up @@ -32,7 +33,8 @@ def __init__(self, main_window):
mime = self.mimedb.get_type(mime_id)
if mime is not None:
apps = self.assocdb.get_apps_for_mimetype(mime_id)
item = AssociationItem(mime, apps, main_window, self.list_widget)
item = AssociationItem(mime, apps, main_window,
self.list_widget)
self.item_map[mime] = item
self.list_widget.addItem(item)

Expand Down Expand Up @@ -90,7 +92,8 @@ def on_filter_update(self):
nb_shown = 0
nb_total = 0
for mime_type in self.item_map:
matches = self.matches(mime_type, filter_text, personal, vendor, ext)
matches = self.matches(mime_type, filter_text, personal, vendor,
ext)
# If it matches, show it
self.item_map[mime_type].setHidden(not matches)
# Count the number of shown apps
Expand Down
3 changes: 2 additions & 1 deletion xdgprefs/gui/custom_item.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# -*- coding: future_fstrings -*-
"""
This module defines a custom QListWidgetItem that uses the following layout:
- icon on the left
- first line of text, bold
- second line of text
- third line of thext, italic
- third line of text, italic
This QListWidgetItem is used to show both MimeTypes and App.
"""

Expand Down
1 change: 1 addition & 0 deletions xdgprefs/gui/main_window.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# -*- coding: future_fstrings -*-
"""
This module defines the main window, allowing the user to effectively
use the application.
Expand Down
1 change: 1 addition & 0 deletions xdgprefs/gui/mime_item.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# -*- coding: future_fstrings -*-
"""
This module defines a single MimeTypeItem in the MimeTypePanel.
"""
Expand Down
Loading

0 comments on commit 2e87583

Please sign in to comment.