-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
133 lines (108 loc) · 3.35 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import asyncio
import os
from datetime import datetime, timedelta
import filetype
import requests
from PIL import Image
from modules import bluesky, mastodon, tumblr, twitter
from utils.globals import IMG_EXTENSIONS, IMG_PATH, cfg, log
retry_count = 0
async def fetch_img():
# ensure at least one site is enabled otherwise we're wasting our time
if (
not cfg.get('twitter.enabled') and
not cfg.get('mastodon.enabled') and
not cfg.get('tumblr.enabled') and
not cfg.get('bluesky.enabled')
):
log.error('No sites are enabled. Please enable at least one site in config.json.')
return
log.info('Fetching image from https://thecatapi.com')
res = requests.get(
url = 'https://api.thecatapi.com/v1/images/search?mime_types=jpg,png',
headers = { 'x-api-key': cfg.get('catapi-key') }
)
try:
data = res.json()
except requests.exceptions.JSONDecodeError:
log.error('Failed to fetch image.')
if retry_count == 3:
log.info('Retrying...')
global retry_count
retry_count += 1
await fetch_img()
else:
log.error('Reached retry limit, giving up.')
return
# catapi sometimes returns things in a list for some reason
if isinstance(data, list):
data = data[0]
# check if the request was successful by checking for the 'url' key
url = data.get('url')
if not url:
log.error('Failed to fetch image.')
return False
# if everything is successful, fetch the image and write it to a file
res = requests.get(url)
if os.path.exists(IMG_PATH):
try:
os.remove(IMG_PATH)
except Exception:
log.error(f'Failed to remove {IMG_PATH}.')
try:
with open(IMG_PATH, 'wb') as f:
f.write(res.content)
log.info('Fetched image successfully. Compressing image to be under 1MB.')
# resave image as webp to compress it
img = Image.open(IMG_PATH)
img.save(IMG_PATH, 'webp', quality=100)
while True:
with open(IMG_PATH, 'rb') as f:
img_bytes = f.read()
mib = len(img_bytes) / 1000 / 1000
if mib < 1:
break
img = Image.open(IMG_PATH)
width = int(img.width * 0.9)
height = int(img.height * 0.9)
img.resize((width, height), Image.Resampling.LANCZOS)
img.save(IMG_PATH, 'webp', quality=75)
except Exception:
log.error('Failed to write the fetched image.')
return
# check if the image is actually supported
img_type = filetype.guess(IMG_PATH)
if img_type is None or img_type.extension not in IMG_EXTENSIONS:
log.error('TheCatAPI returned an invalid image.')
return False
# if everything is successful, post the image to all the platforms
if cfg.get('twitter.enabled'):
try:
twitter()
except Exception:
log.error('Failed to post to Twitter.')
if cfg.get('tumblr.enabled'):
try:
tumblr()
except Exception:
log.error('Failed to post to Tumblr.')
if cfg.get('mastodon.enabled'):
try:
mastodon()
except Exception:
log.error('Failed to post to Mastodon.')
if cfg.get('bluesky.enabled'):
try:
bluesky()
except Exception:
log.error('Failed to post to Bluesky.')
print()
async def main():
while True:
current_time = datetime.now()
goal_timestamp = current_time + timedelta(hours = 1, minutes = -current_time.minute, seconds = -current_time.second, microseconds=-current_time.microsecond)
log.info(f'Posting at: {goal_timestamp.strftime("%H:%M:%S")}')
await asyncio.sleep((goal_timestamp - current_time).total_seconds())
await fetch_img()
if __name__ == '__main__':
asyncio.run(main())