Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import threading | |
| import time | |
| import schedule | |
| import random | |
| import datetime | |
| from playwright.sync_api import sync_playwright | |
| # ββ Streamlit UI Page Config ββ | |
| # Must be the first Streamlit command called on the page | |
| st.set_page_config(page_title="Keep-Alive Console", page_icon="π", layout="wide") | |
| TARGET_URL = "https://streamer1-hsd7neqlzku825vdo6rtkz.streamlit.app/" | |
| # ββ Shared log list (thread-safe for appends in CPython) ββ | |
| logs = ["π System initialized β service startingβ¦"] | |
| def add_log(msg): | |
| ts = datetime.datetime.now().strftime("%H:%M:%S") | |
| entry = f"[{ts}] {msg}" | |
| print(entry) | |
| logs.append(entry) | |
| if len(logs) > 50: | |
| logs.pop(0) | |
| # ββ Keep-alive routine ββ | |
| def visit_and_scroll(): | |
| add_log(f"Opening {TARGET_URL}") | |
| try: | |
| with sync_playwright() as p: | |
| browser = p.chromium.launch( | |
| headless=True, | |
| args=["--no-sandbox", "--disable-dev-shm-usage", "--disable-gpu"], | |
| ) | |
| try: | |
| page = browser.new_page( | |
| user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) " | |
| "AppleWebKit/537.36 (KHTML, like Gecko) " | |
| "Chrome/120.0.0.0 Safari/537.36" | |
| ) | |
| page.goto(TARGET_URL, wait_until="networkidle", timeout=60_000) | |
| add_log("Page loaded β waiting 10 s for hydrationβ¦") | |
| time.sleep(10) | |
| for i in range(1, 6): | |
| y = i * 800 | |
| page.evaluate(f"window.scrollTo(0, {y});") | |
| add_log(f"Scrolled to {y}px") | |
| time.sleep(random.uniform(1.5, 3.0)) | |
| page.evaluate("window.scrollTo(0, 0);") | |
| add_log("Visit completed successfully β ") | |
| finally: | |
| browser.close() | |
| except Exception as e: | |
| add_log(f"ERROR: {e}") | |
| # ββ Background scheduler (one thread, runs forever) ββ | |
| def _loop(): | |
| visit_and_scroll() | |
| schedule.every(10).minutes.do(visit_and_scroll) | |
| while True: | |
| schedule.run_pending() | |
| time.sleep(10) # check for scheduled tasks more frequently | |
| # Guard: start the thread only once per Streamlit process using cache_resource | |
| def start_scheduler(): | |
| thread = threading.Thread(target=_loop, daemon=True) | |
| thread.start() | |
| return thread | |
| start_scheduler() | |
| # ββ Streamlit UI layout ββ | |
| st.title("π€ Keep-Alive Cloud Console") | |
| st.caption(f"Target: **{TARGET_URL}** β’ Frequency: every 10 minutes") | |
| st.divider() | |
| # Fragment for non-blocking UI logs refresh if supported (Streamlit >= 1.33) | |
| if hasattr(st, "fragment"): | |
| def display_logs_fragment(): | |
| st.text_area("Logs (newest first)", "\n".join(reversed(logs)), height=400, disabled=True) | |
| else: | |
| def display_logs_fragment(): | |
| st.text_area("Logs (newest first)", "\n".join(reversed(logs)), height=400, disabled=True) | |
| c1, c2 = st.columns([3, 1]) | |
| with c1: | |
| st.subheader("Activity Log") | |
| display_logs_fragment() | |
| with c2: | |
| st.subheader("Controls") | |
| if st.button("π Push Now"): | |
| with st.spinner("Visitingβ¦"): | |
| visit_and_scroll() | |
| st.success("Done!") | |
| st.rerun() # Force rerun to refresh logs immediately on manual push | |
| st.info("Background scheduler is active.") | |
| # Page level auto-refresh fallback for older Streamlit versions (< 1.33) | |
| if not hasattr(st, "fragment"): | |
| time.sleep(30) | |
| st.rerun() | |