1 | #!/usr/bin/env python3 |
2 | """Performs automatic Unsplash queries for a desktop wallpaper slideshow""" |
3 |
|
4 | import time |
5 | import sys |
6 | import os |
7 | import random |
8 | import requests |
9 |
|
10 | IMAGE_WIDTH = 3840 |
11 | IMAGE_HEIGHT = 1080 |
12 | TEXT_ENABLED = False |
13 |
|
14 | UNSPLASH_API = "https://api.unsplash.com/search/photos" |
15 |
|
16 | REQUEST_HEADERS = {"Accept-Version": "v1"} |
17 | REQUEST_PAYLOAD = {"per_page": 10, "orientation": "landscape"} |
18 |
|
19 | CROP_PARAMS = f"&fm=jpg&q=90&fit=crop&w={IMAGE_WIDTH}&h={IMAGE_HEIGHT}" |
20 | TEXT_PARAMS = "&txt-color=FFFFFF&txt-size=18&txt-shad=5&txt-pad=60" |
21 |
|
22 |
|
23 | def fetch_images(api_key: str, query: str, page_num: int): |
24 | """Make Unsplash API request for image search results""" |
25 |
|
26 | # prepare payload |
27 | page_headers = REQUEST_HEADERS |
28 | page_headers["Authorization"] = f"Client-ID {api_key}" |
29 |
|
30 | page_params = REQUEST_PAYLOAD |
31 | page_params["page"] = page_num |
32 | page_params["query"] = query |
33 |
|
34 | # make request |
35 | result = requests.get(UNSPLASH_API, headers=page_headers, params=page_params) |
36 |
|
37 | # handle API error |
38 | if result.status_code != 200: |
39 | print("unsplash API error:") |
40 | print(result.json) |
41 | return 1 |
42 |
|
43 | # parse JSON |
44 | json = result.json() |
45 | images = [] |
46 | try: |
47 | for image in json["results"]: |
48 | url = image["urls"]["raw"] + CROP_PARAMS |
49 | if TEXT_ENABLED: |
50 | url += f"&txt={query.upper()} ({page_num})" + TEXT_PARAMS |
51 | images.append(url) |
52 | except IndexError: |
53 | return 1 |
54 |
|
55 | return images |
56 |
|
57 |
|
58 | def display_image(url: str): |
59 | """Download image by URL to /tmp/unsplash_bg.jpg and set as background""" |
60 |
|
61 | # download |
62 | image = requests.get(url, stream=True) |
63 | if image.status_code != 200: |
64 | print("unsplash image error") |
65 | print(image) |
66 | return 1 |
67 |
|
68 | # save to /tmp/unsplash_bg.jpg |
69 | with open("/tmp/unsplash_bg.jpg", "wb") as image_file: |
70 | for chunk in image: |
71 | image_file.write(chunk) |
72 |
|
73 | # use gsettings to set as new background |
74 | os.system( |
75 | "/usr/bin/gsettings set org.gnome.desktop.background picture-uri /tmp/unsplash_bg.jpg" |
76 | ) |
77 | return 0 |
78 |
|
79 |
|
80 | def main(): |
81 | """Main controlling logic, handles command arguments""" |
82 | api_key = "" |
83 | interval = 60 |
84 | queries = [] |
85 | if len(sys.argv) < 3: |
86 | print( |
87 | "usage: ./unsplash-background.py <unsplash-api-key> <second-interval> [keywords]+" |
88 | ) |
89 | sys.exit(1) |
90 | else: |
91 | try: |
92 | api_key = str(sys.argv[1]) |
93 | interval = int(sys.argv[2]) |
94 | queries = [str(q) for q in sys.argv[3:]] |
95 | except ValueError: |
96 | print( |
97 | "usage: ./unsplash-background.py <unsplash-api-key> <second-interval> [keywords]+" |
98 | ) |
99 | sys.exit(1) |
100 | page_num = 0 |
101 | while True: |
102 | page_num += 1 |
103 | page_num = page_num if page_num < 4 else 1 |
104 | images = [] |
105 | for query in queries: |
106 | search = None |
107 | while True: |
108 | # repeat request every 15 secs until 200 if error |
109 | search = fetch_images(api_key, query, page_num) |
110 | if search == 1: |
111 | time.sleep(15) |
112 | else: |
113 | break |
114 | images += search |
115 | random.seed() |
116 | random.shuffle(images) |
117 | for image in images: |
118 | if display_image(image) == 0: |
119 | time.sleep(interval) |
120 |
|
121 |
|
122 | if __name__ == "__main__": |
123 | main() |
124 |
|