Skip to content

Commit f68cab0

Browse files
authored
Update at-extender.py
**Version 1.1.8 released** Changelog 1.1.8: - Community+ Unterstützung integriert (Anordnung des Datenvolumen ändert sich dadurch, kein auslesen des Community+ Volumens // nachbuchen noch nicht getestet) - Auf Wunsch Emoji Änderung beim Nachbuchen. - System-Ressourcen Erkennung eingebaut unter 2GB Ram, werden extra Settings für den browser geladen. - Webkit Unterstützung gefixt. Es wird " import psutil" benötigt, wer es nicht installiert hat, installiert das script automatisch über pip nach.
1 parent 85dd946 commit f68cab0

File tree

1 file changed

+91
-46
lines changed

1 file changed

+91
-46
lines changed

at-extender.py

Lines changed: 91 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,28 @@
88
import sys
99
import io
1010
import re
11+
try:
12+
import psutil
13+
except ImportError:
14+
import subprocess
15+
import sys
16+
subprocess.check_call([sys.executable, "-m", "pip", "install", "psutil"])
17+
import psutil
1118
from playwright.sync_api import sync_playwright, TimeoutError
1219

20+
def is_low_memory():
21+
#Erkennt schwache Server (unter 2 GB RAM)
22+
total_ram = psutil.virtual_memory().total / (1024**3)
23+
return total_ram <= 2.0
24+
25+
def get_launch_args(browser):
26+
if browser == "chromium" and is_low_memory():
27+
return ["--no-sandbox", "--disable-dev-shm-usage"]
28+
else:
29+
return []
30+
31+
32+
1333
# Logging einrichten
1434
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
1535
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
@@ -18,14 +38,14 @@
1838
LOGIN_URL = "https://login.alditalk-kundenbetreuung.de/signin/XUI/#login/"
1939
DASHBOARD_URL = "https://www.alditalk-kundenportal.de/portal/auth/uebersicht/"
2040

21-
VERSION = "1.1.6" # Deine aktuelle Version
41+
VERSION = "1.1.8" # Deine aktuelle Version
2242

2343
REMOTE_VERSION_URL = "https://raw.githubusercontent.com/Dinobeiser/AT-Extender/main/version.txt" # Link zur Version
2444
REMOTE_SCRIPT_URL = "https://raw.githubusercontent.com/Dinobeiser/AT-Extender/main/at-extender.py" # Link zum neuesten Skript
2545

2646
USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:137.0) Gecko/20100101 Firefox/139.0"
2747
HEADLESS = True
28-
48+
browser = None
2949

3050
def load_config():
3151
with open("config.json", "r") as f:
@@ -73,7 +93,6 @@ def load_config():
7393
logging.error(f"Konnte 'state.json' nicht neu erstellen: {save_error}")
7494

7595

76-
7796
def send_telegram_message(message, retries=3):
7897
if TELEGRAM == "1":
7998
for attempt in range(retries):
@@ -145,21 +164,80 @@ def wait_and_click(page, selector, timeout=5000, retries=5):
145164
logging.error(f"Konnte {selector} nicht klicken.")
146165
return False
147166

167+
168+
def get_datenvolumen(page):
169+
logging.info("Lese Datenvolumen aus...")
170+
171+
try:
172+
label_selector = 'one-stack.usage-meter:nth-child(1) > one-usage-meter:nth-child(1) > one-button:nth-child(2)'
173+
label_element = page.query_selector(label_selector)
174+
label_text = label_element.text_content().strip() if label_element else ""
175+
176+
if "Inland & EU" in label_text:
177+
logging.info("Community+")
178+
GB_selectors = [
179+
'one-stack.usage-meter:nth-child(2) > one-usage-meter:nth-child(1) > one-group:nth-child(1) > one-heading:nth-child(2)',
180+
'one-stack.usage-meter:nth-child(2) > one-stack:nth-child(1) > one-usage-meter:nth-child(1) > one-group:nth-child(1) > one-heading:nth-child(2)'
181+
]
182+
else:
183+
logging.info("Kein Community+ erkannt")
184+
GB_selectors = [
185+
'one-stack.usage-meter:nth-child(1) > one-usage-meter:nth-child(1) > one-group:nth-child(1) > one-heading:nth-child(2)',
186+
'one-stack.usage-meter:nth-child(1) > one-stack:nth-child(1) > one-usage-meter:nth-child(1) > one-group:nth-child(1) > one-heading:nth-child(2)'
187+
]
188+
except Exception as e:
189+
logging.warning(f"Fehler bei der Erkennung von Community+: {e}")
190+
GB_selectors = [
191+
'one-stack.usage-meter:nth-child(1) > one-usage-meter:nth-child(1) > one-group:nth-child(1) > one-heading:nth-child(2)',
192+
'one-stack.usage-meter:nth-child(1) > one-stack:nth-child(1) > one-usage-meter:nth-child(1) > one-group:nth-child(1) > one-heading:nth-child(2)'
193+
]
194+
195+
GB_text_raw = None
196+
for sel in GB_selectors:
197+
try:
198+
element = page.query_selector(sel)
199+
if element:
200+
GB_text_raw = element.text_content()
201+
if GB_text_raw:
202+
break
203+
except Exception as e:
204+
logging.warning(f"Selector {sel} nicht verfügbar: {e}")
205+
continue
206+
207+
if not GB_text_raw:
208+
raise Exception("Konnte das Datenvolumen nicht auslesen – kein gültiger Selector gefunden.")
209+
210+
match = re.search(r"([\d\.,]+)\s?(GB|MB)", GB_text_raw)
211+
if not match:
212+
raise ValueError(f"Unerwartetes Format beim Datenvolumen: {GB_text_raw}")
213+
214+
value, unit = match.groups()
215+
value = value.replace(",", ".")
216+
217+
if unit == "MB":
218+
GB = float(value) / 1024
219+
else:
220+
GB = float(value)
221+
222+
return GB
223+
224+
148225
def login_and_check_data():
149226
global LAST_GB
150227
with sync_playwright() as p:
151228
for attempt in range(3): # 3 Versuche, falls Playwright abstürzt
152229
try:
153230
COOKIE_FILE = "cookies.json"
154231
logging.info(f"Starte {BROWSER}...")
232+
LAUNCH_ARGS = get_launch_args(BROWSER)
155233

