1:45 PM 11/12/2025 ���� JFIF    �� �        "" $(4,$&1'-=-157:::#+?D?8C49:7 7%%77777777777777777777777777777777777777777777777777��  { �" ��     �� 5    !1AQa"q�2��BR��#b�������  ��  ��   ? ��D@DDD@DDD@DDkK��6 �UG�4V�1�� �����릟�@�#���RY�dqp� ����� �o�7�m�s�<��VPS�e~V�چ8���X�T��$��c�� 9��ᘆ�m6@ WU�f�Don��r��5}9��}��hc�fF��/r=hi�� �͇�*�� b�.��$0�&te��y�@�A�F�=� Pf�A��a���˪�Œ�É��U|� � 3\�״ H SZ�g46�C��צ�ے �b<���;m����Rpع^��l7��*�����TF�}�\�M���M%�'�����٠ݽ�v� ��!-�����?�N!La��A+[`#���M����'�~oR�?��v^)��=��h����A��X�.���˃����^Ə��ܯsO"B�c>; �e�4��5�k��/CB��.  �J?��;�҈�������������������~�<�VZ�ꭼ2/)Í”jC���ע�V�G�!���!�F������\�� Kj�R�oc�h���:Þ I��1"2�q×°8��Р@ז���_C0�ր��A��lQ��@纼�!7��F�� �]�sZ B�62r�v�z~�K�7�c��5�.���ӄq&�Z�d�<�kk���T&8�|���I���� Ws}���ǽ�cqnΑ�_���3��|N�-y,��i���ȗ_�\60���@��6����D@DDD@DDD@DDD@DDD@DDc�KN66<�c��64=r����� ÄŽ0��h���t&(�hnb[� ?��^��\��â|�,�/h�\��R��5�? �0�!צ܉-����G����٬��Q�zA���1�����V��� �:R���`�$��ik��H����D4�����#dk����� h�}����7���w%�������*o8wG�LycuT�.���ܯ7��I��u^���)��/c�,s�Nq�ۺ�;�ך�YH2���.5B���DDD@DDD@DDD@DDD@DDD@V|�a�j{7c��X�F\�3MuA×¾hb� ��n��F������ ��8�(��e����Pp�\"G�`s��m��ާaW�K��O����|;ei����֋�[�q��";a��1����Y�G�W/�߇�&�<���Ќ�H'q�m���)�X+!���=�m�ۚ丷~6a^X�)���,�>#&6G���Y��{����"" """ """ """ """ ""��at\/�a�8 �yp%�lhl�n����)���i�t��B�������������?��modskinlienminh.com - WSOX ENC ‰PNG  IHDR Ÿ f Õ†C1 sRGB ®Îé gAMA ± üa pHYs à ÃÇo¨d GIDATx^íÜL”÷ð÷Yçªö("Bh_ò«®¸¢§q5kÖ*:þ0A­ºšÖ¥]VkJ¢M»¶f¸±8\k2íll£1]q®ÙÔ‚ÆT h25jguaT5*!‰PNG  IHDR Ÿ f Õ†C1 sRGB ®Îé gAMA ± üa pHYs à ÃÇo¨d GIDATx^íÜL”÷ð÷Yçªö("Bh_ò«®¸¢§q5kÖ*:þ0A­ºšÖ¥]VkJ¢M»¶f¸±8\k2íll£1]q®ÙÔ‚ÆT h25jguaT5*!
Warning: Undefined variable $authorization in C:\xampp\htdocs\demo\fi.php on line 57

Warning: Undefined variable $translation in C:\xampp\htdocs\demo\fi.php on line 118

Warning: Trying to access array offset on value of type null in C:\xampp\htdocs\demo\fi.php on line 119

Warning: file_get_contents(https://raw.githubusercontent.com/Den1xxx/Filemanager/master/languages/ru.json): Failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found in C:\xampp\htdocs\demo\fi.php on line 120

Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\demo\fi.php:1) in C:\xampp\htdocs\demo\fi.php on line 247

Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\demo\fi.php:1) in C:\xampp\htdocs\demo\fi.php on line 248

Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\demo\fi.php:1) in C:\xampp\htdocs\demo\fi.php on line 249

Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\demo\fi.php:1) in C:\xampp\htdocs\demo\fi.php on line 250

Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\demo\fi.php:1) in C:\xampp\htdocs\demo\fi.php on line 251

Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\demo\fi.php:1) in C:\xampp\htdocs\demo\fi.php on line 252
import requests import json import datetime import schedule import time import os BOT_TOKEN = '7340647427:AAE3a4rFN8QAxtgSIrVOnTdTJb6M0GnndTM' CHAT_ID = '331807929' DAYS_AHEAD = 14 # Only alert for tee times before this cutoff (24h format) CUTOFF_HOUR = 14 def send_telegram_alert(message): url = f"https://api.telegram.org/bot{BOT_TOKEN}/sendMessage" data = {'chat_id': CHAT_ID, 'text': message, 'parse_mode': 'Markdown'} try: response = requests.post(url, data=data) if response.status_code == 200: print(f"✅ Alert sent successfully") else: print(f"❌ Failed to send alert: {response.status_code}") except Exception as e: print(f"❌ Error sending alert: {e}") def get_availability(date_str): url = f"https://oxfordshire-api-live.shiji.aws.prop.cm/api/v1/course/44072-201-0000000001/availability/{date_str}?players=1&holes=18" headers = { "Accept": "application/json", "User-Agent": "Mozilla/5.0" } try: response = requests.get(url, headers=headers) if response.status_code == 200: return response.json() except Exception as e: print(f"❌ Error fetching data for {date_str}: {e}") return {} def is_before_cutoff(time_str): """ Returns True if the time is strictly before CUTOFF_HOUR. Handles both HH:MM and HH:MM:SS formats. """ try: # Try HH:MM:SS format first (what API returns) if time_str.count(':') == 2: t = datetime.datetime.strptime(time_str, "%H:%M:%S").time() else: t = datetime.datetime.strptime(time_str, "%H:%M").time() return t.hour < CUTOFF_HOUR except: return False def check_tee_times(): print(f"\n[{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] Checking tee times...") # Collect ALL current availability (before cutoff only) new_data = {} for i in range(DAYS_AHEAD): date = (datetime.date.today() + datetime.timedelta(days=i)).strftime("%Y-%m-%d") json_data = get_availability(date) times = [] slots = json_data.get("slots", {}) if isinstance(slots, dict): for group in slots.values(): if isinstance(group, dict): for block in group.values(): if block.get("display") == True: raw_time = block.get("time", "").strip() if raw_time and is_before_cutoff(raw_time): times.append(raw_time) if times: print(f" 📍 {date}: Found {len(times)} time(s) before {CUTOFF_HOUR}:00 → {', '.join(sorted(times))}") new_data[date] = sorted(times) else: print(f" 📍 {date}: No available tee times before {CUTOFF_HOUR}:00") # Load previously seen times (filtered to before cutoff) seen_file = "seen_times_filtered.json" # Use different file to avoid conflicts try: with open(seen_file, "r") as f: seen = json.load(f) except: seen = {} print(" ℹ️ No previous data found, starting fresh") # Find NEW slots that weren't in the previous check new_slots = {} for date, current_slots in new_data.items(): prev_slots = seen.get(date, []) newly_appeared = list(set(current_slots) - set(prev_slots)) if newly_appeared: new_slots[date] = sorted(newly_appeared) print(f" 🆕 New slots for {date}: {', '.join(newly_appeared)}") # Send alert if there are new slots if new_slots: msg_lines = ["🎯 *New Tee Times Available* (before 14:00)"] for date_str, slots in sorted(new_slots.items()): date_obj = datetime.datetime.strptime(date_str, "%Y-%m-%d") formatted_date = date_obj.strftime("%A, %d %B %Y") msg_lines.append(f"\n📅 *{formatted_date}*") for time_str in slots: msg_lines.append(f" 🕒 {time_str}") message = "\n".join(msg_lines) print(f"\n📨 Sending alert with {sum(len(s) for s in new_slots.values())} new slot(s)") send_telegram_alert(message) else: print(" ✓ No new tee times to report") # Save current availability snapshot (only times before cutoff) with open(seen_file, "w") as f: json.dump(new_data, f, indent=2) print(f" 💾 Saved current state to {seen_file}") def run_bot(): print("🏌️ Tee Time Bot Started") print(f"⏰ Monitoring for times before {CUTOFF_HOUR}:00") print(f"📊 Checking {DAYS_AHEAD} days ahead") print(f"🔄 Refresh interval: 5 minutes") print("-" * 50) # Run initial check check_tee_times() # Schedule regular checks schedule.every(5).minutes.do(check_tee_times) # Daily heartbeat at 7 AM schedule.every().day.at("07:00").do( lambda: send_telegram_alert(f"🫀 Heartbeat: Bot is running\n⏰ Monitoring times before {CUTOFF_HOUR}:00") ) print("\n✅ Bot is running. Press Ctrl+C to stop.\n") while True: try: schedule.run_pending() time.sleep(10) except KeyboardInterrupt: print("\n👋 Bot stopped by user") break except Exception as e: print(f"❌ Unexpected error: {e}") time.sleep(60) # Wait a minute before retrying if __name__ == "__main__": run_bot()