-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrenovate.py
164 lines (120 loc) · 4.85 KB
/
renovate.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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
import json
import logging
from datetime import datetime
from os import environ
from sys import exit, stdout
from typing import Any, Self
import dotenv
from discord_webhook import DiscordEmbed, DiscordWebhook
from loguru import logger
from loguru_discord import DiscordSink
from handlers import Intercept
from services import Battlenet, Orbis, Prospero, Steam
class Renovate:
"""
Renovate is a Steam, Battle.net, and PlayStation title watcher that
reports updates via Discord.
https://github.com/EthanC/Renovate
"""
def Start(self: Self) -> None:
"""Initialize Renovate and begin primary functionality."""
logger.info("Renovate")
logger.info("https://github.com/EthanC/Renovate")
# Reroute standard logging to Loguru
logging.basicConfig(handlers=[Intercept()], level=0, force=True)
if dotenv.load_dotenv():
logger.success("Loaded environment variables")
logger.trace(environ)
if level := environ.get("LOG_LEVEL"):
logger.remove()
logger.add(stdout, level=level)
logger.success(f"Set console logging level to {level}")
if url := environ.get("LOG_DISCORD_WEBHOOK_URL"):
logger.add(
DiscordSink(url),
level=environ.get("LOG_DISCORD_WEBHOOK_LEVEL"),
backtrace=False,
)
logger.success(f"Enabled logging to Discord webhook")
logger.trace(url)
self.history: dict[str, Any] = Renovate.LoadHistory(self)
self.changed: bool = False
# Steam
if titles := environ.get("STEAM_TITLES"):
for title in titles.split(","):
if result := Steam.IsUpdated(self, title):
Renovate.Notify(self, result)
# Battle.net
if titles := environ.get("BATTLE_TITLES"):
for title in titles.split(","):
if result := Battlenet.IsUpdated(self, title):
Renovate.Notify(self, result)
# PlayStation 5
if titles := environ.get("PROSPERO_TITLES"):
for title in titles.split(","):
if result := Prospero.IsUpdated(self, title):
Renovate.Notify(self, result)
# PlayStation 4
if titles := environ.get("ORBIS_TITLES"):
for title in titles.split(","):
if result := Orbis.IsUpdated(self, title):
Renovate.Notify(self, result)
if self.changed:
Renovate.SaveHistory(self)
logger.success("Finished processing titles")
def LoadHistory(self: Self) -> dict[str, Any]:
"""Load the last seen title versions specified in history.json"""
try:
with open("history.json", "r") as file:
history: dict[str, Any] = json.loads(file.read())
except FileNotFoundError:
history: dict[str, Any] = {
"steam": {},
"battle": {},
"prospero": {},
"orbis": {},
}
with open("history.json", "w+") as file:
file.write(json.dumps(history, indent=4))
logger.success("Title history not found, created empty file")
except Exception as e:
logger.opt(exception=e).critical("Failed to load title history")
exit(1)
if not history.get("steam"):
history["steam"] = {}
if not history.get("battle"):
history["battle"] = {}
if not history.get("prospero"):
history["prospero"] = {}
if not history.get("orbis"):
history["orbis"] = {}
logger.success("Loaded title history")
return history
def SaveHistory(self: Self) -> None:
"""Save the latest title versions to history.json"""
if environ.get("DEBUG"):
logger.warning("Debug is active, not saving title history")
return
try:
with open("history.json", "w+") as file:
file.write(json.dumps(self.history, indent=4))
except Exception as e:
logger.opt(exception=e).critical("Failed to save title history")
exit(1)
logger.success("Saved title history")
def Notify(self: Self, embed: DiscordEmbed) -> None:
"""Report title version change to the configured Discord webhook."""
if not (url := environ.get("DISCORD_WEBHOOK_URL")):
logger.info("Discord webhook for notifications is not set")
return
embed.set_author(
"Renovate",
url="https://github.com/EthanC/Renovate",
icon_url="https://i.imgur.com/HMRSQeQ.png",
)
DiscordWebhook(url=url, embeds=[embed], rate_limit_retry=True).execute()
if __name__ == "__main__":
try:
Renovate.Start(Renovate)
except KeyboardInterrupt:
exit()