156234
# Browser starten
157235
if BROWSER == "firefox":
158-
browser = p.firefox.launch(headless=HEADLESS)
236+
browser = p.firefox.launch(headless=HEADLESS, args=LAUNCH_ARGS)
159237
elif BROWSER == "webkit":
160-
browser = p.webkit.launch(headless=HEADLESS)
238+
browser = p.webkit.launch(headless=HEADLESS, args=LAUNCH_ARGS)
161239
else:
162-
browser = p.chromium.launch(headless=HEADLESS)
240+
browser = p.chromium.launch(headless=HEADLESS, args=LAUNCH_ARGS)
163241

164242
# Cookies vorbereiten
165243
if os.path.exists(COOKIE_FILE):
@@ -250,43 +328,8 @@ def login_erfolgreich(p):
250328
logging.info("Cookies werden erneuert.")
251329
context.storage_state(path=COOKIE_FILE)
252330

253-
# Weiter mit Datenvolumen-Logik
254-
logging.info("Lese Datenvolumen aus...")
255-
256-
257-
GB_selectors = [
258-
'one-stack.usage-meter:nth-child(1) > one-usage-meter:nth-child(1) > one-group:nth-child(1) > one-heading:nth-child(2)',
259-
'one-stack.usage-meter:nth-child(1) > one-stack:nth-child(1) > one-usage-meter:nth-child(1) > one-group:nth-child(1) > one-heading:nth-child(2)'
260-
]
261-
262-
GB_text_raw = None
263-
for sel in GB_selectors:
264-
try:
265-
element = page.query_selector(sel)
266-
if element:
267-
GB_text_raw = element.text_content()
268-
if GB_text_raw:
269-
break
270-
except Exception as e:
271-
logging.warning(f"Selector {sel} nicht verfügbar: {e}")
272-
continue
273-
274-
if not GB_text_raw:
275-
raise Exception("Konnte das Datenvolumen nicht auslesen - kein gültiger Selector gefunden.")
276-
277-
match = re.search(r"([\d\.,]+)\s?(GB|MB)", GB_text_raw)
278-
if not match:
279-
raise ValueError(f"Unerwartetes Format beim Datenvolumen: {GB_text_raw}")
280-
281-
value, unit = match.groups()
282-
value = value.replace(",", ".")
283-
284-
if unit == "MB":
285-
GB = float(value) / 1024
286-
else:
287-
GB = float(value)
288-
289-
LAST_GB = GB
331+
GB = get_datenvolumen(page)
332+
GB = LAST_GB
290333

291334
try:
292335
with open("state.json", "w") as f:
@@ -300,7 +343,7 @@ def login_erfolgreich(p):
300343
if GB < 1.0:
301344
logging.info("Versuche, 1 GB Datenvolumen nachzubuchen...")
302345
if wait_and_click(page, 'one-button[slot="action"]'):
303-
message = f"{RUFNUMMER}: Aktuelles Datenvolumen: {GB:.2f} GB - 1 GB wurde erfolgreich nachgebucht. "
346+
message = f"{RUFNUMMER}: Aktuelles Datenvolumen: {GB:.2f} GB - 1 GB wurde erfolgreich nachgebucht. 📲"
304347
else:
305348
raise Exception("❌ Konnte den Nachbuchungsbutton nicht klicken!")
306349

@@ -325,8 +368,9 @@ def login_erfolgreich(p):
325368
send_telegram_message(f"{RUFNUMMER}: ❌ Fehler beim Abrufen des Datenvolumens: {e}")
326369

327370
finally:
328-
browser.close()
329-
logging.info("Browser geschlossen.")
371+
if browser:
372+
browser.close()
373+
logging.info("Browser geschlossen.")
330374

331375
time.sleep(2)
332376
logging.error("Skript hat nach 3 Versuchen aufgegeben.")
@@ -373,6 +417,7 @@ def get_interval(config):
373417
else:
374418
return random.randint(300, 500)
375419

420+
376421
if __name__ == "__main__":
377422
while True:
378423
check_for_update()

0 commit comments

Comments
 (0)