diff --git a/.gitignore b/.gitignore index 36b13f1..b7faf40 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ -# ---> Python # Byte-compiled / optimized / DLL files __pycache__/ -*.py[cod] +*.py[codz] *$py.class # C extensions @@ -47,7 +46,7 @@ htmlcov/ nosetests.xml coverage.xml *.cover -*.py,cover +*.py.cover .hypothesis/ .pytest_cache/ cover/ @@ -107,17 +106,24 @@ ipython_config.py # commonly ignored for libraries. # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control #poetry.lock +#poetry.toml # pdm # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python. +# https://pdm-project.org/en/latest/usage/project/#working-with-version-control #pdm.lock -# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it -# in version control. -# https://pdm.fming.dev/latest/usage/project/#working-with-version-control -.pdm.toml +#pdm.toml .pdm-python .pdm-build/ +# pixi +# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control. +#pixi.lock +# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one +# in the .venv directory. It is recommended not to include this directory in version control. +.pixi + # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm __pypackages__/ @@ -130,6 +136,7 @@ celerybeat.pid # Environments .env +.envrc .venv env/ venv/ @@ -168,9 +175,33 @@ cython_debug/ # option (not recommended) you can uncomment the following to ignore the entire idea folder. #.idea/ +# Abstra +# Abstra is an AI-powered process automation framework. +# Ignore directories containing user credentials, local state, and settings. +# Learn more at https://abstra.io/docs +.abstra/ + +# Visual Studio Code +# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore +# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore +# and can be added to the global gitignore or merged into this file. However, if you prefer, +# you could uncomment the following to ignore the entire vscode folder +# .vscode/ + # Ruff stuff: .ruff_cache/ # PyPI configuration file .pypirc +# Cursor +# Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to +# exclude from AI features like autocomplete and code analysis. Recommended for sensitive data +# refer to https://docs.cursor.com/context/ignore-files +.cursorignore +.cursorindexingignore + +# Marimo +marimo/_static/ +marimo/_lsp/ +__marimo__/ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ae1a066 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 s13bby + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index b1e479e..0f9569a 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,253 @@ -# wallpaper_demon +# 🖼️ Wallpaper Daemon -Служба для автоматической смены обоев рабочего стола в зависимости от времени суток. \ No newline at end of file +Служба для автоматической смены обоев рабочего стола в зависимости от времени суток. + +## 📋 Возможности + +- 🌅 **Автоматическая смена обоев** — установка разных обоев для разных периодов дня +- 🎨 **Смена темы GNOME** — автоматическое переключение светлой/тёмной темы +- ⏰ **Гибкое расписание** — настройка времени смены обоев через JSON +- 🔧 **Systemd-служба** — интеграция с systemd для автоматического запуска +- 📝 **Логирование** — запись всех событий в лог + +## 🚀 Требования + +- Python 3.13+ +- Linux с GNOME и systemd +- Установленные пакеты: + +```bash +sudo apt install python3-pip python3-venv rsync +``` + +- Библиотеки Python (стандартные, установка не требуется): + +``` +subprocess, os, json, sys, signal, logging, datetime +``` + +## 📖 Использование + +### Быстрый старт + +**Однократная установка обоев:** + +```bash +python wallpaper_handle.py +``` + +**Запуск демона (вручную):** + +```bash +python wallpaper_daemon.py +``` + +### Управление через systemd + +| Действие | Команда | +|----------|---------| +| Установка службы | `sudo ./install_service.sh` | +| Включение службы | `systemctl --user enable wallpaper-daemon.service` | +| Запуск службы | `systemctl --user start wallpaper-daemon.service` | +| Остановка службы | `systemctl --user stop wallpaper-daemon.service` | +| Проверка статуса | `systemctl --user status wallpaper-daemon.service` | +| Удаление службы | `sudo ./uninstall_service.sh` | + +## ⏰ Расписание смены обоев + +| Время суток | Период | Обои | Тема | +|-------------|--------|------|------| +| 🌙 Ночь | 00:00 - 07:59 | `night.jpg` | 🌑 Тёмная | +| 🌅 Утро | 08:00 - 11:59 | `morning.jpg` | ☀️ Светлая | +| ☀️ День | 12:00 - 15:59 | `day.jpg` | ☀️ Светлая | +| 🌆 Вечер | 16:00 - 19:59 | `evening.jpg` | ☀️ Светлая | +| 🌃 Перед ночью | 20:00 - 23:59 | `before_night.jpg` | 🌑 Тёмная | + +## ⚙️ Настройки + +Файл `settings.json` в корне проекта: + +```json +{ + "night": { + "time": ["0:0", "7:59"], + "theme": "dark", + "file": "night.jpg" + }, + "morning": { + "time": ["8:0", "11:59"], + "theme": "light", + "file": "morning.jpg" + }, + "day": { + "time": ["12:0", "15:59"], + "theme": "light", + "file": "day.jpg" + }, + "evening": { + "time": ["16:0", "19:59"], + "theme": "light", + "file": "evening.jpg" + }, + "before_night": { + "time": ["20:0", "23:59"], + "theme": "dark", + "file": "before_night.jpg" + } +} +``` + +### Параметры + +| Параметр | Описание | +|----------|----------| +| `time` | Период времени в формате `["часы:минуты", "часы:минуты"]` | +| `theme` | Тема GNOME: `light` или `dark` | +| `file` | Имя файла обоев в папке `wallpapers/` | + +## 📂 Структура проекта + +``` +wallpaper-daemon/ +├── wallpaper_daemon.py # Основной демон (фоновый режим) +├── wallpaper_handle.py # Однократная установка обоев +├── settings.json # Конфигурация расписания +├── install_service.sh # Скрипт установки systemd-службы +├── uninstall_service.sh # Скрипт удаления systemd-службы +├── wallpaper-daemon.service # Unit-файл systemd +├── README.md +├── LICENSE +├── .gitignore +└── wallpapers/ + ├── morning.jpg # Утренние обои + ├── day.jpg # Дневные обои + ├── evening.jpg # Вечерние обои + ├── before_night.jpg # Обои перед ночью + └── night.jpg # Ночные обои +``` + +## 🔧 Установка службы + +### Автоматическая установка + +```bash +sudo ./install_service.sh +``` + +Скрипт: +1. Копирует файлы в `~/.local/share/wallpaper-daemon` +2. Устанавливает службу в `/etc/systemd/user` +3. Включает linger для пользователя + +> **Примечание:** После установки службы нужно включить и запустить её от имени пользователя: +> ```bash +> systemctl --user enable wallpaper-daemon.service +> systemctl --user start wallpaper-daemon.service +> ``` + +### Переустановка + +Если служба была установлена неправильно (например, в `/root/.local/...`): + +```bash +# Удалить старую службу +sudo ./uninstall_service.sh + +# Установить заново +sudo ./install_service.sh + +# Включить и запустить +systemctl --user enable wallpaper-daemon.service +systemctl --user start wallpaper-daemon.service +``` + +### Ручная установка + +```bash +# Создать директорию +mkdir -p ~/.local/share/wallpaper-daemon + +# Скопировать файлы (без скриптов установки) +rsync -av --exclude='install_service.sh' --exclude='uninstall_service.sh' ./ ~/.local/share/wallpaper-daemon/ + +# Скопировать unit-файл +sudo cp wallpaper-daemon.service /etc/systemd/user/ + +# Перезагрузить демон +sudo systemctl daemon-reload + +# Включить linger +loginctl enable-linger $USER + +# Включить и запустить службу +systemctl --user enable wallpaper-daemon.service +systemctl --user start wallpaper-daemon.service +``` + +## 🛠️ Устранение неполадок + +### Служба не запускается + +**Проверьте статус:** + +```bash +systemctl --user status wallpaper-daemon.service +``` + +**Посмотрите детальные логи:** + +```bash +journalctl --user -u wallpaper-daemon.service -n 100 --no-pager +``` + +**Просмотр логов в реальном времени:** + +```bash +journalctl --user -u wallpaper-daemon.service -f +``` + +### Обои не меняются + +1. **Проверьте наличие файлов:** + +```bash +ls -la ~/.local/share/wallpaper-daemon/wallpapers/ +``` + +2. **Убедитесь, что GNOME активен:** + +```bash +gsettings get org.gnome.desktop.background picture-uri +``` + +3. **Проверьте переменные окружения:** + +```bash +echo $DISPLAY +echo $DBUS_SESSION_BUS_ADDRESS +``` + +### Ошибки в логах + +| Ошибка | Решение | +|--------|---------| +| `Файл не найден` | Проверьте наличие обоев в папке `wallpapers/` | +| `gsettings: не удалось открыть` | Убедитесь, что GNOME запущен | +| `Permission denied` | Проверьте права доступа к файлам | + +## 🎨 Добавление своих обоев + +1. Поместите изображения в папку `wallpapers/` +2. Отредактируйте `settings.json`: + - Измените `file` на имя вашего файла + - Настройте `time` для нужного периода + - Выберите `theme` (`light` или `dark`) +3. Перезапустите службу: + +```bash +systemctl --user restart wallpaper-daemon.service +``` + +--- + +**сделано: s13bby** diff --git a/install_service.sh b/install_service.sh new file mode 100755 index 0000000..8fbf4d0 --- /dev/null +++ b/install_service.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SERVICE_NAME="wallpaper-daemon" +SERVICE_FILE="$SCRIPT_DIR/wallpaper-daemon.service" +SYSTEM_SERVICE_DIR="/etc/systemd/user" + +# Используем домашнюю директорию реального пользователя, а не root +if [ "$EUID" -eq 0 ]; then + REAL_USER="${SUDO_USER:-$(logname)}" + INSTALL_DIR="/home/$REAL_USER/.local/share/wallpaper-daemon" +else + INSTALL_DIR="$HOME/.local/share/wallpaper-daemon" +fi + +echo "Установка файлов в $INSTALL_DIR..." +mkdir -p "$INSTALL_DIR" + +rsync -av --exclude='install_service.sh' --exclude='uninstall_service.sh' \ + "$SCRIPT_DIR/" "$INSTALL_DIR/" 2>/dev/null || cp -r "$SCRIPT_DIR"/* "$INSTALL_DIR/" + +if [ "$EUID" -ne 0 ]; then + echo "Для установки сервиса требуются права root. Запустите с sudo:" + echo " sudo $0" + exit 1 +fi + +mkdir -p "$SYSTEM_SERVICE_DIR" + +cp "$SERVICE_FILE" "$SYSTEM_SERVICE_DIR/$SERVICE_NAME.service" + +systemctl daemon-reload + +loginctl enable-linger "$REAL_USER" + +# Устанавливаем владельца файлов +chown -R "$REAL_USER:$REAL_USER" "$INSTALL_DIR" + +echo "Сервис установлен в $SYSTEM_SERVICE_DIR" +echo "Файлы скопированы в $INSTALL_DIR" +echo "" +echo "Для запуска выполните:" +echo " systemctl --user enable $SERVICE_NAME.service" +echo " systemctl --user start $SERVICE_NAME.service" +echo "" +echo "Проверить статус:" +echo " systemctl --user status $SERVICE_NAME.service" +echo " journalctl --user -u $SERVICE_NAME.service -f" diff --git a/settings.json b/settings.json new file mode 100644 index 0000000..5017358 --- /dev/null +++ b/settings.json @@ -0,0 +1,32 @@ +{ + "night": + { + "time":["0:0", "7:59"], + "theme": "dark", + "file": "night.jpg" + }, + "morning": + { + "time":["8:0", "11:59"], + "theme": "light", + "file": "morning.jpg" + }, + "day": + { + "time": ["12:0", "15:59"], + "theme": "light", + "file": "day.jpg" + }, + "evening": + { + "time": ["16:0", "19:59"], + "theme": "light", + "file": "evening.jpg" + }, + "before_night": + { + "time": ["20:0", "23:59"], + "theme": "dark", + "file": "before_night.jpg" + } +} \ No newline at end of file diff --git a/uninstall_service.sh b/uninstall_service.sh new file mode 100755 index 0000000..ab2421c --- /dev/null +++ b/uninstall_service.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +set -e + +SERVICE_NAME="wallpaper-daemon" +SYSTEM_SERVICE_DIR="/etc/systemd/user" + +# Используем домашнюю директорию реального пользователя, а не root +if [ "$EUID" -eq 0 ]; then + REAL_USER="${SUDO_USER:-$(logname)}" + INSTALL_DIR="/home/$REAL_USER/.local/share/wallpaper-daemon" +else + INSTALL_DIR="$HOME/.local/share/wallpaper-daemon" +fi + +if [ "$EUID" -ne 0 ]; then + echo "Для удаления сервиса требуются права root. Запустите с sudo:" + echo " sudo $0" + exit 1 +fi + +echo "Остановка сервисов у активных пользователей..." +for uid in $(loginctl list-users --no-legend | awk '{print $1}'); do + user=$(id -un "$uid" 2>/dev/null) + if [ -n "$user" ]; then + echo " - $user" + runuser -u "$user" -- systemctl --user stop "$SERVICE_NAME.service" 2>/dev/null || true + runuser -u "$user" -- systemctl --user disable "$SERVICE_NAME.service" 2>/dev/null || true + fi +done + +for uid in $(loginctl list-users --no-legend | awk '{print $1}'); do + user=$(id -un "$uid" 2>/dev/null) + if [ -n "$user" ]; then + loginctl disable-linger "$user" 2>/dev/null || true + fi +done + +rm -f "$SYSTEM_SERVICE_DIR/$SERVICE_NAME.service" + +systemctl daemon-reload + +echo "Удаление файлов из $INSTALL_DIR..." +rm -rf "$INSTALL_DIR" + +echo "Сервис удален" diff --git a/wallpaper-daemon.service b/wallpaper-daemon.service new file mode 100644 index 0000000..c513df3 --- /dev/null +++ b/wallpaper-daemon.service @@ -0,0 +1,22 @@ +[Unit] +Description=Wallpaper Auto-Switcher Daemon +After=graphical-session.target +PartOf=graphical-session.target +Wants=sleep.target suspend.target hibernate.target hybrid-sleep.target + +[Service] +Type=simple +WorkingDirectory=%h/.local/share/wallpaper-daemon +ExecStart=%h/.local/share/wallpaper-daemon/venv/bin/python %h/.local/share/wallpaper-daemon/wallpaper_daemon.py +Restart=on-failure +RestartSec=5 + +Environment=DISPLAY=:0 +Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/%U/bus + +IOSchedulingClass=idle +CPUSchedulingPolicy=idle +Nice=19 + +[Install] +WantedBy=graphical-session.target diff --git a/wallpaper_daemon.py b/wallpaper_daemon.py new file mode 100755 index 0000000..084bba5 --- /dev/null +++ b/wallpaper_daemon.py @@ -0,0 +1,177 @@ +#!/usr/bin/env python3 + +from datetime import datetime, timedelta +import subprocess +import os +import json +import sys +import signal +import logging + +logging.basicConfig( + level=logging.INFO, + format='%(asctime)s - %(levelname)s - %(message)s', + handlers=[logging.StreamHandler()] +) +logger = logging.getLogger(__name__) + +RUNNING = True + +def signal_handler(signum, frame): + global RUNNING + RUNNING = False + logger.info("Получен сигнал остановки, завершаю работу...") + +def get_base_dir(): + return os.path.dirname(os.path.abspath(__file__)) + +def get_settings(): + path = os.path.join(get_base_dir(), "settings.json") + try: + with open(path, "r", encoding="utf-8") as data: + return json.load(data) + except Exception as e: + logger.error(f"Ошибка чтения {path}: {e}") + sys.exit(1) + +def get_current_time(): + now = datetime.now() + return now.hour, now.minute, now.second + +def parse_time(time_str): + h, m = map(int, time_str.split(':')) + return h * 60 + m + +def choose_wallpaper(current_time, settings): + current_hours, current_minutes, _ = current_time + current_minutes_total = current_hours * 60 + current_minutes + + for phase_name, data in settings.items(): + start = parse_time(data["time"][0]) + end = parse_time(data["time"][1]) + + if start <= end: + if start <= current_minutes_total <= end: + return data["file"], data["theme"], phase_name + else: + if current_minutes_total >= start or current_minutes_total <= end: + return data["file"], data["theme"], phase_name + + return "night.jpg", "dark", "night" + +def check_system_active(): + """Проверяет, активна ли система (не в процессе suspend/resume)""" + try: + result = subprocess.run( + ["systemctl", "status", "sleep.target", "suspend.target", + "hibernate.target", "hybrid-sleep.target"], + capture_output=True, text=True, timeout=2 + ) + # Если есть активные таргеты сна - ждём + if result.returncode == 0: + return False + except Exception: + pass + return True + +def set_wallpaper(image): + wallpaper_path = os.path.join(get_base_dir(), "wallpapers", image) + + if not os.path.exists(wallpaper_path): + logger.error(f"Файл не найден: {wallpaper_path}") + return False + + uri = f"file://{wallpaper_path}" + + try: + subprocess.run( + ["gsettings", "set", "org.gnome.desktop.background", "picture-options", "zoom"], + check=True, capture_output=True + ) + except subprocess.CalledProcessError as e: + logger.warning(f"Ошибка picture-options: {e}") + + keys = [ + ("org.gnome.desktop.background", "picture-uri"), + ("org.gnome.desktop.background", "picture-uri-dark"), + ] + + success = True + for schema, setting in keys: + try: + subprocess.run( + ["gsettings", "set", schema, setting, f"'{uri}'"], + check=True, capture_output=True + ) + except subprocess.CalledProcessError as e: + logger.warning(f"Ошибка {setting}: {e}") + success = False + + return success + +def switch_theme(theme): + scheme = "prefer-dark" if theme == "dark" else "prefer-light" + try: + subprocess.run( + ["gsettings", "set", "org.gnome.desktop.interface", "color-scheme", scheme], + check=True, capture_output=True + ) + except subprocess.CalledProcessError as e: + logger.warning(f"Ошибка смены темы: {e}") + +def main(): + global RUNNING + + signal.signal(signal.SIGTERM, signal_handler) + signal.signal(signal.SIGINT, signal_handler) + + settings = get_settings() + last_applied = None + was_inactive = False + + logger.info("Демон обоев запущен. Ожидание переключений...") + + while RUNNING: + current_time = get_current_time() + image, theme, phase = choose_wallpaper(current_time, settings) + current_key = f"{image}_{theme}" + + # Проверяем активность системы + system_active = check_system_active() + + # Если система только что вернулась из сна - применяем обои принудительно + if was_inactive and system_active: + logger.info("Система вернулась из сна, применяю обои...") + switch_theme(theme) + if set_wallpaper(image): + last_applied = current_key + was_inactive = False + elif current_key != last_applied: + logger.info(f"Переключение: {phase} -> {image} (тема: {theme})") + switch_theme(theme) + if set_wallpaper(image): + last_applied = current_key + else: + logger.debug(f"Без изменений: {phase} -> {image}") + + if not system_active: + was_inactive = True + logger.debug("Система неактивна (сон/приостановка)") + + # Короткий интервал опроса для быстрой реакции после сна + # Используем interruptible sleep для корректной обработки сигналов + sleep_seconds = 30 + + logger.debug(f"Сон на {sleep_seconds} сек") + + # Прерываемый сон - проверяем RUNNING каждые 0.5 сек + import time + for _ in range(sleep_seconds * 2): + if not RUNNING: + break + time.sleep(0.5) + + logger.info("Демон остановлен") + +if __name__ == "__main__": + main() diff --git a/wallpaper_handle.py b/wallpaper_handle.py new file mode 100644 index 0000000..9abb5d0 --- /dev/null +++ b/wallpaper_handle.py @@ -0,0 +1,89 @@ +from datetime import datetime +import subprocess +import os +import json +import sys + +def get_settings(): + base_dir = os.path.dirname(os.path.abspath(__file__)) + path = os.path.join(base_dir, "settings.json") + try: + with open(path, "r", encoding="utf-8") as data: + return json.load(data) + except Exception: + print(f"Ошибка: Не удалось прочитать {path}") + sys.exit() + +def get_current_time(): + return [datetime.now().hour, datetime.now().minute] + +def switch_theme(theme): + scheme = "prefer-dark" if theme == "dark" else "prefer-light" + cmd = ["gsettings", "set", "org.gnome.desktop.interface", "color-scheme", scheme] + try: + subprocess.run(cmd, check=True) + except subprocess.CalledProcessError as e: + print(f"Ошибка при смене темы: {e}") + +def choose_wallpaper(current_time, settings): + current_hours, current_minutes = current_time + for phase_name, data in settings.items(): + start_hours, start_minutes = map(int, data["time"][0].split(':')) + end_hours, end_minutes = map(int, data["time"][1].split(':')) + if (start_hours, start_minutes) <= (current_hours, current_minutes) \ + <= (end_hours, end_minutes): + return data["file"], data["theme"] + return "night.jpg", "dark" + +def main(): + settings = get_settings() + current_time = get_current_time() + image, theme = choose_wallpaper(current_time, settings) + switch_theme(theme) + set_wallpaper(image) + + +def set_wallpaper(image): + base_dir = os.path.dirname(os.path.abspath(__file__)) + wallpaper_path = os.path.join(base_dir, "wallpapers", image) + + if not os.path.exists(wallpaper_path): + print(f"ОШИБКА: Файл не найден: {wallpaper_path}") + return + uri = f"file://{wallpaper_path}" + try: + subprocess.run( + ["gsettings", "set", "org.gnome.desktop.background", "picture-options", "zoom"], + check=True + ) + except subprocess.CalledProcessError as e: + print(f"Ошибка при установке picture-options: {e}") + + keys = [ + ("org.gnome.desktop.background", "picture-uri"), + ("org.gnome.desktop.background", "picture-uri-dark"), + ("org.gnome.desktop.screensaver", "picture-uri") + ] + + for schema, setting in keys: + command = ["gsettings", "set", schema, setting, f"'{uri}'"] + try: + subprocess.run(command, check=True) + print(f"Успешно: {setting} -> {image}") + except subprocess.CalledProcessError as e: + print(f"Ошибка: {e}") + try: + subprocess.run([ + "gdbus", "call", "--session", + "--dest", "org.gnome.Shell", + "--object-path", "/org/gnome/Shell", + "--method", "org.gnome.Shell.Eval", + "imports.gi.Meta.BackgroundActor.get_for_screen(global.display.get_screen()).force_redraw()" + ], check=False, capture_output=True) + except Exception: + pass + + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/wallpapers/before_night.jpg b/wallpapers/before_night.jpg new file mode 100644 index 0000000..58f7006 Binary files /dev/null and b/wallpapers/before_night.jpg differ diff --git a/wallpapers/day.jpg b/wallpapers/day.jpg new file mode 100644 index 0000000..e5f7e2d Binary files /dev/null and b/wallpapers/day.jpg differ diff --git a/wallpapers/evening.jpg b/wallpapers/evening.jpg new file mode 100644 index 0000000..053536e Binary files /dev/null and b/wallpapers/evening.jpg differ diff --git a/wallpapers/morning.jpg b/wallpapers/morning.jpg new file mode 100644 index 0000000..26d41f4 Binary files /dev/null and b/wallpapers/morning.jpg differ diff --git a/wallpapers/night.jpg b/wallpapers/night.jpg new file mode 100644 index 0000000..9785935 Binary files /dev/null and b/wallpapers/night.jpg differ