Created
June 6, 2024 02:12
-
-
Save blackle/8380a76fa40bedccde4a66c2ff31bc82 to your computer and use it in GitHub Desktop.
background management tool
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import gi | |
gi.require_version('Gtk', '3.0') | |
from gi.repository import Gtk, GObject, GLib | |
from gi.repository.GdkPixbuf import Pixbuf, InterpType | |
import subprocess, os, time, errno | |
from xdg_base_dirs import xdg_cache_home, xdg_config_home | |
import shutil | |
PROGNAME = "blackle_backgrounder" | |
def mkdir_p(path): | |
try: | |
os.makedirs(path) | |
except OSError as exc: | |
if exc.errno != errno.EEXIST: | |
raise | |
feh_sizes = { | |
"Center": "--bg-center", | |
"Fill": "--bg-fill", | |
"Maximum": "--bg-max", | |
"Scale": "--bg-scale", | |
"Tile": "--bg-tile", | |
} | |
class MyWindow(Gtk.Window): | |
def __init__(self): | |
Gtk.Window.__init__(self, title="Blackle's Backgrounder", resizable=True, default_height=500, default_width=510) | |
self.cache_directory = xdg_cache_home() / PROGNAME | |
self.config_directory = xdg_config_home() / PROGNAME | |
self.folder_file = self.config_directory / "folder" | |
mkdir_p(self.config_directory) | |
mkdir_p(self.cache_directory) | |
self.killed = False | |
try: | |
self.wallpaper_directory = open(self.folder_file, 'r').readline() | |
except: | |
if not self.change_folder(): | |
self.killed = True | |
return | |
self.close_button = self.make_button("_Close", "window-close") | |
self.close_button.connect("clicked", Gtk.main_quit) | |
self.file_button = self.make_button("Change _Folder", "folder-open") | |
self.file_button.connect("clicked", self.change_folder_cb) | |
self.browser_info = Gtk.ListStore(Pixbuf, str) | |
self.image_browser = Gtk.IconView.new() | |
self.image_browser.set_model(self.browser_info) | |
self.image_browser.set_pixbuf_column(0) | |
self.image_browser.set_selection_mode(Gtk.SelectionMode.BROWSE) | |
#self.image_browser.set_columns(2) | |
self.image_browser.set_item_width(190) | |
self.image_browser.connect("selection-changed", self.update_wallpaper) | |
self.browser_scroll = Gtk.ScrolledWindow() | |
self.browser_scroll.add(self.image_browser) | |
#self.browser_scroll.set_size_request(502, 450) | |
self.style_combo = Gtk.ComboBoxText() | |
self.style_combo.connect("changed", self.update_wallpaper) | |
self.style_combo.set_entry_text_column(0) | |
for style in feh_sizes.keys(): | |
self.style_combo.append_text(style) | |
self.style_combo.set_active(1) | |
self.blankbox = Gtk.Box() | |
self.main_table = Gtk.Table(n_rows=4, n_columns=2, homogeneous=False) | |
self.main_table.attach(self.style_combo, 0, 1, 1, 2, Gtk.AttachOptions.SHRINK, Gtk.AttachOptions.SHRINK, 4, 4) | |
self.main_table.attach(self.close_button, 3, 4, 1, 2, Gtk.AttachOptions.SHRINK, Gtk.AttachOptions.SHRINK, 4, 4) | |
self.main_table.attach(self.file_button, 2, 3, 1, 2, Gtk.AttachOptions.SHRINK, Gtk.AttachOptions.SHRINK, 4, 4) | |
self.main_table.attach(self.browser_scroll, 0, 4, 0, 1, Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL, Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL, 4, 4) | |
self.main_table.attach(self.blankbox, 1, 2, 1, 2, Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL, Gtk.AttachOptions.SHRINK, 4, 4) | |
self.add(self.main_table) | |
self.parse_directory() | |
def make_button(self, text, icon): | |
btn = Gtk.Button.new_with_mnemonic(text) | |
icon = Gtk.Image.new_from_icon_name(icon, Gtk.IconSize.BUTTON) | |
btn.set_image(icon) | |
btn.set_always_show_image(True) | |
return btn | |
def parse_directory(self): | |
os.chdir(self.wallpaper_directory) | |
self.filelist = os.listdir(".") | |
self.filelist.sort(key=lambda x: -os.path.getmtime(x)) | |
self.thumbdict = dict() | |
self.iterator = 0 | |
GLib.idle_add(self.loadmore, None) | |
def update_wallpaper(self, widget): | |
"""Update wallpaper using feh command (creates .fehbg which is useful)""" | |
style = self.style_combo.get_active_text() | |
command = feh_sizes.get(style, feh_sizes['Fill']) | |
try: | |
background = self.image_browser.get_selected_items()[0] | |
except: | |
return | |
path = self.browser_info[background][1] | |
subprocess.run(["feh", command, path]) | |
def loadmore(self, derp): | |
"""Reduce startup time by using an idle signal to load wallpaper icons""" | |
file = self.filelist[self.iterator] | |
_, ext = os.path.splitext(file) | |
print(ext) | |
if ext.lower() in [".png", ".jpeg", ".jpg"]: | |
wallpaper = self.wallpaper_directory+"/"+file | |
thumb_path = file | |
self.thumbdict[thumb_path+".png"] = 0 | |
thumb_path = self.cache_directory / (thumb_path+".png") | |
if not (os.path.exists(thumb_path) and os.path.getmtime(thumb_path) > os.path.getmtime(wallpaper)): | |
tempthumb = Pixbuf.new_from_file(wallpaper) | |
target_width = 220 | |
target_height = 124 | |
scale = min( | |
target_width / tempthumb.get_width(), | |
target_height / tempthumb.get_height() | |
) | |
tempthumb = tempthumb.scale_simple(tempthumb.get_width()*scale, tempthumb.get_height()*scale, InterpType.TILES) | |
self.browser_info.append([tempthumb, wallpaper]) | |
print(str(thumb_path)) | |
tempthumb.savev(str(thumb_path), "png") | |
else: | |
self.browser_info.append([Pixbuf.new_from_file(str(thumb_path)), wallpaper]) | |
self.iterator += 1 | |
if self.iterator >= len(self.filelist): | |
GLib.idle_add(self.clean_thumbnails, None) | |
else: | |
GLib.idle_add(self.loadmore, None) | |
def change_folder_cb(self, btn): | |
if self.change_folder(): | |
self.browser_info.clear() | |
self.parse_directory() | |
def change_folder(self): | |
chooser = Gtk.FileChooserDialog( | |
title="Change Wallpaper Search Folder", | |
action=Gtk.FileChooserAction.SELECT_FOLDER | |
) | |
chooser.add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL) | |
chooser.add_buttons(Gtk.STOCK_OPEN, Gtk.ResponseType.OK) | |
response = chooser.run() | |
if response == Gtk.ResponseType.OK: | |
self.wallpaper_directory = chooser.get_filename() | |
open(self.folder_file, "w").write(self.wallpaper_directory) | |
chooser.destroy() | |
else: | |
chooser.destroy() | |
return False | |
return True | |
def clean_thumbnails(self, btn): | |
os.chdir(self.cache_directory) | |
files = os.listdir(".") | |
for file in files: | |
if file not in self.thumbdict: | |
os.remove(file) | |
win = MyWindow() | |
win.connect("delete-event", Gtk.main_quit) | |
if not win.killed: | |
win.show_all() | |
Gtk.main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment