mirror of
https://github.com/anufrievroman/waypaper.git
synced 2024-08-17 12:10:24 +03:00
Compare commits
13 Commits
4fb3f27d3d
...
5d8483f337
Author | SHA1 | Date | |
---|---|---|---|
|
5d8483f337 | ||
|
5ad8b85a15 | ||
|
683bc85127 | ||
|
d53d013db4 | ||
|
8545e45f4f | ||
|
d23f342876 | ||
|
79b2f386c8 | ||
|
1dff8bde0b | ||
|
0bb54963df | ||
|
296c07491c | ||
|
fd588c5c34 | ||
|
eb5bfedb95 | ||
|
059b107445 |
16
README.md
16
README.md
@ -46,6 +46,10 @@ The `waypaper` package is available thanks to Basil Keeler.
|
||||
|
||||
- `swww` or `swaybg` or `feh` or `wallutils`
|
||||
- gobject python library (it might be called `python-gobject` or `python3-gi` or `python3-gobject` in your package manager.)
|
||||
- `python-importlib_metadata`
|
||||
- `python-platformdirs`
|
||||
- `gettext`
|
||||
- `setuptools-gettext`
|
||||
|
||||
## Usage
|
||||
|
||||
@ -93,6 +97,16 @@ If you wish to change language, change `laguage` variable in `.config/waypaper/c
|
||||
|
||||
## Contributions
|
||||
|
||||
Feel free to propose PR and suggest the improvements. I'll also appreciate any help with packaging for various distributions. Also, if you wish to contribute with translation into your language, plese translate `translation_en.py` file, and I'll do the rest.
|
||||
Feel free to propose PR and suggest the improvements. I'll also appreciate any help with packaging for various distributions.
|
||||
|
||||
If you wish to contribute with translation into your language, first make sure `gettext` is installed.
|
||||
After doing so switch your copy of the wayper sources, run the command below and follow the instructions:
|
||||
|
||||
```
|
||||
cd po; msginit
|
||||
```
|
||||
|
||||
For more information about the translation process visit the gettext [manual](https://www.gnu.org/software/gettext/manual/gettext.html).
|
||||
|
||||
|
||||
If you'd like to support the development, consider [donations](https://www.buymeacoffee.com/angryprofessor).
|
||||
|
84
misc/update_translations.py
Executable file
84
misc/update_translations.py
Executable file
@ -0,0 +1,84 @@
|
||||
#!/usr/bin/python3
|
||||
"""Scan source files and to update translations"""
|
||||
# pylint: disable=global-statement, exec-used
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
import setuptools
|
||||
|
||||
# Global variables
|
||||
|
||||
exclude_files = ['setup.py',
|
||||
os.path.basename(sys.argv[0]),
|
||||
'build']
|
||||
project_root=Path(subprocess.getoutput("git rev-parse --show-toplevel"))
|
||||
|
||||
po_dir=project_root / "po"
|
||||
|
||||
metadata = {}
|
||||
|
||||
# Load metadata from setup.py
|
||||
# First create a mock setup() function
|
||||
def setup(**kwargs):
|
||||
"""Retrieve metadata from setup.py
|
||||
@returns: metadata as 'metadata'
|
||||
"""
|
||||
global metadata
|
||||
metadata = kwargs
|
||||
setuptools.setup = setup
|
||||
|
||||
# Now open setup.py and use setup to store metadata
|
||||
# in the dictionary metadata
|
||||
|
||||
with open(project_root/"setup.py", mode='r', encoding='utf-8') as setup_fd:
|
||||
setup_str = setup_fd.read()
|
||||
exec(setup_str)
|
||||
|
||||
os.makedirs(po_dir, exist_ok=True)
|
||||
|
||||
# Generate po files
|
||||
xgettext = ['xgettext', '--indent', '--language=Python',
|
||||
'--foreign-use', '--output-dir', str(po_dir),
|
||||
f'--package-name={metadata["name"]}',
|
||||
f'--package-version={metadata["version"]}',
|
||||
f'--default-domain={metadata["name"]}',
|
||||
f'--output={metadata["name"]}.pot',
|
||||
'--msgid-bugs-address=none@none']
|
||||
msgmerge = [ 'msgmerge', '--update']
|
||||
msginit = ['msginit',
|
||||
'--no-translator', '--locale=en',
|
||||
f'--output-file={str(po_dir)}/en.po',
|
||||
f'--input={str(po_dir)}/{metadata["name"]}.pot']
|
||||
|
||||
package_path = Path(metadata["name"])
|
||||
|
||||
src_files = [ str(src_file.relative_to(project_root)) \
|
||||
for src_file in (project_root/package_path).glob('**/*.py') \
|
||||
if src_file.name not in exclude_files]
|
||||
|
||||
os.chdir(project_root)
|
||||
|
||||
try:
|
||||
subprocess.run([*xgettext, *src_files], check=True)
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(e)
|
||||
|
||||
# Now update existing translations if needed
|
||||
for po_file in po_dir.glob('*.po'):
|
||||
try:
|
||||
subprocess.run([*msgmerge, po_file, str(po_dir)+f'/{metadata["name"]}.pot'],
|
||||
check=True)
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(e)
|
||||
|
||||
# Create or update English translation
|
||||
english_translation = po_dir/'en.po'
|
||||
|
||||
if english_translation.exists():
|
||||
english_translation.unlink()
|
||||
try:
|
||||
subprocess.run([*msginit],
|
||||
check=True)
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(e)
|
233
po/de.po
Normal file
233
po/de.po
Normal file
@ -0,0 +1,233 @@
|
||||
# Language deDE translations for waypaper package.
|
||||
# This file is put in the public domain.
|
||||
# bidar <me@thaodan.de>, 2023.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: waypaper 0.0.2\n"
|
||||
"Report-Msgid-Bugs-To: none@none\n"
|
||||
"POT-Creation-Date: 2023-10-16 03:54+0300\n"
|
||||
"PO-Revision-Date: 2023-10-16 18:43+0300\n"
|
||||
"Last-Translator: Björn Bidar <me@thaodan.de>\n"
|
||||
"Language-Team: Language de\n"
|
||||
"Language: de\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: waypaper/__main__.py:28
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"GUI wallpaper setter for Wayland and X11. It works as a frontend for "
|
||||
"{backends}"
|
||||
msgstr ""
|
||||
"Grafisches Hintergrundbild-Auswahlwerkzeug für Wayland und X11. Es dient als "
|
||||
"Frontend für{backends}"
|
||||
|
||||
#: waypaper/__main__.py:29
|
||||
#, python-brace-format
|
||||
msgid "For more information, visit: {homePage}"
|
||||
msgstr "Weitere Informationen finden Sie unter: {homePage}"
|
||||
|
||||
#: waypaper/__main__.py:31
|
||||
msgid "print version of the program"
|
||||
msgstr "gibt die Programmversion aus"
|
||||
|
||||
#: waypaper/__main__.py:33
|
||||
msgid "restore last wallpaper"
|
||||
msgstr "stellt das zuletzt verwendete Hintergrundbild wieder her"
|
||||
|
||||
#: waypaper/__main__.py:34
|
||||
msgid "set a random wallpaper"
|
||||
msgstr "Ein zufälliges Hintergrundbild auswählen"
|
||||
|
||||
#: waypaper/__main__.py:35
|
||||
msgid "specify how to fill the screen with chosen image"
|
||||
msgstr ""
|
||||
"legt fest, wie das Bild skaliert werden soll, um den gesamten Bildschirm "
|
||||
"auszufüllen"
|
||||
|
||||
#: waypaper/__main__.py:37
|
||||
msgid "specify which backend to use to set wallpaper"
|
||||
msgstr ""
|
||||
"legt das Backend fest, welches zum Setzen des Hintergrundbildes verwendet "
|
||||
"werden soll"
|
||||
|
||||
#: waypaper/changer.py:23 waypaper/changer.py:46
|
||||
#, python-brace-format
|
||||
msgid "Warning related to killall: {error}"
|
||||
msgstr "Warnung im Zusammenhang mit dem Befehl killall: {error}"
|
||||
|
||||
#: waypaper/changer.py:84
|
||||
#, python-brace-format
|
||||
msgid "Sent command to set wallpaper was set with {backend}"
|
||||
msgstr "Hintergrundbild wurde mit folgendem Befehl gesetzt {backend}"
|
||||
|
||||
#: waypaper/changer.py:88
|
||||
#, python-brace-format
|
||||
msgid "The backend is not supported: {backend}"
|
||||
msgstr "Das folgende Backend wird nicht unterstützt: {backend}"
|
||||
|
||||
#: waypaper/changer.py:92
|
||||
#, python-brace-format
|
||||
msgid "Error changing wallpaper: {error}"
|
||||
msgstr "Fehler beim Ändern des Hintergrundbildes: {error}"
|
||||
|
||||
#: waypaper/app.py:69
|
||||
msgid "Change wallpaper folder"
|
||||
msgstr "Hintergrundbild-Ordner ändern"
|
||||
|
||||
#: waypaper/app.py:89
|
||||
msgid "Subfolders"
|
||||
msgstr "Unterordner"
|
||||
|
||||
#: waypaper/app.py:92
|
||||
msgid "Include/exclude images in subfolders"
|
||||
msgstr "Wählen, ob Unterordner mit einbezogen werden sollen"
|
||||
|
||||
#: waypaper/app.py:108
|
||||
msgid "Choose backen"
|
||||
msgstr "Backend auswählen"
|
||||
|
||||
#: waypaper/app.py:112
|
||||
msgid "Fill"
|
||||
msgstr "Füllen"
|
||||
|
||||
#: waypaper/app.py:113
|
||||
msgid "Stretch"
|
||||
msgstr "Dehnen"
|
||||
|
||||
#: waypaper/app.py:114
|
||||
msgid "Fit"
|
||||
msgstr "Passen"
|
||||
|
||||
#: waypaper/app.py:115
|
||||
msgid "Center"
|
||||
msgstr "Zentrieren"
|
||||
|
||||
#: waypaper/app.py:116
|
||||
msgid "Tile"
|
||||
msgstr "Kacheln"
|
||||
|
||||
#: waypaper/app.py:121
|
||||
msgid "Choose fill type"
|
||||
msgstr "Skalierungsart auswählen"
|
||||
|
||||
#: waypaper/app.py:130
|
||||
msgid "Choose background color"
|
||||
msgstr "Hintergrundfarbe auswählen"
|
||||
|
||||
#: waypaper/app.py:134 waypaper/app.py:135
|
||||
msgid "Name"
|
||||
msgstr "Name"
|
||||
|
||||
#: waypaper/app.py:136 waypaper/app.py:137
|
||||
msgid "Date"
|
||||
msgstr "Datum"
|
||||
|
||||
#: waypaper/app.py:144
|
||||
msgid "Choose sorting type"
|
||||
msgstr "Sortierungsart auswählen"
|
||||
|
||||
#: waypaper/app.py:148
|
||||
msgid "Exit"
|
||||
msgstr "Beenden"
|
||||
|
||||
#: waypaper/app.py:150
|
||||
msgid "Exit the application"
|
||||
msgstr "Das Programm beenden"
|
||||
|
||||
#: waypaper/app.py:153
|
||||
msgid "Refresh"
|
||||
msgstr "Aktualisieren"
|
||||
|
||||
#: waypaper/app.py:156
|
||||
msgid "Reache the folder of images"
|
||||
msgstr "Erneutes einlesen des Hintergrundbild-Ordners"
|
||||
|
||||
#: waypaper/app.py:159
|
||||
msgid "Random"
|
||||
msgstr "Zufällig"
|
||||
|
||||
#: waypaper/app.py:161
|
||||
msgid "Set random wallpaper"
|
||||
msgstr "Ein zufälliges Hintergrundbild auswählen"
|
||||
|
||||
#: waypaper/app.py:214
|
||||
#, python-brace-format
|
||||
msgid "Error determining monitor names: {error}"
|
||||
msgstr "Fehler beim Ermitteln der Monitor-Namen {error}"
|
||||
|
||||
#: waypaper/app.py:222
|
||||
msgid "Choose Display"
|
||||
msgstr "Bildschirm auswählen"
|
||||
|
||||
#: waypaper/app.py:239
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"\n"
|
||||
" Looks like none of the wallpaper backends is installed in the "
|
||||
"system.\n"
|
||||
" Use your package manager to install at least one of these "
|
||||
"backends:\n"
|
||||
" {backends}\n"
|
||||
" For more information, visit: {url}"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"Es sieht aus als würde keines der Hintergrund Backend\n"
|
||||
"installiert seit auf dem Systm\n"
|
||||
"Verwende deinen Paket-Manager um mindestens eines zu installieren:\n"
|
||||
"{backends}\n"
|
||||
"Für mehr Informationen, besuche: {url}"
|
||||
|
||||
#: waypaper/app.py:282
|
||||
msgid "Caching wallpapers.."
|
||||
msgstr "Hintergrundbilder werden zwischengespeichert..."
|
||||
|
||||
#: waypaper/app.py:364
|
||||
msgid "Please choose a folder"
|
||||
msgstr "Bitte wählen Sie einen Ordner aus"
|
||||
|
||||
#: waypaper/app.py:365
|
||||
msgid "Select"
|
||||
msgstr "Auswählen"
|
||||
|
||||
#: waypaper/app.py:425 waypaper/app.py:451 waypaper/app.py:530
|
||||
#, python-brace-format
|
||||
msgid "Selected image path: {image}"
|
||||
msgstr "Pfad zum ausgewählten Bild: {image}"
|
||||
|
||||
#: waypaper/app.py:463
|
||||
#, fuzzy, python-brace-format
|
||||
msgid "Error deleting cache '{cacheDir}': '{error}'"
|
||||
msgstr "Fehler beim Löschen des Zwischenspeichers '{cacheDir}': '{error}'"
|
||||
|
||||
#: waypaper/app.py:513
|
||||
#, fuzzy, python-brace-format
|
||||
msgid ""
|
||||
"Waypaper's hotkeys:\n"
|
||||
" hjkl - Navigation (←↓↑→)\n"
|
||||
" f - Change wallpaper folder\n"
|
||||
" g - Scroll to top\n"
|
||||
" G - Scroll to bottom\n"
|
||||
" R - Set random wallpaper\n"
|
||||
" r - Recache wallpapers\n"
|
||||
" s - Include/exclude images in subfolders\n"
|
||||
" ? - Help\n"
|
||||
" q - Exit\n"
|
||||
" For more information, visit:\n"
|
||||
" {url}\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"Waypapers Tastenkürzel:\n"
|
||||
"Navigation (←↓↑→)\n"
|
||||
"f - Hintergrundbild-Ordner ändern\n"
|
||||
"g - Zum Anfang scrollen\\nG - Zum Ende scrollen\n"
|
||||
"G - Zum Ende scrollen\n"
|
||||
"R - Zufälliges Hintergrundbild\n"
|
||||
"r - Hintergrundbilder zwischenspeichern\n"
|
||||
"s - Unterordner mit einbeziehen\n"
|
||||
"? - Hilfe\n"
|
||||
"q - Beenden\n"
|
||||
"Weitere Informationen finden Sie unter:\n"
|
||||
"{url}\n"
|
232
po/en.po
Normal file
232
po/en.po
Normal file
@ -0,0 +1,232 @@
|
||||
# English translations for waypaper package.
|
||||
# This file is put in the public domain.
|
||||
# Automatically generated, 2023.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: waypaper 0.0.2\n"
|
||||
"Report-Msgid-Bugs-To: none@none\n"
|
||||
"POT-Creation-Date: 2023-10-16 18:48+0300\n"
|
||||
"PO-Revision-Date: 2023-10-16 18:48+0300\n"
|
||||
"Last-Translator: Automatically generated\n"
|
||||
"Language-Team: none\n"
|
||||
"Language: en\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: waypaper/__main__.py:28
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"GUI wallpaper setter for Wayland and X11. It works as a frontend for "
|
||||
"{backends}"
|
||||
msgstr ""
|
||||
"GUI wallpaper setter for Wayland and X11. It works as a frontend for "
|
||||
"{backends}"
|
||||
|
||||
#: waypaper/__main__.py:29
|
||||
#, python-brace-format
|
||||
msgid "For more information, visit: {homePage}"
|
||||
msgstr "For more information, visit: {homePage}"
|
||||
|
||||
#: waypaper/__main__.py:31
|
||||
msgid "print version of the program"
|
||||
msgstr "print version of the program"
|
||||
|
||||
#: waypaper/__main__.py:33
|
||||
msgid "restore last wallpaper"
|
||||
msgstr "restore last wallpaper"
|
||||
|
||||
#: waypaper/__main__.py:34
|
||||
msgid "set a random wallpaper"
|
||||
msgstr "set a random wallpaper"
|
||||
|
||||
#: waypaper/__main__.py:35
|
||||
msgid "specify how to fill the screen with chosen image"
|
||||
msgstr "specify how to fill the screen with chosen image"
|
||||
|
||||
#: waypaper/__main__.py:37
|
||||
msgid "specify which backend to use to set wallpaper"
|
||||
msgstr "specify which backend to use to set wallpaper"
|
||||
|
||||
#: waypaper/app.py:69
|
||||
msgid "Change wallpaper folder"
|
||||
msgstr "Change wallpaper folder"
|
||||
|
||||
#: waypaper/app.py:89
|
||||
msgid "Subfolders"
|
||||
msgstr "Subfolders"
|
||||
|
||||
#: waypaper/app.py:92
|
||||
msgid "Include/exclude images in subfolders"
|
||||
msgstr "Include/exclude images in subfolders"
|
||||
|
||||
#: waypaper/app.py:108
|
||||
msgid "Choose backend"
|
||||
msgstr "Choose backend"
|
||||
|
||||
#: waypaper/app.py:112
|
||||
msgid "Fill"
|
||||
msgstr "Fill"
|
||||
|
||||
#: waypaper/app.py:113
|
||||
msgid "Stretch"
|
||||
msgstr "Stretch"
|
||||
|
||||
#: waypaper/app.py:114
|
||||
msgid "Fit"
|
||||
msgstr "Fit"
|
||||
|
||||
#: waypaper/app.py:115
|
||||
msgid "Center"
|
||||
msgstr "Center"
|
||||
|
||||
#: waypaper/app.py:116
|
||||
msgid "Tile"
|
||||
msgstr "Tile"
|
||||
|
||||
#: waypaper/app.py:121
|
||||
msgid "Choose fill type"
|
||||
msgstr "Choose fill type"
|
||||
|
||||
#: waypaper/app.py:130
|
||||
msgid "Choose background color"
|
||||
msgstr "Choose background color"
|
||||
|
||||
#: waypaper/app.py:134 waypaper/app.py:135
|
||||
msgid "Name"
|
||||
msgstr "Name"
|
||||
|
||||
#: waypaper/app.py:136 waypaper/app.py:137
|
||||
msgid "Date"
|
||||
msgstr "Date"
|
||||
|
||||
#: waypaper/app.py:144
|
||||
msgid "Choose sorting type"
|
||||
msgstr "Choose sorting type"
|
||||
|
||||
#: waypaper/app.py:148
|
||||
msgid "Exit"
|
||||
msgstr "Exit"
|
||||
|
||||
#: waypaper/app.py:150
|
||||
msgid "Exit the application"
|
||||
msgstr "Exit the application"
|
||||
|
||||
#: waypaper/app.py:153
|
||||
msgid "Refresh"
|
||||
msgstr "Refresh"
|
||||
|
||||
#: waypaper/app.py:156
|
||||
msgid "Reache the folder of images"
|
||||
msgstr "Reache the folder of images"
|
||||
|
||||
#: waypaper/app.py:159
|
||||
msgid "Random"
|
||||
msgstr "Random"
|
||||
|
||||
#: waypaper/app.py:161
|
||||
msgid "Set random wallpaper"
|
||||
msgstr "Set random wallpaper"
|
||||
|
||||
#: waypaper/app.py:214
|
||||
#, python-brace-format
|
||||
msgid "Error determining monitor names: {error}"
|
||||
msgstr "Error determining monitor names: {error}"
|
||||
|
||||
#: waypaper/app.py:222
|
||||
msgid "Choose Display"
|
||||
msgstr "Choose Display"
|
||||
|
||||
#: waypaper/app.py:239
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"\n"
|
||||
" Looks like none of the wallpaper backends is installed in the "
|
||||
"system.\n"
|
||||
" Use your package manager to install at least one of these "
|
||||
"backends:\n"
|
||||
" {backends}\n"
|
||||
" For more information, visit: {url}"
|
||||
msgstr ""
|
||||
"\n"
|
||||
" Looks like none of the wallpaper backends is installed in the "
|
||||
"system.\n"
|
||||
" Use your package manager to install at least one of these "
|
||||
"backends:\n"
|
||||
" {backends}\n"
|
||||
" For more information, visit: {url}"
|
||||
|
||||
#: waypaper/app.py:282
|
||||
msgid "Caching wallpapers.."
|
||||
msgstr "Caching wallpapers.."
|
||||
|
||||
#: waypaper/app.py:364
|
||||
msgid "Please choose a folder"
|
||||
msgstr "Please choose a folder"
|
||||
|
||||
#: waypaper/app.py:365
|
||||
msgid "Select"
|
||||
msgstr "Select"
|
||||
|
||||
#: waypaper/app.py:425 waypaper/app.py:451 waypaper/app.py:530
|
||||
#, python-brace-format
|
||||
msgid "Selected image path: {image}"
|
||||
msgstr "Selected image path: {image}"
|
||||
|
||||
#: waypaper/app.py:463
|
||||
#, python-brace-format
|
||||
msgid "Error deleting cache '{cacheDir}': '{error}'"
|
||||
msgstr "Error deleting cache '{cacheDir}': '{error}'"
|
||||
|
||||
#: waypaper/app.py:513
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Waypaper's hotkeys:\n"
|
||||
" hjkl - Navigation (←↓↑→)\n"
|
||||
" f - Change wallpaper folder\n"
|
||||
" g - Scroll to top\n"
|
||||
" G - Scroll to bottom\n"
|
||||
" R - Set random wallpaper\n"
|
||||
" r - Recache wallpapers\n"
|
||||
" s - Include/exclude images in subfolders\n"
|
||||
" ? - Help\n"
|
||||
" q - Exit\n"
|
||||
" For more information, visit:\n"
|
||||
" {url}\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"Waypaper's hotkeys:\n"
|
||||
" hjkl - Navigation (←↓↑→)\n"
|
||||
" f - Change wallpaper folder\n"
|
||||
" g - Scroll to top\n"
|
||||
" G - Scroll to bottom\n"
|
||||
" R - Set random wallpaper\n"
|
||||
" r - Recache wallpapers\n"
|
||||
" s - Include/exclude images in subfolders\n"
|
||||
" ? - Help\n"
|
||||
" q - Exit\n"
|
||||
" For more information, visit:\n"
|
||||
" {url}\n"
|
||||
" "
|
||||
|
||||
#: waypaper/changer.py:23 waypaper/changer.py:46
|
||||
#, python-brace-format
|
||||
msgid "Warning related to killall: {error}"
|
||||
msgstr "Warning related to killall: {error}"
|
||||
|
||||
#: waypaper/changer.py:84
|
||||
#, python-brace-format
|
||||
msgid "Sent command to set wallpaper was set with {backend}"
|
||||
msgstr "Sent command to set wallpaper was set with {backend}"
|
||||
|
||||
#: waypaper/changer.py:88
|
||||
#, python-brace-format
|
||||
msgid "The backend is not supported: {backend}"
|
||||
msgstr "The backend is not supported: {backend}"
|
||||
|
||||
#: waypaper/changer.py:92
|
||||
#, python-brace-format
|
||||
msgid "Error changing wallpaper: {error}"
|
||||
msgstr "Error changing wallpaper: {error}"
|
230
po/fr.po
Normal file
230
po/fr.po
Normal file
@ -0,0 +1,230 @@
|
||||
# French translations for waypaper package.
|
||||
# This file is put in the public domain.
|
||||
# bidar <bjorn.bidar@thaodan.de>, 2023.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: waypaper 0.0.2\n"
|
||||
"Report-Msgid-Bugs-To: none@none\n"
|
||||
"POT-Creation-Date: 2023-10-16 17:25+0300\n"
|
||||
"PO-Revision-Date: 2023-10-16 18:21+0300\n"
|
||||
"Last-Translator: Björn Bidar <bjorn.bidar@thaodan.de>\n"
|
||||
"Language-Team: French <traduc@traduc.org>\n"
|
||||
"Language: fr\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
|
||||
#: waypaper/__main__.py:28
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"GUI wallpaper setter for Wayland and X11. It works as a frontend for "
|
||||
"{backends}"
|
||||
msgstr "Sélecteur de papier peint graphique pour Wayland et X11. Il fonctionne comme une interface pour {backends}"
|
||||
|
||||
#: waypaper/__main__.py:29
|
||||
#, python-brace-format
|
||||
msgid "For more information, visit: {homePage}"
|
||||
msgstr "Pour plus d'informations, visitez {homePage}"
|
||||
|
||||
#: waypaper/__main__.py:31
|
||||
msgid "print version of the program"
|
||||
msgstr "afficher la version du programme"
|
||||
|
||||
#: waypaper/__main__.py:33
|
||||
msgid "restore last wallpaper"
|
||||
msgstr "restaurer le dernier papier peint"
|
||||
|
||||
#: waypaper/__main__.py:34
|
||||
msgid "set a random wallpaper"
|
||||
msgstr "définir un papier peint aléatoire"
|
||||
|
||||
#: waypaper/__main__.py:35
|
||||
msgid "specify how to fill the screen with chosen image"
|
||||
msgstr "spécifier comment remplir l'écran avec l'image choisie"
|
||||
|
||||
#: waypaper/__main__.py:37
|
||||
msgid "specify which backend to use to set wallpaper"
|
||||
msgstr "spécifier quel backend utiliser pour définir le papier peint"
|
||||
|
||||
#: waypaper/changer.py:23 waypaper/changer.py:46
|
||||
#, python-brace-format
|
||||
msgid "Warning related to killall: {error}"
|
||||
msgstr "Avertissement lié à killall: {error}"
|
||||
|
||||
#: waypaper/changer.py:84
|
||||
#, python-brace-format
|
||||
msgid "Sent command to set wallpaper was set with {backend}"
|
||||
msgstr "La commande envoyée pour définir le papier peint a été définie avec {backend}"
|
||||
|
||||
#: waypaper/changer.py:88
|
||||
#, python-brace-format
|
||||
msgid "The backend is not supported: {backend}"
|
||||
msgstr "Le backend n'est pas pris en charge: {backend}"
|
||||
|
||||
#: waypaper/changer.py:92
|
||||
#, python-brace-format
|
||||
msgid "Error changing wallpaper: {error}"
|
||||
msgstr "Erreur lors du changement de papie peint: {error}"
|
||||
|
||||
#: waypaper/app.py:69
|
||||
msgid "Change wallpaper folder"
|
||||
msgstr "Changer de dossier de papier peint"
|
||||
|
||||
#: waypaper/app.py:89
|
||||
msgid "Subfolders"
|
||||
msgstr "Sous-dossiers"
|
||||
|
||||
#: waypaper/app.py:92
|
||||
msgid "Include/exclude images in subfolders"
|
||||
msgstr "Inclure/exclure les images des sous-dossiers"
|
||||
|
||||
#: waypaper/app.py:108
|
||||
msgid "Choose backen"
|
||||
msgstr "Choisir le backend"
|
||||
|
||||
#: waypaper/app.py:112
|
||||
msgid "Fill"
|
||||
msgstr "Remplir"
|
||||
|
||||
#: waypaper/app.py:113
|
||||
msgid "Stretch"
|
||||
msgstr "Étirer"
|
||||
|
||||
#: waypaper/app.py:114
|
||||
msgid "Fit"
|
||||
msgstr "S'adapter"
|
||||
|
||||
#: waypaper/app.py:115
|
||||
msgid "Center"
|
||||
msgstr "Centrer"
|
||||
|
||||
#: waypaper/app.py:116
|
||||
msgid "Tile"
|
||||
msgstr "Carreler"
|
||||
|
||||
#: waypaper/app.py:121
|
||||
msgid "Choose fill type"
|
||||
msgstr "Choisir le type de remplissage"
|
||||
|
||||
#: waypaper/app.py:130
|
||||
msgid "Choose background color"
|
||||
msgstr "Choisir la couleur de fond"
|
||||
|
||||
#: waypaper/app.py:134 waypaper/app.py:135
|
||||
msgid "Name"
|
||||
msgstr "Nom"
|
||||
|
||||
#: waypaper/app.py:136 waypaper/app.py:137
|
||||
msgid "Date"
|
||||
msgstr "Date"
|
||||
|
||||
#: waypaper/app.py:144
|
||||
msgid "Choose sorting type"
|
||||
msgstr "Choisir le type de tri"
|
||||
|
||||
#: waypaper/app.py:148
|
||||
msgid "Exit"
|
||||
msgstr "Quitter"
|
||||
|
||||
#: waypaper/app.py:150
|
||||
msgid "Exit the application"
|
||||
msgstr "Quitter l'application"
|
||||
|
||||
#: waypaper/app.py:153
|
||||
msgid "Refresh"
|
||||
msgstr "Actualiser"
|
||||
|
||||
#: waypaper/app.py:156
|
||||
msgid "Reache the folder of images"
|
||||
msgstr "Recréer le dossier d'images"
|
||||
|
||||
#: waypaper/app.py:159
|
||||
msgid "Random"
|
||||
msgstr "Aléatoire"
|
||||
|
||||
#: waypaper/app.py:161
|
||||
msgid "Set random wallpaper"
|
||||
msgstr "Définir un papier peint aléatoire"
|
||||
|
||||
#: waypaper/app.py:214
|
||||
#, python-brace-format
|
||||
msgid "Error determining monitor names: {error}"
|
||||
msgstr "Erreur lors de la détermination des noms des moniteurs: {error}"
|
||||
|
||||
#: waypaper/app.py:222
|
||||
msgid "Choose Display"
|
||||
msgstr "Choisir l'affichage"
|
||||
|
||||
#: waypaper/app.py:239
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"\n"
|
||||
" Looks like none of the wallpaper backends is installed in the "
|
||||
"system.\n"
|
||||
" Use your package manager to install at least one of these "
|
||||
"backends:\n"
|
||||
" {backends}\n"
|
||||
" For more information, visit: {url}"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"Il semble qu'aucun des backends de papier peint ne soit installé sur le système.\n"
|
||||
"Utilisez votre gestionnaire de paquets pour installer au moins l'un de ces backends:\n"
|
||||
"{backends}\n"
|
||||
"\n"
|
||||
"Pour plus d'informations, visitez: {url}"
|
||||
|
||||
#: waypaper/app.py:282
|
||||
msgid "Caching wallpapers.."
|
||||
msgstr "Mise en cache des papiers peints.."
|
||||
|
||||
#: waypaper/app.py:364
|
||||
msgid "Please choose a folder"
|
||||
msgstr "Veuillez choisir un dossier"
|
||||
|
||||
#: waypaper/app.py:365
|
||||
msgid "Select"
|
||||
msgstr "Sélectionner"
|
||||
|
||||
#: waypaper/app.py:425 waypaper/app.py:451 waypaper/app.py:530
|
||||
#, python-brace-format
|
||||
msgid "Selected image path: {image}"
|
||||
msgstr "Chemin de l'image sélectionnée: {image}"
|
||||
|
||||
#: waypaper/app.py:463
|
||||
#, python-brace-format
|
||||
msgid "Error deleting cache '{cacheDir}': '{error}'"
|
||||
msgstr "Erreur lors de la suppression du cache '{cacheDir}': '{error}'"
|
||||
|
||||
#: waypaper/app.py:513
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Waypaper's hotkeys:\n"
|
||||
" hjkl - Navigation (←↓↑→)\n"
|
||||
" f - Change wallpaper folder\n"
|
||||
" g - Scroll to top\n"
|
||||
" G - Scroll to bottom\n"
|
||||
" R - Set random wallpaper\n"
|
||||
" r - Recache wallpapers\n"
|
||||
" s - Include/exclude images in subfolders\n"
|
||||
" ? - Help\n"
|
||||
" q - Exit\n"
|
||||
" For more information, visit:\n"
|
||||
" {url}\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"Raccourcis clavier de Waypaper:\n"
|
||||
"hjkl - Navigation (←↓↑→)\n"
|
||||
"f - Changer de dossier de papier peint\n"
|
||||
"g - Faire défiler vers le haut\n"
|
||||
"G - Faire défiler vers le bas\n"
|
||||
"R - Définir un papier peint aléatoire\n"
|
||||
"r - Recréer le cache des papiers peints\n"
|
||||
"s - Inclure/exclure les images des sous-dossiers\n"
|
||||
"? - Aide\n"
|
||||
"q - Quitter\n"
|
||||
"\n"
|
||||
"Pour plus d'informations, visitez:\n"
|
||||
"{url}\n"
|
||||
" "
|
206
po/waypaper.pot
Normal file
206
po/waypaper.pot
Normal file
@ -0,0 +1,206 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# This file is put in the public domain.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr "Project-Id-Version: waypaper 0.0.2\n"
|
||||
"Report-Msgid-Bugs-To: none@none\n"
|
||||
"POT-Creation-Date: 2023-10-16 18:48+0300\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: waypaper/__main__.py:28
|
||||
#, python-brace-format
|
||||
msgid "GUI wallpaper setter for Wayland and X11. It works as a frontend for "
|
||||
"{backends}"
|
||||
msgstr ""
|
||||
|
||||
#: waypaper/__main__.py:29
|
||||
#, python-brace-format
|
||||
msgid "For more information, visit: {homePage}"
|
||||
msgstr ""
|
||||
|
||||
#: waypaper/__main__.py:31
|
||||
msgid "print version of the program"
|
||||
msgstr ""
|
||||
|
||||
#: waypaper/__main__.py:33
|
||||
msgid "restore last wallpaper"
|
||||
msgstr ""
|
||||
|
||||
#: waypaper/__main__.py:34
|
||||
msgid "set a random wallpaper"
|
||||
msgstr ""
|
||||
|
||||
#: waypaper/__main__.py:35
|
||||
msgid "specify how to fill the screen with chosen image"
|
||||
msgstr ""
|
||||
|
||||
#: waypaper/__main__.py:37
|
||||
msgid "specify which backend to use to set wallpaper"
|
||||
msgstr ""
|
||||
|
||||
#: waypaper/app.py:69
|
||||
msgid "Change wallpaper folder"
|
||||
msgstr ""
|
||||
|
||||
#: waypaper/app.py:89
|
||||
msgid "Subfolders"
|
||||
msgstr ""
|
||||
|
||||
#: waypaper/app.py:92
|
||||
msgid "Include/exclude images in subfolders"
|
||||
msgstr ""
|
||||
|
||||
#: waypaper/app.py:108
|
||||
msgid "Choose backend"
|
||||
msgstr ""
|
||||
|
||||
#: waypaper/app.py:112
|
||||
msgid "Fill"
|
||||
msgstr ""
|
||||
|
||||
#: waypaper/app.py:113
|
||||
msgid "Stretch"
|
||||
msgstr ""
|
||||
|
||||
#: waypaper/app.py:114
|
||||
msgid "Fit"
|
||||
msgstr ""
|
||||
|
||||
#: waypaper/app.py:115
|
||||
msgid "Center"
|
||||
msgstr ""
|
||||
|
||||
#: waypaper/app.py:116
|
||||
msgid "Tile"
|
||||
msgstr ""
|
||||
|
||||
#: waypaper/app.py:121
|
||||
msgid "Choose fill type"
|
||||
msgstr ""
|
||||
|
||||
#: waypaper/app.py:130
|
||||
msgid "Choose background color"
|
||||
msgstr ""
|
||||
|
||||
#: waypaper/app.py:134 waypaper/app.py:135
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
|
||||
#: waypaper/app.py:136 waypaper/app.py:137
|
||||
msgid "Date"
|
||||
msgstr ""
|
||||
|
||||
#: waypaper/app.py:144
|
||||
msgid "Choose sorting type"
|
||||
msgstr ""
|
||||
|
||||
#: waypaper/app.py:148
|
||||
msgid "Exit"
|
||||
msgstr ""
|
||||
|
||||
#: waypaper/app.py:150
|
||||
msgid "Exit the application"
|
||||
msgstr ""
|
||||
|
||||
#: waypaper/app.py:153
|
||||
msgid "Refresh"
|
||||
msgstr ""
|
||||
|
||||
#: waypaper/app.py:156
|
||||
msgid "Reache the folder of images"
|
||||
msgstr ""
|
||||
|
||||
#: waypaper/app.py:159
|
||||
msgid "Random"
|
||||
msgstr ""
|
||||
|
||||
#: waypaper/app.py:161
|
||||
msgid "Set random wallpaper"
|
||||
msgstr ""
|
||||
|
||||
#: waypaper/app.py:214
|
||||
#, python-brace-format
|
||||
msgid "Error determining monitor names: {error}"
|
||||
msgstr ""
|
||||
|
||||
#: waypaper/app.py:222
|
||||
msgid "Choose Display"
|
||||
msgstr ""
|
||||
|
||||
#: waypaper/app.py:239
|
||||
#, python-brace-format
|
||||
msgid "\n"
|
||||
" Looks like none of the wallpaper backends is installed "
|
||||
"in the system.\n"
|
||||
" Use your package manager to install at least one of "
|
||||
"these backends:\n"
|
||||
" {backends}\n"
|
||||
" For more information, visit: {url}"
|
||||
msgstr ""
|
||||
|
||||
#: waypaper/app.py:282
|
||||
msgid "Caching wallpapers.."
|
||||
msgstr ""
|
||||
|
||||
#: waypaper/app.py:364
|
||||
msgid "Please choose a folder"
|
||||
msgstr ""
|
||||
|
||||
#: waypaper/app.py:365
|
||||
msgid "Select"
|
||||
msgstr ""
|
||||
|
||||
#: waypaper/app.py:425 waypaper/app.py:451 waypaper/app.py:530
|
||||
#, python-brace-format
|
||||
msgid "Selected image path: {image}"
|
||||
msgstr ""
|
||||
|
||||
#: waypaper/app.py:463
|
||||
#, python-brace-format
|
||||
msgid "Error deleting cache '{cacheDir}': '{error}'"
|
||||
msgstr ""
|
||||
|
||||
#: waypaper/app.py:513
|
||||
#, python-brace-format
|
||||
msgid "Waypaper's hotkeys:\n"
|
||||
" hjkl - Navigation (←↓↑→)\n"
|
||||
" f - Change wallpaper folder\n"
|
||||
" g - Scroll to top\n"
|
||||
" G - Scroll to bottom\n"
|
||||
" R - Set random wallpaper\n"
|
||||
" r - Recache wallpapers\n"
|
||||
" s - Include/exclude images in subfolders\n"
|
||||
" ? - Help\n"
|
||||
" q - Exit\n"
|
||||
" For more information, visit:\n"
|
||||
" {url}\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: waypaper/changer.py:23 waypaper/changer.py:46
|
||||
#, python-brace-format
|
||||
msgid "Warning related to killall: {error}"
|
||||
msgstr ""
|
||||
|
||||
#: waypaper/changer.py:84
|
||||
#, python-brace-format
|
||||
msgid "Sent command to set wallpaper was set with {backend}"
|
||||
msgstr ""
|
||||
|
||||
#: waypaper/changer.py:88
|
||||
#, python-brace-format
|
||||
msgid "The backend is not supported: {backend}"
|
||||
msgstr ""
|
||||
|
||||
#: waypaper/changer.py:92
|
||||
#, python-brace-format
|
||||
msgid "Error changing wallpaper: {error}"
|
||||
msgstr ""
|
@ -1,4 +1,4 @@
|
||||
[build-system]
|
||||
requires = ["setuptools", "wheel"]
|
||||
requires = ["setuptools", "wheel", "setuptools-gettext"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
|
21
setup.py
21
setup.py
@ -1,20 +1,25 @@
|
||||
from pathlib import Path
|
||||
import re
|
||||
import setuptools
|
||||
|
||||
setup_dir = Path(__file__).resolve().parent
|
||||
|
||||
version = re.search( r'__version__ = "(.*)"', Path(setup_dir, 'waypaper/__main__.py').open().read())
|
||||
if version is None:
|
||||
raise SystemExit("Could not determine version to use")
|
||||
version = version.group(1)
|
||||
long_description = ''
|
||||
|
||||
try:
|
||||
long_description = \
|
||||
Path(setup_dir, 'README.md').open().read()
|
||||
except:
|
||||
# In case we don't find README.md ignore it,
|
||||
# e.g. when we update translations
|
||||
pass
|
||||
|
||||
setuptools.setup(
|
||||
name='waypaper',
|
||||
author='Roman Anufriev',
|
||||
author_email='anufriev.roman@protonmail.com',
|
||||
url='https://github.com/anufrievroman/waypaper',
|
||||
description='GUI wallpaper setter for Wayland',
|
||||
long_description=Path(setup_dir, 'README.md').open().read(),
|
||||
long_description=long_description,
|
||||
long_description_content_type='text/markdown',
|
||||
license='GPL',
|
||||
entry_points={
|
||||
@ -22,8 +27,8 @@ setuptools.setup(
|
||||
"waypaper = waypaper.__main__:run"
|
||||
]
|
||||
},
|
||||
install_requires=["PyGObject"],
|
||||
version=version,
|
||||
install_requires=["PyGObject", "importlib_metadata", "platformdirs"],
|
||||
version='0.0.2',
|
||||
python_requires='>3.9',
|
||||
classifiers=[
|
||||
"Development Status :: 4 - Beta",
|
||||
|
@ -1,21 +1,42 @@
|
||||
"""Main module that runs the program and either runs GUI or just changer wallpaper"""
|
||||
|
||||
import time
|
||||
import argparse
|
||||
import gettext
|
||||
|
||||
|
||||
from waypaper.config import cf
|
||||
from waypaper.arguments import args
|
||||
from waypaper.config import Config
|
||||
from waypaper.app import App
|
||||
from waypaper.changer import change_wallpaper
|
||||
from waypaper.common import get_random_file
|
||||
from waypaper.aboutdata import AboutData
|
||||
from waypaper.options import FILL_OPTIONS, BACKEND_OPTIONS
|
||||
|
||||
|
||||
|
||||
__version__ = "2.0.2"
|
||||
|
||||
|
||||
def run():
|
||||
"""Read user arguments and either run GUI app or just reset the wallpaper"""
|
||||
|
||||
aboutData = AboutData()
|
||||
|
||||
gettext.install(aboutData.applicationName())
|
||||
|
||||
cf = Config()
|
||||
|
||||
parser = argparse.ArgumentParser(prog = aboutData.applicationName(), description =
|
||||
_("GUI wallpaper setter for Wayland and X11. It works as a frontend for {backends}".format(backends=BACKEND_OPTIONS)),
|
||||
epilog = _("For more information, visit: {homePage}").
|
||||
format(homePage=aboutData.homePage()))
|
||||
parser.add_argument("-v", "--version", help=_("print version of the program"),
|
||||
action="store_true")
|
||||
parser.add_argument("--restore", help=_("restore last wallpaper"), action="store_true")
|
||||
parser.add_argument("--random", help=_("set a random wallpaper"), action="store_true")
|
||||
parser.add_argument("--fill", help=_("specify how to fill the screen with chosen image"),
|
||||
action="store_true")
|
||||
parser.add_argument("--backend", help=_("specify which backend to use to set wallpaper"),
|
||||
choices=BACKEND_OPTIONS)
|
||||
args = parser.parse_args()
|
||||
cf.read_parameters_from_user_arguments(args)
|
||||
|
||||
# Set the wallpaper and quit:
|
||||
@ -29,12 +50,12 @@ def run():
|
||||
continue
|
||||
change_wallpaper(wallpaper, cf.fill_option, cf.color, cf.backend, monitor)
|
||||
time.sleep(0.1)
|
||||
exit()
|
||||
exit(0)
|
||||
|
||||
# Print the version and quit:
|
||||
if args.version:
|
||||
print(f"waypaper v.{__version__}")
|
||||
exit()
|
||||
print(f"{aboutData.applicationName()} v.{aboutData.applicationVersion()}")
|
||||
exit(0)
|
||||
|
||||
# Start GUI:
|
||||
app = App()
|
||||
|
19
waypaper/aboutdata.py
Normal file
19
waypaper/aboutdata.py
Normal file
@ -0,0 +1,19 @@
|
||||
"""Module to store acces application metadata"""
|
||||
from importlib_metadata import metadata
|
||||
|
||||
class AboutData():
|
||||
"""This class stores application about data in a central place"""
|
||||
def __init__(self):
|
||||
self.__app_metadata = metadata(__package__)
|
||||
def applicationName(self):
|
||||
return self.__app_metadata['Name']
|
||||
def applicationSummary(self):
|
||||
return self.__app_metadata['Summary']
|
||||
def applicationLogo(self):
|
||||
return str(self.__app_metadata['Name'])+".svg"
|
||||
def applicationVersion(self):
|
||||
return self.__app_metadata['Version'] # pylint: disable=no-member
|
||||
def homePage(self):
|
||||
return self.__app_metadata['Home-page']
|
||||
def Author(self):
|
||||
return self.__app_metadata['Author']
|
220
waypaper/app.py
220
waypaper/app.py
@ -5,38 +5,37 @@ import threading
|
||||
import os
|
||||
import shutil
|
||||
import gi
|
||||
from pathlib import Path
|
||||
from platformdirs import user_cache_path
|
||||
import gettext
|
||||
|
||||
from waypaper.aboutdata import AboutData
|
||||
from waypaper.changer import change_wallpaper
|
||||
from waypaper.config import cf
|
||||
from waypaper.config import Config
|
||||
from waypaper.common import get_image_paths, get_random_file
|
||||
from waypaper.options import FILL_OPTIONS, BACKEND_OPTIONS, SORT_OPTIONS, SORT_DISPLAYS
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, GdkPixbuf, Gdk, GLib
|
||||
|
||||
if cf.lang == "de":
|
||||
from waypaper.translation_de import *
|
||||
elif cf.lang == "fr":
|
||||
from waypaper.translation_fr import *
|
||||
elif cf.lang == "ru":
|
||||
from waypaper.translation_ru import *
|
||||
elif cf.lang == "pl":
|
||||
from waypaper.translation_pl import *
|
||||
elif cf.lang == "zh":
|
||||
from waypaper.translation_zh import *
|
||||
else:
|
||||
from waypaper.translation_en import *
|
||||
|
||||
|
||||
def cache_image(image_path):
|
||||
def cache_image(image_path, cachedir):
|
||||
"""Resize and cache images using gtk library"""
|
||||
pixbuf = GdkPixbuf.Pixbuf.new_from_file(image_path)
|
||||
try:
|
||||
pixbuf = GdkPixbuf.Pixbuf.new_from_file(str(image_path))
|
||||
except GLib.Error as err:
|
||||
if err.matches(GdkPixbuf.pixbuf_error_quark(), GdkPixbuf.PixbufError.CORRUPT_IMAGE):
|
||||
# Ignore errors where GdkPixbuf tries to open an image by its extension
|
||||
# but the extension doesn't match the real mime type
|
||||
return False
|
||||
else:
|
||||
raise
|
||||
|
||||
aspect_ratio = pixbuf.get_width() / pixbuf.get_height()
|
||||
scaled_width = 240
|
||||
scaled_height = int(scaled_width / aspect_ratio)
|
||||
scaled_pixbuf = pixbuf.scale_simple(scaled_width, scaled_height, GdkPixbuf.InterpType.BILINEAR)
|
||||
output_file = f"{cf.config_folder}/.cache/{os.path.basename(image_path)}"
|
||||
scaled_pixbuf.savev(output_file, "jpeg", [], [])
|
||||
output_file = cachedir / Path(os.path.basename(image_path))
|
||||
scaled_pixbuf.savev(str(output_file), "jpeg", [], [])
|
||||
|
||||
|
||||
class App(Gtk.Window):
|
||||
@ -46,15 +45,19 @@ class App(Gtk.Window):
|
||||
super().__init__(title="Waypaper")
|
||||
self.check_backends()
|
||||
self.set_default_size(780, 600)
|
||||
self.init_ui()
|
||||
self.connect("delete-event", Gtk.main_quit)
|
||||
self.selected_index = 0
|
||||
self.highlighted_image_row = 0
|
||||
self.aboutData = AboutData()
|
||||
self.cachePath = user_cache_path(self.aboutData.applicationName())
|
||||
gettext.install(self.aboutData.applicationName())
|
||||
self.cf = Config()
|
||||
|
||||
self.init_ui()
|
||||
|
||||
# Start the image processing in a separate thread:
|
||||
threading.Thread(target=self.process_images).start()
|
||||
|
||||
|
||||
def init_ui(self):
|
||||
"""Initialize the UI elements of the application"""
|
||||
|
||||
@ -63,7 +66,7 @@ class App(Gtk.Window):
|
||||
self.add(self.main_box)
|
||||
|
||||
# Create a button to open folder dialog:
|
||||
self.choose_folder_button = Gtk.Button(label=MSG_CHANGEFOLDER)
|
||||
self.choose_folder_button = Gtk.Button(label=_("Change wallpaper folder"))
|
||||
self.choose_folder_button.connect("clicked", self.on_choose_folder_clicked)
|
||||
self.main_box.pack_start(self.choose_folder_button, False, False, 0)
|
||||
|
||||
@ -83,10 +86,10 @@ class App(Gtk.Window):
|
||||
self.scrolled_window.add(self.grid)
|
||||
|
||||
# Create subfolder toggle:
|
||||
self.include_subfolders_checkbox = Gtk.ToggleButton(label=MSG_SUBFOLDERS)
|
||||
self.include_subfolders_checkbox.set_active(cf.include_subfolders)
|
||||
self.include_subfolders_checkbox = Gtk.ToggleButton(label=_("Subfolders"))
|
||||
self.include_subfolders_checkbox.set_active(self.cf.include_subfolders)
|
||||
self.include_subfolders_checkbox.connect("toggled", self.on_include_subfolders_toggled)
|
||||
self.include_subfolders_checkbox.set_tooltip_text(TIP_SUBFOLDER)
|
||||
self.include_subfolders_checkbox.set_tooltip_text(_("Include/exclude images in subfolders"))
|
||||
|
||||
# Create a backend dropdown menu:
|
||||
self.backend_option_combo = Gtk.ComboBoxText()
|
||||
@ -97,55 +100,65 @@ class App(Gtk.Window):
|
||||
# Set as active line the backend from config, if it is installed:
|
||||
try:
|
||||
installed_backends = [value for value, miss in zip(BACKEND_OPTIONS, self.missing_backends) if not miss]
|
||||
active_num = installed_backends.index(cf.backend)
|
||||
active_num = installed_backends.index(self.cf.backend)
|
||||
except:
|
||||
active_num = 0
|
||||
self.backend_option_combo.set_active(active_num)
|
||||
self.backend_option_combo.connect("changed", self.on_backend_option_changed)
|
||||
self.backend_option_combo.set_tooltip_text(TIP_BACKEND)
|
||||
self.backend_option_combo.set_tooltip_text(_("Choose backend"))
|
||||
|
||||
# Create a fill option dropdown menu:
|
||||
self.fill_option_combo = Gtk.ComboBoxText()
|
||||
for option in FILL_OPTIONS:
|
||||
capitalized_option = option[0].upper() + option[1:]
|
||||
self.fill_option_combo.append_text(capitalized_option)
|
||||
fil_options_text_tr = [ _("Fill"),
|
||||
_("Stretch"),
|
||||
_("Fit"),
|
||||
_("Center"),
|
||||
_("Tile")]
|
||||
for index in range(len(FILL_OPTIONS)):
|
||||
self.fill_option_combo.append_text(fil_options_text_tr[index])
|
||||
self.fill_option_combo.set_active(0)
|
||||
self.fill_option_combo.connect("changed", self.on_fill_option_changed)
|
||||
self.fill_option_combo.set_tooltip_text(TIP_FILL)
|
||||
self.fill_option_combo.set_tooltip_text(_("Choose fill type"))
|
||||
|
||||
# Create a color picker:
|
||||
self.color_picker_button = Gtk.ColorButton()
|
||||
self.color_picker_button.set_use_alpha(True)
|
||||
rgba_color = Gdk.RGBA()
|
||||
rgba_color.parse(cf.color)
|
||||
rgba_color.parse(self.cf.color)
|
||||
self.color_picker_button.set_rgba(rgba_color)
|
||||
self.color_picker_button.connect("color-set", self.on_color_set)
|
||||
self.color_picker_button.set_tooltip_text(TIP_COLOR)
|
||||
self.color_picker_button.set_tooltip_text(_("Choose background color"))
|
||||
|
||||
# Create a sort option dropdown menu:
|
||||
self.sort_option_combo = Gtk.ComboBoxText()
|
||||
for option in SORT_OPTIONS:
|
||||
self.sort_option_combo.append_text(SORT_DISPLAYS[option])
|
||||
active_num = SORT_OPTIONS.index(cf.sort_option)
|
||||
sort_options_text_tr = [ _("Name")+" ↓",
|
||||
_("Name")+" ↑",
|
||||
_("Date")+" ↓",
|
||||
_("Date")+" ↑"]
|
||||
for option in range(len(sort_options_text_tr)):
|
||||
self.sort_option_combo.append_text(sort_options_text_tr[option])
|
||||
active_num = SORT_OPTIONS.index(self.cf.sort_option)
|
||||
self.sort_option_combo.set_active(active_num)
|
||||
self.sort_option_combo.connect("changed", self.on_sort_option_changed)
|
||||
self.sort_option_combo.set_tooltip_text(TIP_SORTING)
|
||||
self.sort_option_combo.set_tooltip_text(
|
||||
_("Choose sorting type"))
|
||||
|
||||
|
||||
# Create exit button:
|
||||
self.exit_button = Gtk.Button(label=MSG_EXIT)
|
||||
self.exit_button = Gtk.Button(label=_("Exit"))
|
||||
self.exit_button.connect("clicked", self.on_exit_clicked)
|
||||
self.exit_button.set_tooltip_text(TIP_EXIT)
|
||||
self.exit_button.set_tooltip_text(_("Exit the application"))
|
||||
|
||||
# Create refresh button:
|
||||
self.refresh_button = Gtk.Button(label=MSG_REFRESH)
|
||||
self.refresh_button = Gtk.Button(label=_("Refresh"))
|
||||
self.refresh_button.connect("clicked", self.on_refresh_clicked)
|
||||
self.refresh_button.set_tooltip_text(TIP_REFRESH)
|
||||
self.refresh_button.set_tooltip_text(
|
||||
_("Reache the folder of images"))
|
||||
|
||||
# Create random button:
|
||||
self.random_button = Gtk.Button(label=MSG_RANDOM)
|
||||
self.random_button = Gtk.Button(label=_("Random"))
|
||||
self.random_button.connect("clicked", self.on_random_clicked)
|
||||
self.random_button.set_tooltip_text(TIP_RANDOM)
|
||||
self.random_button.set_tooltip_text(_("Set random wallpaper"))
|
||||
|
||||
# Create a box to contain the bottom row of buttons with margin:
|
||||
self.bottom_button_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=20)
|
||||
@ -186,8 +199,8 @@ class App(Gtk.Window):
|
||||
def monitor_option_display(self):
|
||||
"""Display monitor option if backend is swww"""
|
||||
self.options_box.remove(self.monitor_option_combo)
|
||||
# if "swww" not in self.missing_backends and cf.backend not in ["wallutils", "feh"]:
|
||||
if cf.backend == "swww":
|
||||
# if "swww" not in self.missing_backends and self.cf.backend not in ["wallutils", "feh"]:
|
||||
if self.cf.backend == "swww":
|
||||
|
||||
# Check available monitors:
|
||||
monitor_names = ["All"]
|
||||
@ -198,7 +211,7 @@ class App(Gtk.Window):
|
||||
for monitor in monitors[:-1]:
|
||||
monitor_names.append(monitor.split(':')[0])
|
||||
except Exception as e:
|
||||
print(f"{ERR_DISP} {e}")
|
||||
print(_("Error determining monitor names: {error}").format(error=e))
|
||||
|
||||
# Create a monitor option dropdown menu:
|
||||
self.monitor_option_combo = Gtk.ComboBoxText()
|
||||
@ -206,7 +219,7 @@ class App(Gtk.Window):
|
||||
self.monitor_option_combo.append_text(monitor)
|
||||
self.monitor_option_combo.set_active(0)
|
||||
self.monitor_option_combo.connect("changed", self.on_monitor_option_changed)
|
||||
self.monitor_option_combo.set_tooltip_text(TIP_DISPLAY)
|
||||
self.monitor_option_combo.set_tooltip_text(_("Choose Display"))
|
||||
|
||||
# Add it to the row of buttons:
|
||||
self.options_box.pack_start(self.monitor_option_combo, False, False, 0)
|
||||
@ -223,8 +236,13 @@ class App(Gtk.Window):
|
||||
|
||||
# Show error message if no backends are installed:
|
||||
if all(self.missing_backends):
|
||||
self.show_message(ERR_BACKEND)
|
||||
exit()
|
||||
self.show_message(_("""
|
||||
Looks like none of the wallpaper backends is installed in the system.
|
||||
Use your package manager to install at least one of these backends:
|
||||
{backends}
|
||||
For more information, visit: {url}""").format(backends=BACKEND_OPTIONS,
|
||||
url=self.aboutData.homePage()))
|
||||
exit(1)
|
||||
|
||||
|
||||
def show_message(self, message):
|
||||
@ -242,13 +260,13 @@ class App(Gtk.Window):
|
||||
|
||||
def sort_images(self):
|
||||
"""Sort images depending on the sorting option"""
|
||||
if cf.sort_option == "name":
|
||||
if self.cf.sort_option == "name":
|
||||
self.image_paths.sort(key=lambda x: os.path.basename(x))
|
||||
elif cf.sort_option == "namerev":
|
||||
elif self.cf.sort_option == "namerev":
|
||||
self.image_paths.sort(key=lambda x: os.path.basename(x), reverse=True)
|
||||
elif cf.sort_option == "date":
|
||||
elif self.cf.sort_option == "date":
|
||||
self.image_paths.sort(key=lambda x: os.path.getmtime(x))
|
||||
elif cf.sort_option == "daterev":
|
||||
elif self.cf.sort_option == "daterev":
|
||||
self.image_paths.sort(key=lambda x: os.path.getmtime(x), reverse=True)
|
||||
else:
|
||||
pass
|
||||
@ -257,11 +275,11 @@ class App(Gtk.Window):
|
||||
def process_images(self):
|
||||
"""Load images from the selected folder, resize them, and arrange into a grid"""
|
||||
|
||||
self.image_paths = get_image_paths(cf.image_folder, cf.include_subfolders, depth=1)
|
||||
self.image_paths = get_image_paths(self.cf.image_folder, self.cf.include_subfolders, depth=1)
|
||||
self.sort_images()
|
||||
|
||||
# Show caching label:
|
||||
self.loading_label = Gtk.Label(label=MSG_CACHING)
|
||||
self.loading_label = Gtk.Label(label=_("Caching wallpapers.."))
|
||||
self.bottom_loading_box.add(self.loading_label)
|
||||
self.show_all()
|
||||
|
||||
@ -269,14 +287,20 @@ class App(Gtk.Window):
|
||||
self.image_names = []
|
||||
|
||||
for image_path in self.image_paths:
|
||||
|
||||
if os.path.getsize(image_path) == 0:
|
||||
# Skip zero byte files inside the image_path
|
||||
self.image_paths.remove(image_path)
|
||||
continue
|
||||
# If this image is not cached yet, resize and cache it:
|
||||
if not os.path.exists(f"{cf.config_folder}/.cache/{os.path.basename(image_path)}"):
|
||||
cache_image(image_path)
|
||||
cached_image_path = self.cachePath/os.path.basename(image_path)
|
||||
if not cached_image_path.exists():
|
||||
if not cache_image(image_path, self.cachePath):
|
||||
# Cache image didn't work move on to next image
|
||||
self.image_paths.remove(image_path)
|
||||
continue
|
||||
|
||||
# Load cached thumbnail:
|
||||
cached_image_path = f"{cf.config_folder}/.cache/{os.path.basename(image_path)}"
|
||||
thumbnail = GdkPixbuf.Pixbuf.new_from_file(cached_image_path)
|
||||
thumbnail = GdkPixbuf.Pixbuf.new_from_file(str(cached_image_path))
|
||||
self.thumbnails.append(thumbnail)
|
||||
self.image_names.append(os.path.basename(image_path))
|
||||
|
||||
@ -337,12 +361,12 @@ class App(Gtk.Window):
|
||||
"""Choosing the folder of images, saving the path, and reloading images"""
|
||||
|
||||
dialog = Gtk.FileChooserDialog(
|
||||
MSG_CHOOSEFOLDER, self, Gtk.FileChooserAction.SELECT_FOLDER,
|
||||
(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, MSG_SELECT, Gtk.ResponseType.OK)
|
||||
_("Please choose a folder"), self, Gtk.FileChooserAction.SELECT_FOLDER,
|
||||
(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, _("Select"), Gtk.ResponseType.OK)
|
||||
)
|
||||
response = dialog.run()
|
||||
if response == Gtk.ResponseType.OK:
|
||||
cf.image_folder = dialog.get_filename()
|
||||
self.cf.image_folder = dialog.get_filename()
|
||||
threading.Thread(target=self.process_images).start()
|
||||
dialog.destroy()
|
||||
|
||||
@ -354,32 +378,32 @@ class App(Gtk.Window):
|
||||
|
||||
def on_include_subfolders_toggled(self, toggle):
|
||||
"""On chosing to include subfolders"""
|
||||
cf.include_subfolders = toggle.get_active()
|
||||
self.cf.include_subfolders = toggle.get_active()
|
||||
threading.Thread(target=self.process_images).start()
|
||||
|
||||
|
||||
def on_fill_option_changed(self, combo):
|
||||
"""Save fill parameter when it was changed"""
|
||||
cf.fill_option = combo.get_active_text()
|
||||
self.cf.fill_option = FILL_OPTIONS[combo.get_active()]
|
||||
|
||||
|
||||
def on_monitor_option_changed(self, combo):
|
||||
"""Save monitor parameter when it was changed"""
|
||||
cf.selected_monitor = combo.get_active_text()
|
||||
self.cf.selected_monitor = combo.get_active_text()
|
||||
|
||||
|
||||
def on_sort_option_changed(self, combo):
|
||||
"""Save sort parameter whet it is changed"""
|
||||
selected_option = combo.get_active_text()
|
||||
selected_option_num = list(SORT_DISPLAYS.values()).index(selected_option)
|
||||
cf.sort_option = list(SORT_DISPLAYS.keys())[selected_option_num]
|
||||
self.cf.sort_option = list(SORT_DISPLAYS.keys())[selected_option_num]
|
||||
threading.Thread(target=self.process_images).start()
|
||||
|
||||
|
||||
def on_backend_option_changed(self, combo):
|
||||
"""Save backend parameter whet it is changed"""
|
||||
cf.backend = combo.get_active_text()
|
||||
cf.selected_monitor = "All"
|
||||
self.cf.backend = combo.get_active_text()
|
||||
self.cf.selected_monitor = "All"
|
||||
self.monitor_option_display()
|
||||
self.show_all()
|
||||
|
||||
@ -390,18 +414,18 @@ class App(Gtk.Window):
|
||||
red = int(rgba_color.red * 255)
|
||||
green = int(rgba_color.green * 255)
|
||||
blue = int(rgba_color.blue * 255)
|
||||
cf.color = "#{:02X}{:02X}{:02X}".format(red, green, blue)
|
||||
self.cf.color = "#{:02X}{:02X}{:02X}".format(red, green, blue)
|
||||
|
||||
|
||||
def on_image_clicked(self, widget, path):
|
||||
"""On clicking an image, set it as a wallpaper and save"""
|
||||
cf.selected_wallpaper = path
|
||||
self.cf.selected_wallpaper = path
|
||||
self.selected_index = self.image_paths.index(path)
|
||||
self.load_image_grid()
|
||||
print(MSG_PATH, cf.selected_wallpaper)
|
||||
cf.fill_option = self.fill_option_combo.get_active_text() or cf.fill_option
|
||||
change_wallpaper(cf.selected_wallpaper, cf.fill_option, cf.color, cf.backend, cf.selected_monitor)
|
||||
cf.save()
|
||||
print(_("Selected image path: {image}").format(image=self.cf.selected_wallpaper))
|
||||
self.cf.fill_option = FILL_OPTIONS[self.fill_option_combo.get_active()]
|
||||
change_wallpaper(self.cf.selected_wallpaper, self.cf.fill_option, self.cf.color, self.cf.backend, self.cf.selected_monitor)
|
||||
self.cf.save()
|
||||
|
||||
|
||||
def on_refresh_clicked(self, widget):
|
||||
@ -421,23 +445,23 @@ class App(Gtk.Window):
|
||||
|
||||
def set_random_wallpaper(self):
|
||||
"""Choose a random image and set it as the wallpaper"""
|
||||
cf.selected_wallpaper = get_random_file(cf.image_folder, cf.include_subfolders)
|
||||
if cf.selected_wallpaper is None:
|
||||
self.cf.selected_wallpaper = get_random_file(self.cf.image_folder, self.cf.include_subfolders)
|
||||
if self.cf.selected_wallpaper is None:
|
||||
return
|
||||
print(MSG_PATH, cf.selected_wallpaper)
|
||||
cf.fill_option = self.fill_option_combo.get_active_text() or cf.fill_option
|
||||
change_wallpaper(cf.selected_wallpaper, cf.fill_option, cf.color, cf.backend, cf.selected_monitor)
|
||||
cf.save()
|
||||
print(_("Selected image path: {image}").format(image=self.cf.selected_wallpaper))
|
||||
self.cf.fill_option = self.fill_option_combo.get_active_text() or self.cf.fill_option
|
||||
change_wallpaper(self.cf.selected_wallpaper, self.cf.fill_option, self.cf.color, self.cf.backend, self.cf.selected_monitor)
|
||||
self.cf.save()
|
||||
|
||||
|
||||
def clear_cache(self):
|
||||
"""Delete cache folder and reprocess the images"""
|
||||
cache_folder = f"{cf.config_folder}/.cache"
|
||||
try:
|
||||
shutil.rmtree(cache_folder)
|
||||
os.makedirs(cache_folder)
|
||||
shutil.rmtree(self.cachePath)
|
||||
os.makedirs(self.cachePath)
|
||||
except OSError as e:
|
||||
print(f"{ERR_CACHE} '{cache_folder}': {e}")
|
||||
print(_("Error deleting cache '{cachePath}': '{error}'".format(
|
||||
cachePath=self.cachePath, error=e)))
|
||||
threading.Thread(target=self.process_images).start()
|
||||
|
||||
|
||||
@ -486,16 +510,28 @@ class App(Gtk.Window):
|
||||
self.scroll_to_selected_image()
|
||||
|
||||
elif event.keyval == Gdk.KEY_question:
|
||||
message = MSG_HELP
|
||||
self.show_message(message)
|
||||
self.show_message(_("""Waypaper's hotkeys:
|
||||
hjkl - Navigation (←↓↑→)
|
||||
f - Change wallpaper folder
|
||||
g - Scroll to top
|
||||
G - Scroll to bottom
|
||||
R - Set random wallpaper
|
||||
r - Recache wallpapers
|
||||
s - Include/exclude images in subfolders
|
||||
? - Help
|
||||
q - Exit
|
||||
For more information, visit:
|
||||
{url}
|
||||
""").format(url=self.aboutData.homePage()))
|
||||
|
||||
elif event.keyval == Gdk.KEY_Return or event.keyval == Gdk.KEY_KP_Enter:
|
||||
wallpaper_path = self.image_paths[self.selected_index]
|
||||
cf.selected_wallpaper = wallpaper_path
|
||||
print(MSG_PATH, cf.selected_wallpaper)
|
||||
cf.fill_option = self.fill_option_combo.get_active_text() or cf.fill_option
|
||||
change_wallpaper(cf.selected_wallpaper, cf.fill_option, cf.color, cf.backend, cf.selected_monitor)
|
||||
cf.save()
|
||||
self.cf.selected_wallpaper = wallpaper_path
|
||||
print(_("Selected image path: {image}").format(image=self.cf.selected_wallpaper))
|
||||
self.cf.fill_option = self.fill_option_combo.get_active_text() or self.cf.fill_option
|
||||
change_wallpaper(self.cf.selected_wallpaper, self.cf.fill_option,
|
||||
self.cf.color, self.cf.backend, self.cf.selected_monitor)
|
||||
self.cf.save()
|
||||
|
||||
# Prevent other default key handling:
|
||||
if event.keyval in [Gdk.KEY_Up, Gdk.KEY_Down, Gdk.KEY_Left, Gdk.KEY_Right, Gdk.KEY_Return, Gdk.KEY_KP_Enter]:
|
||||
|
@ -5,20 +5,6 @@ import argparse
|
||||
from waypaper.options import FILL_OPTIONS, BACKEND_OPTIONS
|
||||
from waypaper.config import cf
|
||||
|
||||
if cf.lang == "de":
|
||||
from waypaper.translation_de import *
|
||||
elif cf.lang == "fr":
|
||||
from waypaper.translation_fr import *
|
||||
elif cf.lang == "ru":
|
||||
from waypaper.translation_ru import *
|
||||
elif cf.lang == "pl":
|
||||
from waypaper.translation_pl import *
|
||||
elif cf.lang == "zh":
|
||||
from waypaper.translation_zh import *
|
||||
else:
|
||||
from waypaper.translation_en import *
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser(prog = "waypaper", description = MSG_DESC, epilog = MSG_INFO)
|
||||
parser.add_argument("-v", "--version", help=MSG_ARG_HELP, action="store_true")
|
||||
parser.add_argument("--restore", help=MSG_ARG_REST, action="store_true")
|
||||
|
@ -2,99 +2,91 @@
|
||||
|
||||
import subprocess
|
||||
import time
|
||||
from gettext import gettext as _
|
||||
|
||||
from waypaper.config import cf
|
||||
|
||||
if cf.lang == "de":
|
||||
from waypaper.translation_de import *
|
||||
elif cf.lang == "fr":
|
||||
from waypaper.translation_fr import *
|
||||
elif cf.lang == "ru":
|
||||
from waypaper.translation_ru import *
|
||||
elif cf.lang == "pl":
|
||||
from waypaper.translation_pl import *
|
||||
elif cf.lang == "zh":
|
||||
from waypaper.translation_zh import *
|
||||
else:
|
||||
from waypaper.translation_en import *
|
||||
|
||||
from waypaper.config import Config
|
||||
from waypaper.options import BACKEND_OPTIONS
|
||||
|
||||
def change_wallpaper(image_path, fill_option, color, backend, monitor):
|
||||
"""Run a system command to change the wallpaper depending on the backend"""
|
||||
|
||||
cf = Config()
|
||||
try:
|
||||
# swaybg backend:
|
||||
if backend == "swaybg":
|
||||
fill = fill_option.lower()
|
||||
try:
|
||||
subprocess.Popen(["killall", "swaybg"])
|
||||
time.sleep(0.005)
|
||||
except Exception as e:
|
||||
print(f"{ERR_KILL} {e}")
|
||||
command = ["swaybg"]
|
||||
# if monitor != "All":
|
||||
# command.extend(["-o", monitor])
|
||||
command.extend(["-i", image_path])
|
||||
command.extend(["-m", fill, "-c", color])
|
||||
subprocess.Popen(command)
|
||||
print(f"{MSG_SETWITH} {backend}")
|
||||
if backend in BACKEND_OPTIONS:
|
||||
if backend == "swaybg":
|
||||
fill = fill_option.lower()
|
||||
try:
|
||||
subprocess.Popen(["killall", "swaybg"])
|
||||
time.sleep(0.005)
|
||||
except Exception as e:
|
||||
print(_("Warning related to killall: {error}".format(
|
||||
error=e)))
|
||||
command = ["swaybg"]
|
||||
# if monitor != "All":
|
||||
# command.extend(["-o", monitor])
|
||||
command.extend(["-i", image_path])
|
||||
command.extend(["-m", fill, "-c", color])
|
||||
subprocess.Popen(command)
|
||||
|
||||
# swww backend:
|
||||
elif backend == "swww":
|
||||
fill_types = {
|
||||
# swww backend:
|
||||
elif backend == "swww":
|
||||
fill_types = {
|
||||
"fill": "crop",
|
||||
"fit": "fit",
|
||||
"center": "no",
|
||||
"stretch": "crop",
|
||||
"tile": "no",
|
||||
}
|
||||
fill = fill_types[fill_option.lower()]
|
||||
try:
|
||||
subprocess.Popen(["killall", "swaybg"])
|
||||
time.sleep(0.005)
|
||||
except Exception as e:
|
||||
print(f"{ERR_KILL} {e}")
|
||||
subprocess.Popen(["swww", "init"])
|
||||
command = ["swww", "img", image_path]
|
||||
command.extend(["--resize", fill])
|
||||
command.extend(["--fill-color", color])
|
||||
command.extend(["--transition-step", str(10)])
|
||||
if monitor != "All":
|
||||
command.extend(["--outputs", monitor])
|
||||
subprocess.Popen(command)
|
||||
print(f"{MSG_SETWITH} {backend}")
|
||||
}
|
||||
fill = fill_types[fill_option.lower()]
|
||||
try:
|
||||
subprocess.Popen(["killall", "swaybg"])
|
||||
time.sleep(0.005)
|
||||
except Exception as e:
|
||||
print(_("Warning related to killall: {error}".format(
|
||||
error=e)))
|
||||
subprocess.Popen(["swww", "init"])
|
||||
command = ["swww", "img", image_path]
|
||||
command.extend(["--resize", fill])
|
||||
command.extend(["--fill-color", color])
|
||||
command.extend(["--transition-step", str(10)])
|
||||
if monitor != "All":
|
||||
command.extend(["--outputs", monitor])
|
||||
subprocess.Popen(command)
|
||||
|
||||
# feh backend:
|
||||
elif backend == "feh":
|
||||
fill_types = {
|
||||
# feh backend:
|
||||
elif backend == "feh":
|
||||
fill_types = {
|
||||
"fill": "--bg-fill",
|
||||
"fit": "--bg-max",
|
||||
"center": "--bg-center",
|
||||
"stretch": "--bg-scale",
|
||||
"tile": "--bg-tile",
|
||||
}
|
||||
fill = fill_types[fill_option.lower()]
|
||||
command = ["feh", fill, "--image-bg", color]
|
||||
command.extend([image_path])
|
||||
subprocess.Popen(command)
|
||||
print(f"{MSG_SETWITH} {backend}")
|
||||
}
|
||||
fill = fill_types[fill_option.lower()]
|
||||
command = ["feh", fill, "--image-bg", color]
|
||||
command.extend([image_path])
|
||||
subprocess.Popen(command)
|
||||
|
||||
# wallutils backend:
|
||||
elif backend == "wallutils":
|
||||
fill_types = {
|
||||
# wallutils backend:
|
||||
elif backend == "wallutils":
|
||||
fill_types = {
|
||||
"fill": "scale",
|
||||
"fit": "scale",
|
||||
"center": "center",
|
||||
"stretch": "stretch",
|
||||
"tile": "tile",
|
||||
}
|
||||
fill = fill_types[fill_option.lower()]
|
||||
}
|
||||
fill = fill_types[fill_option.lower()]
|
||||
|
||||
subprocess.Popen(["setwallpaper", "--mode", fill, image_path])
|
||||
print(f"{MSG_SETWITH} {backend}")
|
||||
subprocess.Popen(["setwallpaper", "--mode", fill, image_path])
|
||||
|
||||
print(_("Sent command to set wallpaper was set with {backend}").format(
|
||||
backend=backend))
|
||||
|
||||
else:
|
||||
print(f"{ERR_NOTSUP} {backend}")
|
||||
print(_("The backend is not supported: {backend}").format(
|
||||
backend=backend))
|
||||
|
||||
except Exception as e:
|
||||
print(f"{ERR_WALL} {e}")
|
||||
print(_("Error changing wallpaper: {error}".format(error=e)))
|
||||
|
@ -18,7 +18,7 @@ def get_image_paths(root_folder, include_subfolders=False, depth=None):
|
||||
if not include_subfolders and root != root_folder:
|
||||
continue
|
||||
if depth is not None and root != root_folder:
|
||||
current_depth = root.count(os.path.sep) - root_folder.count(os.path.sep)
|
||||
current_depth = root.count(os.path.sep) - str(root_folder).count(os.path.sep)
|
||||
if current_depth > depth:
|
||||
continue
|
||||
for filename in files:
|
||||
|
@ -3,16 +3,16 @@
|
||||
import configparser
|
||||
import pathlib
|
||||
import os
|
||||
from sys import exit
|
||||
from platformdirs import user_config_path, user_pictures_path, user_cache_path
|
||||
|
||||
from waypaper.aboutdata import AboutData
|
||||
from waypaper.options import FILL_OPTIONS, SORT_OPTIONS
|
||||
|
||||
|
||||
class Config:
|
||||
"""User configuration loaded from the config.ini file"""
|
||||
def __init__(self):
|
||||
self.image_folder = str(pathlib.Path.home())
|
||||
if os.path.exists(str(pathlib.Path.home()) + "/Pictures"):
|
||||
self.image_folder = str(pathlib.Path.home()) + "/Pictures"
|
||||
self.image_folder = user_pictures_path()
|
||||
self.selected_wallpaper = None
|
||||
self.selected_monitor = "All"
|
||||
self.fill_option = "fill"
|
||||
@ -21,11 +21,21 @@ class Config:
|
||||
self.color = "#ffffff"
|
||||
self.lang = "en"
|
||||
self.monitors = [self.selected_monitor]
|
||||
self.wallpaper = []
|
||||
self.wallpaper = str()
|
||||
self.include_subfolders = False
|
||||
self.config_folder = str(pathlib.Path.home()) + "/.config/waypaper"
|
||||
self.config_file = self.config_folder + "/config.ini"
|
||||
self.aboutData = AboutData()
|
||||
self.cachePath = user_cache_path(self.aboutData.applicationName())
|
||||
self.configPath = user_config_path(self.aboutData.applicationName())
|
||||
self.config_file = self.configPath / "config.ini"
|
||||
|
||||
# Create all directories we use here
|
||||
# Create config folder:
|
||||
self.configPath.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Create cache folder:
|
||||
self.cachePath.mkdir(parents=True,exist_ok=True)
|
||||
|
||||
self.read()
|
||||
|
||||
def create(self):
|
||||
"""Create a default config.ini file if it does not exist"""
|
||||
@ -41,38 +51,33 @@ class Config:
|
||||
"wallpaper": str(self.selected_wallpaper),
|
||||
"monitors": str(self.selected_monitor),
|
||||
}
|
||||
with open(cf.config_file, "w") as configfile:
|
||||
with open(self.config_file, "w") as configfile:
|
||||
config.write(configfile)
|
||||
|
||||
|
||||
def read(self):
|
||||
"""Load data from the config.ini or use default if it does not exists"""
|
||||
try:
|
||||
config = configparser.ConfigParser()
|
||||
config.read(self.config_file, 'utf-8')
|
||||
self.image_folder = config.get("Settings", "folder", fallback=self.image_folder)
|
||||
self.fill_option = config.get("Settings", "fill", fallback=self.fill_option)
|
||||
if self.fill_option not in FILL_OPTIONS:
|
||||
self.sort_option = FILL_OPTIONS[0]
|
||||
self.sort_option = config.get("Settings", "sort", fallback=self.sort_option)
|
||||
if self.sort_option not in SORT_OPTIONS:
|
||||
self.sort_option = SORT_OPTIONS[0]
|
||||
self.backend = config.get("Settings", "backend", fallback=self.backend)
|
||||
self.color = config.get("Settings", "color", fallback=self.color)
|
||||
self.lang = config.get("Settings", "language", fallback=self.lang)
|
||||
self.include_subfolders = config.getboolean("Settings", "subfolders", fallback=self.include_subfolders)
|
||||
config = configparser.ConfigParser()
|
||||
config.read(self.config_file, 'utf-8')
|
||||
self.image_folder = config.get("Settings", "folder", fallback=self.image_folder)
|
||||
self.fill_option = config.get("Settings", "fill", fallback=self.fill_option)
|
||||
if self.fill_option not in FILL_OPTIONS:
|
||||
self.sort_option = FILL_OPTIONS[0]
|
||||
self.sort_option = config.get("Settings", "sort", fallback=self.sort_option)
|
||||
if self.sort_option not in SORT_OPTIONS:
|
||||
self.sort_option = SORT_OPTIONS[0]
|
||||
self.backend = config.get("Settings", "backend", fallback=self.backend)
|
||||
self.color = config.get("Settings", "color", fallback=self.color)
|
||||
self.lang = config.get("Settings", "language", fallback=self.lang)
|
||||
self.include_subfolders = config.getboolean("Settings", "subfolders", fallback=self.include_subfolders)
|
||||
|
||||
self.monitors_str = config.get("Settings", "monitors", fallback=self.selected_monitor, raw=True)
|
||||
if self.monitors_str is not None:
|
||||
self.monitors = [str(monitor) for monitor in self.monitors_str.split(",")]
|
||||
|
||||
self.wallpaper_str = config.get("Settings", "wallpaper", fallback=self.wallpaper, raw=True)
|
||||
if self.wallpaper_str is not None:
|
||||
self.wallpaper = [str(paper) for paper in self.wallpaper_str.split(",")]
|
||||
except Exception as e:
|
||||
print(e)
|
||||
exit()
|
||||
self.monitors_str = config.get("Settings", "monitors", fallback=self.selected_monitor, raw=True)
|
||||
if self.monitors_str is not None:
|
||||
self.monitors = [str(monitor) for monitor in self.monitors_str.split(",")]
|
||||
|
||||
self.wallpaper_str = config.get("Settings", "wallpaper", fallback=self.wallpaper, raw=True)
|
||||
if self.wallpaper_str is not None:
|
||||
self.wallpaper = [str(paper) for paper in self.wallpaper_str.split(",")]
|
||||
|
||||
def save(self):
|
||||
"""Update the parameters and save them to the configuration file"""
|
||||
@ -91,16 +96,18 @@ class Config:
|
||||
# Write configuration to the file:
|
||||
config = configparser.ConfigParser()
|
||||
config.read(self.config_file)
|
||||
config.set("Settings", "folder", cf.image_folder)
|
||||
config.set("Settings", "fill", cf.fill_option)
|
||||
config.set("Settings", "sort", cf.sort_option)
|
||||
config.set("Settings", "backend", cf.backend)
|
||||
config.set("Settings", "color", cf.color)
|
||||
config.set("Settings", "language", cf.lang)
|
||||
config.set("Settings", "subfolders", str(cf.include_subfolders))
|
||||
if not config.has_section("Settings"):
|
||||
config.add_section("Settings")
|
||||
config.set("Settings", "folder", self.image_folder)
|
||||
config.set("Settings", "fill", self.fill_option)
|
||||
config.set("Settings", "sort", self.sort_option)
|
||||
config.set("Settings", "backend", self.backend)
|
||||
config.set("Settings", "color", self.color)
|
||||
config.set("Settings", "language", self.lang)
|
||||
config.set("Settings", "subfolders", str(self.include_subfolders))
|
||||
config.set("Settings", "wallpaper", ",".join(self.wallpaper))
|
||||
config.set("Settings", "monitors", ",".join(self.monitors))
|
||||
with open(cf.config_file, "w") as configfile:
|
||||
with open(self.config_file, "w") as configfile:
|
||||
config.write(configfile)
|
||||
|
||||
|
||||
@ -111,20 +118,3 @@ class Config:
|
||||
if args.fill:
|
||||
self.fill_option = args.fill
|
||||
|
||||
|
||||
cf = Config()
|
||||
|
||||
# Create config folder:
|
||||
if not os.path.exists(cf.config_folder):
|
||||
os.makedirs(cf.config_folder)
|
||||
|
||||
# Create cache folder:
|
||||
if not os.path.exists(f"{cf.config_folder}/.cache"):
|
||||
os.makedirs(f"{cf.config_folder}/.cache")
|
||||
|
||||
# Create config file:
|
||||
if not os.path.exists(cf.config_file):
|
||||
cf.create()
|
||||
|
||||
# Read config file:
|
||||
cf.read()
|
||||
|
@ -1,47 +0,0 @@
|
||||
"""German translations of the program interface (deutsche übersetzungen der Benutzeroberfläche)"""
|
||||
|
||||
MSG_DESC = "Grafisches Hintergrundbild-Auswahlwerkzeug für Wayland und X11. Es dient als Frontend für feh, swaybg, wallutils und swww."
|
||||
MSG_INFO = "Weitere Informationen finden Sie unter:\nhttps://github.com/anufrievroman/waypaper"
|
||||
|
||||
MSG_ARG_HELP = "gibt die Programmversion aus"
|
||||
MSG_ARG_FILL = "legt fest, wie das Bild skaliert werden soll, um den gesamten Bildschirm auszufüllen"
|
||||
MSG_ARG_REST = "stellt das zuletzt verwendete Hintergrundbild wieder her"
|
||||
MSG_ARG_BACK = "legt das Backend fest, welches zum Setzen des Hintergrundbildes verwendet werden soll"
|
||||
MSG_ARG_RAND = "wählt ein zufälliges Hintergrundbild aus"
|
||||
|
||||
MSG_PATH = "Pfad zum ausgewählten Bild:"
|
||||
MSG_SELECT = "Auswählen"
|
||||
MSG_REFRESH = "Aktualisieren"
|
||||
MSG_RANDOM = "Zufällig"
|
||||
MSG_EXIT = "Beenden"
|
||||
MSG_SUBFOLDERS = "Unterordner"
|
||||
MSG_CHANGEFOLDER = "Hintergrundbild-Ordner ändern"
|
||||
MSG_CHOOSEFOLDER = "Bitte wählen Sie einen Ordner aus"
|
||||
MSG_CACHING = "Hintergrundbilder werden zwischengespeichert..."
|
||||
MSG_SETWITH = "Hintergrundbild wurde mit folgendem Befehl gesetzt"
|
||||
|
||||
MSG_HELP = "Waypapers Tastenkürzel:\n\nhjkl - Navigation (←↓↑→)\nf - Hintergrundbild-Ordner ändern\n"
|
||||
MSG_HELP += "g - Zum Anfang scrollen\nG - Zum Ende scrollen\nR - Zufälliges Hintergrundbild\nr - Hintergrundbilder zwischenspeichern\n"
|
||||
MSG_HELP += "s - Unterordner mit einbeziehen\n? - Hilfe\nq - Beenden\n\n"
|
||||
MSG_HELP += MSG_INFO
|
||||
|
||||
ERR_CACHE = "Fehler beim Löschen des Zwischenspeichers"
|
||||
ERR_BACKEND = "Es konnte kein Hintergrundbild-Backend gefunden werden.\n"
|
||||
ERR_BACKEND += "Installieren Sie mindestens eines der folgenden Backends:\n\n"
|
||||
ERR_BACKEND += "- swaybg (für Wayland)\n- swww (für Wayland)\n"
|
||||
ERR_BACKEND += "- feh (für Xorg)\n- wallutils (für Xorg & Wayland)\n\n"
|
||||
ERR_BACKEND += MSG_INFO
|
||||
ERR_WALL = "Fehler beim Ändern des Hintergrundbildes:"
|
||||
ERR_NOTSUP = "Das folgende Backend wird nicht unterstützt:"
|
||||
ERR_DISP = "Fehler beim Ermitteln der Monitor-Namen:"
|
||||
ERR_KILL = "Warnung im Zusammenhang mit dem Befehl killall:"
|
||||
|
||||
TIP_SUBFOLDER = "Wählen, ob Unterordner mit einbezogen werden sollen"
|
||||
TIP_REFRESH = "Erneutes einlesen des Hintergrundbild-Ordners"
|
||||
TIP_FILL = "Skalierungsart auswählen"
|
||||
TIP_BACKEND = "Backend auswählen"
|
||||
TIP_SORTING = "Sortierungsart auswählen"
|
||||
TIP_DISPLAY = "Bildschirm auswählen"
|
||||
TIP_COLOR = "Hintergrundfarbe auswählen"
|
||||
TIP_RANDOM = "Ein zufälliges Hintergrundbild auswählen"
|
||||
TIP_EXIT = "Das Programm beenden"
|
@ -1,47 +0,0 @@
|
||||
"""Traductions en français de l'interface du programme"""
|
||||
|
||||
MSG_DESC = "Sélecteur de papier peint graphique pour Wayland et X11. Il fonctionne comme une interface pour feh, swaybg, wallutils et swww."
|
||||
MSG_INFO = "Pour plus d'informations, visitez :\nhttps://github.com/anufrievroman/waypaper"
|
||||
|
||||
MSG_ARG_HELP = "afficher la version du programme"
|
||||
MSG_ARG_FILL = "spécifier comment remplir l'écran avec l'image choisie"
|
||||
MSG_ARG_REST = "restaurer le dernier papier peint"
|
||||
MSG_ARG_BACK = "spécifier quel backend utiliser pour définir le papier peint"
|
||||
MSG_ARG_RAND = "définir un papier peint aléatoire"
|
||||
|
||||
MSG_PATH = "Chemin de l'image sélectionnée :"
|
||||
MSG_SELECT = "Sélectionner"
|
||||
MSG_REFRESH = "Actualiser"
|
||||
MSG_RANDOM = "Aléatoire"
|
||||
MSG_EXIT = "Quitter"
|
||||
MSG_SUBFOLDERS = "Sous-dossiers"
|
||||
MSG_CHANGEFOLDER = "Changer de dossier de papier peint"
|
||||
MSG_CHOOSEFOLDER = "Veuillez choisir un dossier"
|
||||
MSG_CACHING = "Mise en cache des papiers peints..."
|
||||
MSG_SETWITH = "La commande envoyée pour définir le papier peint a été définie avec"
|
||||
|
||||
MSG_HELP = "Raccourcis clavier de Waypaper :\n\nhjkl - Navigation (←↓↑→)\nf - Changer de dossier de papier peint\n"
|
||||
MSG_HELP += "g - Faire défiler vers le haut\nG - Faire défiler vers le bas\nR - Définir un papier peint aléatoire\nr - Recréer le cache des papiers peints\n"
|
||||
MSG_HELP += "s - Inclure/exclure les images des sous-dossiers\n? - Aide\nq - Quitter\n\n"
|
||||
MSG_HELP += MSG_INFO
|
||||
|
||||
ERR_CACHE = "Erreur lors de la suppression du cache"
|
||||
ERR_BACKEND = "Il semble qu'aucun des backends de papier peint ne soit installé sur le système.\n"
|
||||
ERR_BACKEND += "Utilisez votre gestionnaire de paquets pour installer au moins l'un de ces backends :\n\n"
|
||||
ERR_BACKEND += "- swaybg (pour Wayland)\n- swww (pour Wayland)\n"
|
||||
ERR_BACKEND += "- feh (pour Xorg)\n- wallutils (pour Xorg & Wayland)\n\n"
|
||||
ERR_BACKEND += MSG_INFO
|
||||
ERR_WALL = "Erreur lors du changement de papier peint :"
|
||||
ERR_NOTSUP = "Le backend n'est pas pris en charge :"
|
||||
ERR_DISP = "Erreur lors de la détermination des noms des moniteurs :"
|
||||
ERR_KILL = "Avertissement lié à killall :"
|
||||
|
||||
TIP_SUBFOLDER = "Inclure/exclure les images des sous-dossiers"
|
||||
TIP_REFRESH = "Recréer le dossier d'images"
|
||||
TIP_FILL = "Choisir le type de remplissage"
|
||||
TIP_BACKEND = "Choisir le backend"
|
||||
TIP_SORTING = "Choisir le type de tri"
|
||||
TIP_DISPLAY = "Choisir l'affichage"
|
||||
TIP_COLOR = "Choisir la couleur de fond"
|
||||
TIP_RANDOM = "Définir un papier peint aléatoire"
|
||||
TIP_EXIT = "Quitter l'application"
|
Loading…
Reference in New Issue
Block a user