Mercurial > hg > pub > prymula > scripts
comparison bing4desktop/bing4desktop.py @ 10:ed9556d0c5d7
bing4desktop-0.240205-4
author | prymula <prymula76@outlook.com> |
---|---|
date | Tue, 06 Feb 2024 00:30:36 +0100 |
parents | |
children | c01d7edb9cb9 |
comparison
equal
deleted
inserted
replaced
9:b2ef499536b0 | 10:ed9556d0c5d7 |
---|---|
1 #!/usr/bin/env python3 | |
2 # bing4desktop.py - skrypt tray dla Cinnamon oraz Matte i innych WM | |
3 # inspiracja: https://pystray.readthedocs.io/en/latest/usage.html | |
4 # oraz 'zasłyszane' w internecie :) | |
5 # licencja: Public Domain | |
6 # edytor: Geany | |
7 # data: 05-II-2024 | |
8 # napisał: Prymula | |
9 | |
10 # python3-pillow-tk | |
11 | |
12 import pystray | |
13 from pystray import Icon as icon, Menu as menu, MenuItem as item | |
14 import tkinter as tk | |
15 from tkinter import messagebox | |
16 from PIL import ImageTk, Image | |
17 | |
18 import os, sys, subprocess | |
19 import requests | |
20 import json | |
21 import tempfile | |
22 import shutil | |
23 | |
24 ver = "0.240205-4" | |
25 | |
26 BING_URI_BASE = "http://www.bing.com" | |
27 BING_WALLPAPER_PATH = "/HPImageArchive.aspx?format=js&idx=50&n=1&mkt=en-US" | |
28 full_path="" | |
29 actualImage = -1 | |
30 COPYRIGHT_TXT = "" | |
31 | |
32 tmp_path = tempfile.mkdtemp() | |
33 | |
34 | |
35 | |
36 class WPaper: | |
37 def get(self): | |
38 global full_path, COPYRIGHT_TXT | |
39 # open the Bing HPImageArchive URI and ask for a JSON response | |
40 resp = requests.get(BING_URI_BASE + BING_WALLPAPER_PATH) | |
41 | |
42 if resp.status_code == 200: | |
43 json_response = json.loads(resp.content) | |
44 wallpaper_path = json_response['images'][0]['url'] | |
45 COPYRIGHT_TXT = json_response['images'][0]['copyright'] | |
46 filename = wallpaper_path.split('/')[-1] | |
47 wallpaper_uri = BING_URI_BASE + wallpaper_path | |
48 filename_short = filename.split('&') | |
49 print ("filemname_short", filename_short[0]) | |
50 # open the actual wallpaper uri, and write the response as an image on the filesystem | |
51 response = requests.get(wallpaper_uri) | |
52 if resp.status_code == 200: | |
53 desktop_env = os.environ.get('DESKTOP_SESSION') | |
54 if desktop_env=="windows": | |
55 messagebox.showinfo("Błąd","Brak wsparcia dla Windows i Mac !") | |
56 cleanup() | |
57 exit | |
58 else: | |
59 full_path = tmp_path + filename_short[0] | |
60 with open(full_path, 'wb') as f: | |
61 f.write(response.content) | |
62 else: | |
63 raise ValueError("[ERROR] non-200 response from Bing server for '{}'".format(wallpaper_uri)) | |
64 COPYRIGHT_TXT = "[ERROR] non-200 response from Bing server for " + str(format(wallpaper_uri)) | |
65 return False | |
66 else: | |
67 raise ValueError("[ERROR] non-200 response from Bing server for '{}'".format(BING_URI_BASE + BING_WALLPAPER_PATH)) | |
68 COPYRIGHT_TXT = "[ERROR] non-200 response from Bing server for " + str(format(BING_URI_BASE + BING_WALLPAPER_PATH)) | |
69 return False | |
70 return True | |
71 | |
72 def set(self,file_loc, first_run): | |
73 global full_path | |
74 desktop_env = os.environ.get('DESKTOP_SESSION') | |
75 | |
76 if len(full_path) == 0: | |
77 messagebox.showinfo("Błąd","Niewybrano obrazu, najpierw wybierz obraz") | |
78 return | |
79 try: | |
80 if desktop_env in ["gnome-classic", "gnome", "unity", "default"]: | |
81 uri = "'file://%s'" % file_loc | |
82 try: | |
83 SCHEMA = "org.gnome.desktop.background" | |
84 KEY = "picture-uri" | |
85 gsettings = Gio.Settings.new(SCHEMA) | |
86 gsettings.set_string(KEY, uri) | |
87 except: | |
88 args = ["gsettings", "set", "org.gnome.desktop.background", "picture-uri", uri] | |
89 subprocess.Popen(args) | |
90 elif desktop_env in ["cinnamon"]: | |
91 uri = "'file://%s'" % file_loc | |
92 try: | |
93 SCHEMA = "org.cinnamon.desktop.background" | |
94 KEY = "picture-uri" | |
95 gsettings = Gio.Settings.new(SCHEMA) | |
96 gsettings.set_string(KEY, uri) | |
97 except: | |
98 args = ["gsettings", "set", "org.cinnamon.desktop.background", "picture-uri", uri] | |
99 subprocess.Popen(args) | |
100 elif desktop_env=="mate": | |
101 try: # MATE >= 1.6 | |
102 # info from http://wiki.mate-desktop.org/docs:gsettings | |
103 args = ["gsettings", "set", "org.mate.background", "picture-filename", "'%s'" % file_loc] | |
104 subprocess.Popen(args) | |
105 except: # MATE < 1.6 | |
106 # From https://bugs.launchpad.net/variety/+bug/1033918 | |
107 args = ["mateconftool-2","-t","string","--set","/desktop/mate/background/picture_filename",'"%s"' %file_loc] | |
108 subprocess.Popen(args) | |
109 elif desktop_env=="gnome2": # Not tested | |
110 # From https://bugs.launchpad.net/variety/+bug/1033918 | |
111 args = ["gconftool-2","-t","string","--set","/desktop/gnome/background/picture_filename", '"%s"' %file_loc] | |
112 subprocess.Popen(args) | |
113 ## KDE4 is difficult | |
114 ## see http://blog.zx2c4.com/699 for a solution that might work | |
115 elif desktop_env in ["kde3", "trinity"]: | |
116 # From http://ubuntuforums.org/archive/index.php/t-803417.html | |
117 args = 'dcop kdesktop KBackgroundIface setWallpaper 0 "%s" 6' % file_loc | |
118 subprocess.Popen(args,shell=True) | |
119 | |
120 elif desktop_env=="xfce4": | |
121 #From http://www.commandlinefu.com/commands/view/2055/change-wallpaper-for-xfce4-4.6.0 | |
122 if first_run: | |
123 args0 = ["xfconf-query", "-c", "xfce4-desktop", "-p", "/backdrop/screen0/monitor0/image-path", "-s", file_loc] | |
124 args1 = ["xfconf-query", "-c", "xfce4-desktop", "-p", "/backdrop/screen0/monitor0/image-style", "-s", "3"] | |
125 args2 = ["xfconf-query", "-c", "xfce4-desktop", "-p", "/backdrop/screen0/monitor0/image-show", "-s", "true"] | |
126 subprocess.Popen(args0) | |
127 subprocess.Popen(args1) | |
128 subprocess.Popen(args2) | |
129 args = ["xfdesktop","--reload"] | |
130 subprocess.Popen(args) | |
131 | |
132 elif desktop_env in ["fluxbox","jwm","openbox","afterstep"]: | |
133 #http://fluxbox-wiki.org/index.php/Howto_set_the_background | |
134 # used fbsetbg on jwm too since I am too lazy to edit the XML configuration | |
135 # now where fbsetbg does the job excellent anyway. | |
136 # and I have not figured out how else it can be set on Openbox and AfterSTep | |
137 # but fbsetbg works excellent here too. | |
138 try: | |
139 args = ["fbsetbg", file_loc] | |
140 subprocess.Popen(args) | |
141 except: | |
142 sys.stderr.write("ERROR: Failed to set wallpaper with fbsetbg!\n") | |
143 sys.stderr.write("Please make sre that You have fbsetbg installed.\n") | |
144 elif desktop_env=="icewm": | |
145 # command found at http://urukrama.wordpress.com/2007/12/05/desktop-backgrounds-in-window-managers/ | |
146 args = ["icewmbg", file_loc] | |
147 subprocess.Popen(args) | |
148 elif desktop_env=="blackbox": | |
149 # command found at http://blackboxwm.sourceforge.net/BlackboxDocumentation/BlackboxBackground | |
150 args = ["bsetbg", "-full", file_loc] | |
151 subprocess.Popen(args) | |
152 elif desktop_env=="lxde": | |
153 args = "pcmanfm --set-wallpaper %s --wallpaper-mode=scaled" % file_loc | |
154 subprocess.Popen(args,shell=True) | |
155 elif desktop_env=="WindowMaker": | |
156 # From http://www.commandlinefu.com/commands/view/3857/set-wallpaper-on-windowmaker-in-one-line | |
157 args = "wmsetbg -s -u %s" % file_loc | |
158 subprocess.Popen(args,shell=True) | |
159 elif desktop_env=="windows": #Not tested since I do not run this on Windows | |
160 #From https://stackoverflow.com/questions/1977694/change-desktop-background | |
161 import ctypes | |
162 SPI_SETDESKWALLPAPER = 20 | |
163 ctypes.windll.user32.SystemParametersInfoA(SPI_SETDESKWALLPAPER, 0, file_loc , 0) | |
164 else: | |
165 if first_run: #don't spam the user with the same message over and over again | |
166 sys.stderr.write("Warning: Failed to set wallpaper. Your desktop environment is not supported.") | |
167 sys.stderr.write("You can try manually to set Your wallpaper to %s" % file_loc) | |
168 return False | |
169 return True | |
170 except: | |
171 sys.stderr.write("ERROR: Failed to set wallpaper. There might be a bug.\n") | |
172 return False | |
173 | |
174 | |
175 class Gui(): | |
176 global COPYRIGHT_TXT | |
177 | |
178 def __init__(self): | |
179 self.window = tk.Tk() | |
180 self.image = Image.open("bing.ico") | |
181 self.menu = ( | |
182 item("Ustaw Tapetę", lambda icon, item: wp.set(full_path, True)), | |
183 item('Tapeta poprzednia', lambda icon, item: self.change_pic(1)), | |
184 item('Tapeta następna', lambda icon, item: self.change_pic(-1)), | |
185 item('Opis zdjęcia', lambda icon, item: icon.notify(COPYRIGHT_TXT)), | |
186 item('O Programie', lambda icon, item: self.about()), | |
187 | |
188 item('Wyjdź', self.quit_window) | |
189 ) | |
190 self.frame = tk.Frame(self.window, width=600, height=400) | |
191 self.frame.pack() | |
192 self.frame.place(anchor='center', relx=0.5, rely=5) | |
193 | |
194 #self.window.title("Bing4Desktop") | |
195 #self.window.geometry('800x600') | |
196 #self.window.protocol('WM_DELETE_WINDOW', self.withdraw_window) | |
197 self.withdraw_window() | |
198 self.window.mainloop() | |
199 | |
200 def about(self): | |
201 global ver | |
202 messagebox.showinfo("Bing4Desktop","Inspracja:\npystray.readthedocs.io/en/latest/usage.html\n\nNapisał: Prymula\n\nLuty 2024\n\nLicencja:\nPublic Domain\n\nWersja: "+ver) | |
203 # możliwe że nieprawidlowe | |
204 self.window.destroy() | |
205 self.window.update() | |
206 | |
207 | |
208 def change_pic(self, n): | |
209 global actualImage, BING_WALLPAPER_PATH | |
210 BASE = "/HPImageArchive.aspx?format=js&idx=" | |
211 OFF = "&n=1&mkt=en-US" | |
212 | |
213 actualImage = actualImage + n; | |
214 if (actualImage < 0): | |
215 actualImage = 10 | |
216 elif (actualImage > 10): | |
217 actualImage = 0 | |
218 | |
219 print ("FULL: ", len(full_path)) | |
220 | |
221 wp=WPaper() | |
222 if wp.get(): | |
223 BING_WALLPAPER_PATH = BASE+str(actualImage)+OFF | |
224 if wp.get() == False: | |
225 cleanup() | |
226 exit | |
227 | |
228 img = Image.open(full_path) #.convert('RGBA') # PIL solution | |
229 tmp = img.resize((600, 400), None, None, 3.0) | |
230 tmp.show() | |
231 | |
232 def quit_window(self): | |
233 self.icon.stop() | |
234 self.window.destroy() | |
235 | |
236 | |
237 def show_window(self): | |
238 self.icon.stop() | |
239 self.window.protocol('WM_DELETE_WINDOW', self.withdraw_window) | |
240 self.window.after(0, self.window.deiconify) | |
241 | |
242 | |
243 def withdraw_window(self): | |
244 self.window.withdraw() | |
245 self.icon = pystray.Icon("name", self.image, "title", self.menu) | |
246 self.icon.run() | |
247 | |
248 def cleanup(): | |
249 # NIEBEZPIECZNA ! lepiej niczym innym nie nadpisywać tych zmiennych | |
250 shutil.rmtree(tmp_path) | |
251 | |
252 if __name__ in '__main__': | |
253 wp=WPaper() | |
254 if wp.get(): | |
255 wp.set(full_path, True) | |
256 g = Gui() | |
257 cleanup() |