Last active
June 27, 2023 13:54
-
-
Save MolarFox/dd76fa677340fc5948db698c6c8b88f5 to your computer and use it in GitHub Desktop.
Simple website watcher cobbled together in an hour
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/python3 | |
| # MolarFox 2023 | |
| import re | |
| import tkinter as tk | |
| from tkinter.scrolledtext import ScrolledText | |
| import hashlib | |
| import urllib3 | |
| import datetime as dt | |
| from collections import namedtuple | |
| DEFAULT_WAIT = 5000 # Default wait, milliseconds | |
| DEFAULT_URL = "https://taylorswift.ticketek.com.au/" | |
| http = urllib3.PoolManager() | |
| ProgramState = namedtuple( | |
| "ProgramState", | |
| ["next_check", "last_hash", "wait_time_millis", "url", "event_log"] | |
| ) | |
| def get_and_hash(state: ProgramState) -> str: | |
| resp = http.request("GET", state.url.get()) | |
| curr_time = dt.datetime.now().strftime("%H:%M:%S") | |
| state.event_log.insert( | |
| tk.END, | |
| f"{curr_time}: Sent request, response ({resp.status})\n" | |
| ) | |
| if not 200 <= resp.status <= 300: | |
| state.event_log.insert( | |
| tk.END, | |
| f"{curr_time}: Failed response message: {resp.data}\n" | |
| ) | |
| # raise ValueError({ | |
| # "message": "Website returned an unsuccessful response code", | |
| # "code": resp.status, | |
| # "response": resp.data | |
| # }) | |
| return hashlib.md5( | |
| re.sub(b'<script>.*</script>', b"", resp.data, flags=re.DOTALL) | |
| ).hexdigest() | |
| # Window | |
| window = tk.Tk() | |
| window.title("Website watcher") | |
| window.geometry('580x300') | |
| # Program statevars | |
| state = ProgramState( | |
| next_check=[dt.datetime.now() + dt.timedelta(milliseconds=DEFAULT_WAIT)], | |
| last_hash=tk.StringVar(), | |
| wait_time_millis=tk.IntVar(), | |
| url=tk.StringVar(), | |
| event_log=ScrolledText(window, height=12), | |
| ) | |
| state.wait_time_millis.set(DEFAULT_WAIT) | |
| state.url.set(DEFAULT_URL) | |
| state.last_hash.set(get_and_hash(state)) | |
| # Window elements | |
| tk.Label( | |
| window, | |
| text="URL: ", | |
| justify=tk.RIGHT, | |
| ).grid(column=0, row=0) | |
| tk.Entry( | |
| window, | |
| width=30, | |
| textvariable=state.url, | |
| ).grid(column=1, row=0) | |
| tk.Label( | |
| window, | |
| text="Delay (ms): ", | |
| justify=tk.RIGHT, | |
| ).grid(column=0, row=1) | |
| tk.Entry( | |
| window, | |
| width=30, | |
| textvariable=state.wait_time_millis, | |
| ).grid(column=1, row=1) | |
| state.event_log.grid(row=2, columnspan=2) | |
| # Mainloop | |
| while True: | |
| if dt.datetime.now() > state.next_check[0]: | |
| new_hash = get_and_hash(state) | |
| if new_hash != state.last_hash.get(): | |
| window.focus_force() | |
| window.title("WEBSITE CHANGED!!") | |
| window.bell() | |
| state.event_log.insert( | |
| tk.END, | |
| f"-- WEBSITE HAS CHANGED --\n" | |
| ) | |
| state.last_hash.set(new_hash) | |
| state.next_check[0] = dt.datetime.now() + dt.timedelta(milliseconds=state.wait_time_millis.get()) | |
| window.update_idletasks() | |
| window.update() | |
| try: | |
| if not window.winfo_exists(): break | |
| except tk.TclError: | |
| break |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment