Bing wallpapers on Linux (python version)
Earlier I made a post with the script which pulls wallpapers from Bing. Here I show my Python script, which is doing the same:
- Saves new image from the Bing server.
- Adds watermark with the copyright information to it.
- Sets this image the lock screen tool and/or as a desktop wallpaper.
Script logic
- To store wallpapers I use
~/wallpapers/bing/
folder. - In order to detect if image on the Bing server is the new one, I do the following:
- I save copyright information of the last saved (and currently used) image in the
~/wallpapers/bing/bing_wallpaper_copyright.txt
file. - On each request to Bing I compare copyright information of the image on server with the one in the file.
- If copyright is the same - then I don’t update image.
- If copyright differs - then I download the image.
- Every image with the copyright watermark I save in the
~/wallpapers/bing/
folder.
- I save copyright information of the last saved (and currently used) image in the
- Then I use downloaded image as:
- As a background picture for the [slick-greeter] for LightDM.
- Because
slick-greeter
has panel on top, I use image without copyright watermark for it. - For that I am saving it under the
/mnt/data/greeter-wallpapers/bing_image.jpg
name. - This image is always overwritten with the latest downloaded one. I do not save images without copyright watermark.
- Because
- Lock screen picture for betterlockscreen.
- Picture with the watermark copyright on it.
- Lock screen picture for slock-bgimage:
- I take picture with the copyright watermark on it as a source and I add small locker icon to its corner. Source www.flaticon.com.
Lock icon for watermark
- Then I save this image under
~/wallpapers/bing/current_lock_image.jpg
name.Image with watermark and lock
- I take picture with the copyright watermark on it as a source and I add small locker icon to its corner. Source www.flaticon.com.
- As a background picture for the [slick-greeter] for LightDM.
I am not using
/tmp
folder for storing my images for screen locker and for my greeter program. I do it because locker and greeter shall work properly after reboot.
I stopped using
betterlockscreen
because it leaks pop up and notification windows in my setup. I tried to fix it but I could not find solution. And I switched toslock
which is much simpler, faster and has no issues with leaking windows.
Python script itself
Expand to see full script
1#!/bin/python
2
3import requests
4import json
5import sys
6import os
7from PIL import Image
8from PIL import ImageDraw
9from PIL import ImageFont
10
11# Defining URL for pulling the data
12bing_url="https://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1&mkt=de-DE"
13
14# Path to the text file with the copyright text
15local_copyright_file = '/home/alexgum/wallpapers/bing/bing_wallpaper_copyright.txt'
16
17# Path to the font I am using
18local_font = '/usr/share/fonts/TTF/Arial.TTF'
19
20# Folder where I store wallpapers
21wallpaper_folder = '/home/alexgum/wallpapers/bing/'
22
23# Path to the temporary file
24# Firstly, image is downloaded there
25temp_file_path = '/tmp/bing_image_temp.jpg'
26
27# Path to the final file which is going to be used by slick-greeter
28greeter_file_path = '/mnt/data/greeter-wallpapers/bing_image.jpg'
29
30# Icon I use to add locker watermark on the image for slock
31lock_logo_file = '/home/alexgum/.config/icons/lock_64.png'
32
33# Path to the image for slock
34slock_file = '/home/alexgum/wallpapers/bing/current_lock_image.jpg'
35
36# Function to extract file name from the JSON data
37def make_img_file_name(full_json: dict) -> str:
38 try:
39 url_temp = full_json['images'][0]['url'].split('&')
40 return url_temp[0].split('.')[1] + '.jpg'
41 except Exception as e:
42 print("make_img_file_name(): Error. Cannot produce file name.")
43 print(e)
44 sys.exit(1)
45
46# Function to get URL for downloading picture
47# Input - full JSON response, returns string with URL
48def get_picture_url_from_json(full_json: dict) -> str:
49 try:
50 return 'https://bing.com/' + full_json['images'][0]['url']
51 except Exception as e:
52 print("get_picture_url(): Error. Cannot get picture url.")
53 print(e)
54 sys.exit(1)
55
56# Function to get copyright information from the file on disk
57# Input - path to a file with the copyright data of the current image
58# Returns string with the copyright text, or "None"
59def get_copyright_from_file(local_file_name: str) -> str:
60 try:
61 with open(local_file_name, 'rt') as f:
62 return f.readline()
63 except Exception:
64 return "None"
65
66# Function to get copyright information from the JSON data
67# Input - full JSON response, returns string with the copyright text
68def get_copyright_from_json(full_json: dict) -> str:
69 try:
70 return full_json['images'][0]['copyright']
71 except Exception as e:
72 print("get_copyright_from_json(): Error. Cannot get copyright from url.")
73 print(e)
74 sys.exit(1)
75
76# Function to download image
77# Input - URL and path to file where image to be stored
78def img_download(url: str,
79 target_file: str = '/tmp/bing_image_temp.jpg') -> None:
80 try:
81 image_file = requests.get(url)
82 with open(target_file, 'wb') as f:
83 f.write(image_file.content)
84 except Exception as e:
85 print(e)
86 sys.exit(1)
87
88# Function to make wallper image with the copyright watermark
89def make_new_wallpaper(source_file_path: str,
90 target_wallpaper_name: str,
91 copyright_text: str,
92 font_path: str = '/usr/share/fonts/TTF/Arial.TTF') -> None:
93
94 # Code is based on this blog post:
95 ## https://betterprogramming.pub/add-copyright-or-watermark-to-photos-using-python-a3773c71d431
96
97 # Preparing image for drawing (open canvas)
98 img = Image.open(source_file_path)
99 w, h = img.size
100
101 # Preparing text for drawing
102 ## Making drawing canvas
103 drawing = ImageDraw.Draw(img)
104
105 ## Creating text image
106 cprw_font = ImageFont.truetype(font_path, 14)
107 copyright_text_with_margins = " " + copyright_text + " "
108
109 ## Identifying its dimensions
110 text_w, text_h = drawing.textsize(copyright_text_with_margins,cprw_font)
111
112 # Drawing new image from the text object
113 c_text = Image.new('RGBA', (text_w, text_h), color = '#000000')
114 drawing = ImageDraw.Draw(c_text)
115 drawing.text((0,0),copyright_text_with_margins,fill = '#FFFFFF',font = cprw_font)
116 # Adding Alpha channel value
117 c_text.putalpha(130)
118
119 # Identifying text position on the target picture
120 # 10 pixels from top and 10 pixels from the right edge
121 text_position = (w - text_w - 10), 10
122
123 # Pasting this object into the image
124 img.paste(c_text,text_position,mask=c_text)
125
126 # Saving new image
127 try:
128 img.save(target_wallpaper_name)
129 except Exception as e:
130 print('make_new_wallpaper() function cannot save new picture.')
131 print(e)
132 sys.exit(1)
133
134def add_logo(source_file_path: str,
135 target_lock_file: str,
136 logo: str) -> None:
137
138 # Preparing image for drawing (open canvas)
139 img = Image.open(source_file_path)
140 w, h = img.size
141 logo_img = Image.open(logo).convert('RGBA')
142 logo_w, logo_h = logo_img.size
143
144 # converting logo background to transparent and adding alpha channel 178 (80%) to black
145 newImage = []
146 for item in logo_img.getdata():
147 if item[:3] == (255, 255, 255):
148 newImage.append((255, 255, 255, 0))
149 else:
150 newImage.append((0,0,0,178))
151 logo_img.putdata(newImage)
152 logo_position = 10, (h - logo_h - 16)
153 img.paste(logo_img,logo_position,mask=logo_img)
154
155 # Saving new image
156 try:
157 img.save(target_lock_file)
158 except Exception as e:
159 print('add_logo() function cannot save new picture.')
160 print(e)
161 sys.exit(1)
162
163# Main function to assemble it all
164def main() -> None:
165 try:
166 # Getting the JSON data
167 json_data = requests.get(bing_url).json()
168
169 # Extracting new copyright text
170 new_copyright_text = get_copyright_from_json(json_data)
171
172 # Comparing the new copyright text with the stored in the file
173 # If texts are different, then go on
174 if get_copyright_from_file(local_copyright_file) != new_copyright_text:
175
176 # Extracting new image file name from JSON
177 file_name = wallpaper_folder + make_img_file_name(json_data)
178
179 # Extracting URL for image download
180 file_url = get_picture_url_from_json(json_data)
181
182 # Downloading the image and saving it in the /tmp folder
183 img_download(file_url, temp_file_path)
184
185 # Creating wallpaper image with the copyright watermark
186 # and saving it in the ~/wallpapers/bing/ folder
187 make_new_wallpaper(temp_file_path, file_name, new_copyright_text, local_font)
188
189 # Updating copyright information in the local file
190 open(local_copyright_file,'wt').write(new_copyright_text)
191
192 # Adding locker logo to make image for slock
193 # this image is stored in the ~/wallpapers/bing/current_lock_image.jpg
194 add_logo(file_name, slock_file, lock_logo_file)
195
196 # Copy orignal image from /tmp to the /mnt/data/greeter-wallpapers/bing_image.jpg
197 # for being used with slick-greeter
198 os.system('cp ' + temp_file_path + ' ' + greeter_file_path)
199
200 # Setting up betterlockscreen
201 ## Optional part I don't use anymore.
202 os.system('DISPLAY=:0 /usr/bin/betterlockscreen -u ' + file_name)
203
204 except Exception as e:
205 print(e)
206
207if __name__ == '__main__':
208 main()
Runnig the script
Use simple cronjob:
1# {min} {hour} {day of month} {moth} {day of week} command to be executed
20,30 6-19 * * * /home/alexgum/.scripts/lockscreenpicture.py > /tmp/lockscreen.log