diff --git a/requirements.txt b/requirements.txt
index 64851aa..6c0779b 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,3 +1,5 @@
python>=3.6
requests>=2.25.1
-sqlite3
+plyer>=2.0
+win10toast>=0.9
+keyring>=23.0.0 # optional; remove if you don't implement keyring
diff --git a/setup.md b/setup.md
index 63947d1..21e204e 100644
--- a/setup.md
+++ b/setup.md
@@ -1,5 +1,14 @@
-# Kindly go through the steps to locally setup the script on your device.
+# WiFi Auto-Auth Setup Guide with Notification System
___
+
+## ๐ New Features: Desktop Notifications
+The script now includes a cross-platform notification system that alerts you about:
+- โ
Successful login attempts
+- โ Failed login attempts
+- ๐ Network connectivity issues
+- ๐ Already logged in status
+- โฑ๏ธ Connection timeouts
+
## 1. Install Dependencies
Run the following command to install the requirements:
@@ -7,92 +16,284 @@ Run the following command to install the requirements:
```bash
pip install -r requirements.txt
```
-## 2. Find Your Network's Login URL and Payload
-```
-2.1 Connect to your WiFi network manually.
-2.2 Open the login page in a browser (http://192.168.x.x:8090/httpclient.html).
-2.3 Inspect the login form (Right-click โ Inspect โ Network Tab).
-2.4 Find the POST request URL inside the Network tab(should look like http://192.168.x.x:8090/login.xml).
-2.5 Copy the form data parameters (like username, password, a, etc.).
+
+### Platform-specific notification setup:
+
+#### **Linux:**
+- Install `libnotify` if not present:
+ ```bash
+ sudo apt-get install libnotify-bin # Debian/Ubuntu
+ sudo dnf install libnotify # Fedora
+ sudo pacman -S libnotify # Arch
+ ```
+
+#### **Windows:**
+- Notifications work out of the box with Windows 10/11
+- For better support, install: `pip install win10toast`
+
+#### **macOS:**
+- Notifications use native macOS notification center
+- No additional setup required
+
+## 2. Configure Your Network Settings
+
+The script now uses a JSON configuration file located at:
+- **Linux/Mac:** `~/.wifi_auto_auth_config.json`
+- **Windows:** `C:\Users\YourUsername\.wifi_auto_auth_config.json`
+
+### 2.1 First Run
+On first run, the script will create a default configuration file. Edit this file with your network details.
+
+### 2.2 Find Your Network's Login URL and Payload
```
-## 3. Edit ```wifi_auto_login.py``` file
-Modify the ```def wifi_login()``` function to match your payload parameters.
-i.e:
+1. Connect to your WiFi network manually
+2. Open the login page in a browser (typically http://192.168.x.x:8090/httpclient.html)
+3. Open Developer Tools (F12) โ Network Tab
+4. Log in manually and find the POST request (usually to /login.xml)
+5. Copy the request URL and form data parameters
```
+
+### 2.3 Edit the Configuration File
+
+Example configuration:
+```json
{
"login_url": "http://192.168.100.1:8090/login.xml",
- "username": "your_username",
- "password": "your_password",
+ "username": "your_actual_username",
+ "password": "your_actual_password",
"payload_params": {
"mode": "191",
- "username": "your_username",
- "password": "your_password",
+ "username": "your_actual_username",
+ "password": "your_actual_password",
"a": "dynamic",
"producttype": "0"
},
- "db_name": "wifi_log.db"
+ "notifications": {
+ "enabled": true,
+ "sound": true,
+ "on_success": true,
+ "on_failure": true,
+ "on_network_error": true,
+ "on_already_logged_in": true
+ },
+ "db_name": "wifi_log.db",
+ "retry_attempts": 3,
+ "retry_delay": 5
}
```
-Note: a โ Keep "dynamic" if the value changes on every login attempt.
-## 4. Run the Script
-Run the Python script to log in automatically:
-```
+### Configuration Options:
+
+| Option | Description | Values |
+|--------|-------------|--------|
+| `login_url` | Your WiFi portal login URL | String |
+| `username` | Your WiFi username | String |
+| `password` | Your WiFi password | String |
+| `payload_params.a` | Session parameter | "dynamic" or static value |
+| `notifications.enabled` | Enable/disable all notifications | true/false |
+| `notifications.sound` | Play sound with notifications | true/false |
+| `notifications.on_success` | Notify on successful login | true/false |
+| `notifications.on_failure` | Notify on failed login | true/false |
+| `notifications.on_network_error` | Notify on network issues | true/false |
+| `notifications.on_already_logged_in` | Notify if already connected | true/false |
+| `retry_attempts` | Number of retry attempts | Integer (1-10) |
+| `retry_delay` | Delay between retries (seconds) | Integer |
+
+## 3. Test the Script
+
+Run the script manually to test:
+```bash
python wifi_auto_login.py
```
-## 5. Automate WiFi Login on System Boot:
+You should see:
+1. Console output showing the login attempt
+2. A desktop notification with the result
+3. Recent login history
-#### **๐น Windows (Task Scheduler)**
-5.1. Open **Task Scheduler** โ **Create Basic Task**.
-5.2. Set **Trigger** โ **At Startup**.
-5.3. Set **Action** โ **Start a Program** โ Browse for `python.exe`.
-5.4. In **Arguments**, enter:
- ```text
- "C:\path\to\wifi_auto_login.py"
- ```
-5.5. Save and enable the task.
+## 4. Test Notifications
----
-#### **๐น Linux (Crontab)**
-5.1. Open terminal and run:
+To test if notifications are working on your system:
+```bash
+python -c "from plyer import notification; notification.notify(title='Test', message='Notifications working!')"
+```
+
+## 5. Automate WiFi Login on System Boot
+
+### ๐น Windows (Task Scheduler)
+1. Open **Task Scheduler** โ **Create Basic Task**
+2. Name: "WiFi Auto Login"
+3. Trigger: **At Startup**
+4. Action: **Start a Program**
+5. Program: `python.exe` or `pythonw.exe` (for no console window)
+6. Arguments: `"C:\path\to\wifi_auto_login.py"`
+7. Start in: `"C:\path\to\"` (directory containing the script)
+8. Check "Run with highest privileges"
+
+### ๐น Linux (Systemd Service - Recommended)
+1. Create a service file:
```bash
- crontab -e
+ sudo nano /etc/systemd/system/wifi-auto-login.service
+ ```
+
+2. Add content:
+ ```ini
+ [Unit]
+ Description=WiFi Auto Login Service
+ After=network-online.target
+ Wants=network-online.target
+
+ [Service]
+ Type=oneshot
+ User=your_username
+ ExecStartPre=/bin/sleep 10
+ ExecStart=/usr/bin/python3 /path/to/wifi_auto_login.py
+ RemainAfterExit=yes
+
+ [Install]
+ WantedBy=multi-user.target
```
-5.2. Add this line at the end:
+
+3. Enable the service:
```bash
- @reboot python3 /path/to/wifi_auto_login.py
+ sudo systemctl daemon-reload
+ sudo systemctl enable wifi-auto-login.service
+ sudo systemctl start wifi-auto-login.service
```
-5.3. Save and exit.
----
-#### **๐น macOS (Launch Agents)**
-5.1. Create a `.plist` file in `~/Library/LaunchAgents/`:
+### ๐น Linux (Crontab - Alternative)
+```bash
+crontab -e
+# Add this line:
+@reboot sleep 30 && /usr/bin/python3 /path/to/wifi_auto_login.py
+```
+
+### ๐น macOS (Launch Agent)
+1. Create plist file:
```bash
- nano ~/Library/LaunchAgents/wifi_auto_login.plist
+ nano ~/Library/LaunchAgents/com.wifi.autologin.plist
```
-5.2. Add this content:
+
+2. Add content:
```xml
-
+
-
+
Label
- wifi_auto_login
+ com.wifi.autologin
ProgramArguments
- /usr/bin/python3
- /path/to/wifi_auto_login.py
+ /usr/bin/python3
+ /path/to/wifi_auto_login.py
RunAtLoad
-
+ StartInterval
+ 300
+ StandardOutPath
+ /tmp/wifi-auto-login.log
+ StandardErrorPath
+ /tmp/wifi-auto-login-error.log
+
```
-5.3. Save and enable it:
+
+3. Load the agent:
```bash
- launchctl load ~/Library/LaunchAgents/wifi_auto_login.plist
+ launchctl load ~/Library/LaunchAgents/com.wifi.autologin.plist
```
-We have succesfully setup the script now the wifi or LAN will get connected **automatically on system startup**!
+## 6. View Logs and Statistics
+
+The script maintains a SQLite database with all login attempts. To view logs:
+
+```python
+# View last 10 login attempts
+python -c "from wifi_auto_login import view_logs; view_logs(10)"
+```
+
+## 7. Troubleshooting
+
+### Notifications not working?
+
+1. **Linux:** Ensure `notify-send` is installed
+2. **Windows:** Try running as administrator
+3. **macOS:** Check System Preferences โ Notifications โ Python
+4. **All platforms:** Test with the test command in step 4
+
+### Script not running at startup?
+
+1. Check system logs:
+ - **Linux:** `journalctl -u wifi-auto-login.service`
+ - **Windows:** Event Viewer โ Windows Logs โ System
+ - **macOS:** `Console.app` โ system.log
+
+2. Add a delay before execution (network might not be ready)
+
+### Can't find login URL?
+
+1. Try common patterns:
+ - `http://192.168.1.1:8090/login.xml`
+ - `http://192.168.0.1:8090/httpclient.html`
+ - `http://10.0.0.1/login`
+
+2. Check browser's network tab while logging in manually
+
+## 8. Security Notes
+
+- Configuration file contains credentials - keep it secure!
+- Set appropriate file permissions:
+ ```bash
+ chmod 600 ~/.wifi_auto_auth_config.json # Linux/Mac
+ ```
+- Passwords are masked in logs
+- Consider using environment variables for sensitive data
+- The SQLite database is stored locally and logs are auto-cleaned after 30 days
+
+## 9. Customization
+
+### Custom Notification Icons
+Place an icon file (`.png` or `.ico`) in the script directory and update the code:
+```python
+notification.notify(
+ title=title,
+ message=message,
+ app_icon="path/to/icon.png", # Add your icon path
+ timeout=10
+)
+```
+
+### Notification Sounds
+Customize notification sounds by modifying the platform-specific functions in the `NotificationHandler` class.
+
+## 10. Uninstall
+
+To remove the auto-login service:
+
+**Windows:**
+- Delete the Task Scheduler task
+
+**Linux (systemd):**
+```bash
+sudo systemctl stop wifi-auto-login.service
+sudo systemctl disable wifi-auto-login.service
+sudo rm /etc/systemd/system/wifi-auto-login.service
+```
+
+**macOS:**
+```bash
+launchctl unload ~/Library/LaunchAgents/com.wifi.autologin.plist
+rm ~/Library/LaunchAgents/com.wifi.autologin.plist
+```
+
+## Need Help?
+
+- Check the logs: Script creates detailed logs in `wifi_log.db`
+- Enable debug mode by adding verbose output in the script
+- Open an issue on GitHub with your log output (remove sensitive data!)
+
+---
+Successfully set up! Your WiFi will now connect automatically with desktop notifications! ๐
\ No newline at end of file
diff --git a/wifi_auto_login.py b/wifi_auto_login.py
index c2a4153..25179d3 100644
--- a/wifi_auto_login.py
+++ b/wifi_auto_login.py
@@ -2,10 +2,164 @@
import requests
import datetime
import re
+import json
+import os
+import time
+import platform
+import subprocess
+import sys
+import argparse
+from pathlib import Path
+from urllib.parse import urlparse
-# Database setup
+# Try to import plyer for notifications, fallback to native solutions if not available
+try:
+ from plyer import notification
+ PLYER_AVAILABLE = True
+except Exception:
+ PLYER_AVAILABLE = False
+
+# Optional Windows toast library (used only in windows fallback)
+try:
+ import win10toast
+ WIN10TOAST_AVAILABLE = True
+except Exception:
+ WIN10TOAST_AVAILABLE = False
+
+# Configuration file path
+CONFIG_FILE = Path.home() / ".wifi_auto_auth_config.json"
DB_NAME = "wifi_log.db"
+class NotificationHandler:
+ """Cross-platform notification handler"""
+
+ def __init__(self, enabled=True, sound=True):
+ self.enabled = enabled
+ self.sound = sound
+ self.system = platform.system() # always available now
+
+ def send(self, title, message, urgency="normal"):
+ """Send a desktop notification"""
+ if not self.enabled:
+ return
+
+ try:
+ if PLYER_AVAILABLE:
+ notification.notify(
+ title=title,
+ message=message,
+ app_icon=None,
+ timeout=10,
+ )
+ return
+ # Fallback if plyer not available
+ if self.system == "Linux":
+ self._linux_notify(title, message, urgency)
+ elif self.system == "Darwin":
+ self._macos_notify(title, message)
+ elif self.system == "Windows":
+ self._windows_notify(title, message)
+ else:
+ print(f"๐ {title}: {message}")
+ except Exception as e:
+ print(f"Notification failed: {e}")
+ print(f"๐ {title}: {message}")
+
+ def _linux_notify(self, title, message, urgency):
+ """Linux notification using notify-send"""
+ cmd = ["notify-send", title, message, f"--urgency={urgency}"]
+ # note: notify-send doesn't have a cross-distro 'sound' flag; you can play a sound separately if needed
+ try:
+ subprocess.run(cmd, check=False)
+ except FileNotFoundError:
+ print(f"notify-send not found; fallback to console -> {title}: {message}")
+
+ def _macos_notify(self, title, message):
+ """macOS notification using osascript"""
+ # Escape double-quotes in message/title
+ safe_title = title.replace('"', '\\"')
+ safe_message = message.replace('"', '\\"')
+ script = f'display notification "{safe_message}" with title "{safe_title}"'
+ subprocess.run(["osascript", "-e", script], check=False)
+
+ def _windows_notify(self, title, message):
+ """Windows notification using win10toast or powershell fallback"""
+ # Prefer win10toast if installed
+ try:
+ if WIN10TOAST_AVAILABLE:
+ from win10toast import ToastNotifier
+ toaster = ToastNotifier()
+ toaster.show_toast(title, message, duration=10, threaded=True)
+ else:
+ # Use PowerShell balloon as fallback - escape single quotes
+ safe_title = title.replace("'", "''")
+ safe_message = message.replace("'", "''")
+ ps_script = f"""
+ $app = New-Object -ComObject WScript.Shell
+ $app.Popup('{safe_message}', 10, '{safe_title}', 64)
+ """
+ subprocess.run(["powershell", "-NoProfile", "-Command", ps_script], check=False)
+ except Exception:
+ print(f"Windows notification fallback -> {title}: {message}")
+
+def _deep_update(dst, src):
+ """Deep merge src dict into dst dict"""
+ for k, v in src.items():
+ if isinstance(v, dict) and isinstance(dst.get(k), dict):
+ _deep_update(dst[k], v)
+ else:
+ dst[k] = v
+
+class Config:
+ """Configuration manager for the WiFi auto-login script"""
+
+ @staticmethod
+ def load():
+ """Load configuration from file"""
+ default_config = {
+ "login_url": "http://192.168.100.1:8090/login.xml",
+ "username": "your_username",
+ "password": "your_password",
+ "payload_params": {
+ "mode": "191",
+ "username": "your_username",
+ "password": "your_password",
+ "a": "dynamic",
+ "producttype": "0"
+ },
+ "notifications": {
+ "enabled": True,
+ "sound": True,
+ "on_success": True,
+ "on_failure": True,
+ "on_network_error": True,
+ "on_already_logged_in": True
+ },
+ "db_name": DB_NAME,
+ "retry_attempts": 3,
+ "retry_delay": 5
+ }
+
+ if CONFIG_FILE.exists():
+ try:
+ with open(CONFIG_FILE, 'r') as f:
+ user_config = json.load(f)
+ _deep_update(default_config, user_config)
+ except json.JSONDecodeError:
+ print("โ ๏ธ Invalid config file, using defaults")
+ else:
+ Config.save(default_config)
+ print(f"๐ Created default config at: {CONFIG_FILE}")
+ print("Please edit this file with your WiFi credentials!")
+
+ return default_config
+
+ @staticmethod
+ def save(config):
+ """Save configuration to file"""
+ with open(CONFIG_FILE, 'w') as f:
+ json.dump(config, f, indent=4)
+
def setup_database():
"""Create the database and table if they do not exist."""
conn = sqlite3.connect(DB_NAME)
@@ -18,94 +172,299 @@ def setup_database():
password TEXT,
a TEXT,
response_status TEXT,
- response_message TEXT
+ response_message TEXT,
+ notification_sent INTEGER DEFAULT 0
)
""")
conn.commit()
conn.close()
-def log_attempt(username, password, a, response_status, response_message):
+def log_attempt(username, password, a, response_status, response_message, notification_sent=False):
"""Log each login attempt in the database."""
+ ts = datetime.datetime.now().isoformat(sep=' ', timespec='seconds')
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
cursor.execute("""
- INSERT INTO login_attempts (timestamp, username, password, a, response_status, response_message)
- VALUES (?, ?, ?, ?, ?, ?)
- """, (datetime.datetime.now(), username, "******", a, response_status, response_message))
+ INSERT INTO login_attempts (timestamp, username, password, a, response_status, response_message, notification_sent)
+ VALUES (?, ?, ?, ?, ?, ?, ?)
+ """, (ts, username, "******", a, str(response_status), response_message, int(bool(notification_sent))))
conn.commit()
conn.close()
def extract_message(response_text):
- """Extracts the meaningful message from the XML response."""
- match = re.search(r"", response_text)
- return match.group(1) if match else "Unknown response"
+ """Extracts the meaningful message from the XML response (best-effort)."""
+ # Try common CDATA
+ match = re.search(r"\s*\s*", response_text, re.DOTALL | re.IGNORECASE)
+ if match:
+ return match.group(1).strip()
+ # Try plain tag
+ match2 = re.search(r"(.*?)", response_text, re.DOTALL | re.IGNORECASE)
+ if match2:
+ return match2.group(1).strip()
+ # Try tag variant
+ match3 = re.search(r"(.*?)", response_text, re.DOTALL | re.IGNORECASE)
+ if match3:
+ return match3.group(1).strip()
+ # fallback to first 300 chars of plain text
+ return re.sub(r"\s+", " ", response_text).strip()[:300] or "No response"
-def wifi_login():
- """Perform the WiFi login request and log the result."""
- url = "POST url from the inspect element" # Change Required
- username = "username"
- password = "password"
- a_value = str(int(datetime.datetime.now().timestamp())) # Generate dynamic 'a' value, you may refer to the screenshots in the setup.md file
-
- payload = {
- "mode": "191",
- "username": username,
- "password": password,
- "a": a_value,
- "producttype": "0"
- }
+def check_connectivity(url):
+ """Check if the network/login portal is reachable"""
+ try:
+ parsed = urlparse(url if '://' in url else 'http://' + url)
+ base_url = f"{parsed.scheme}://{parsed.netloc}"
+ response = requests.get(base_url, timeout=5)
+ return True
+ except requests.exceptions.RequestException:
+ return False
+ except Exception:
+ return False
+def wifi_login(config, notifier):
+ """Perform the WiFi login request and log the result."""
+ url = config["login_url"]
+ username = config["username"]
+ password = config["password"]
+
+ # Check network connectivity first
+ if not check_connectivity(url):
+ error_msg = "Network unreachable or login portal not available"
+ print(f"โ {error_msg}")
+
+ if config["notifications"]["on_network_error"]:
+ notifier.send(
+ "WiFi Auto-Auth: Network Error",
+ error_msg,
+ urgency="critical"
+ )
+
+ log_attempt(username, password, "N/A", "NETWORK_ERROR", error_msg, True)
+ return False
+
+ # Generate dynamic 'a' value if needed
+ if config["payload_params"].get("a") == "dynamic":
+ a_value = str(int(datetime.datetime.now().timestamp()))
+ else:
+ a_value = config["payload_params"].get("a", "")
+
+ # Build payload - copy to avoid mutation
+ payload = dict(config["payload_params"])
+ payload["username"] = username
+ payload["password"] = password
+ if "a" in payload:
+ payload["a"] = a_value
+
+ notification_sent = False
+
try:
- response = requests.post(url, data=payload)
+ response = requests.post(url, data=payload, timeout=10)
response_status = response.status_code
response_message = extract_message(response.text)
-
+
print(f"\n๐ Login Attempt")
- print(f"Time: {datetime.datetime.now()}")
+ print(f"Time: {datetime.datetime.now().isoformat(sep=' ', timespec='seconds')}")
print(f"Username: {username}")
- print(f"Session ID (a): {a_value}")
+ if a_value:
+ print(f"Session ID (a): {a_value}")
print(f"Status: {response_status}")
print(f"Message: {response_message}")
print("-" * 80)
-
+
+ # Determine success/failure and send appropriate notification
+ success_keywords = ["success", "logged in", "authenticated", "welcome"]
+ already_logged_keywords = ["already", "exist", "active"]
+
+ message_lower = response_message.lower()
+
+ if any(keyword in message_lower for keyword in success_keywords):
+ if config["notifications"]["on_success"]:
+ notifier.send(
+ "WiFi Auto-Auth: Success โ
",
+ f"Successfully logged in as {username}",
+ urgency="normal"
+ )
+ notification_sent = True
+ elif any(keyword in message_lower for keyword in already_logged_keywords):
+ if config["notifications"]["on_already_logged_in"]:
+ notifier.send(
+ "WiFi Auto-Auth: Already Connected ๐",
+ "You are already logged into the network",
+ urgency="low"
+ )
+ notification_sent = True
+ else:
+ if config["notifications"]["on_failure"]:
+ notifier.send(
+ "WiFi Auto-Auth: Login Failed โ",
+ f"Failed: {response_message[:100]}",
+ urgency="critical"
+ )
+ notification_sent = True
+
# Log the attempt in SQLite
- log_attempt(username, password, a_value, response_status, response_message)
-
+ log_attempt(username, password, a_value, str(response_status), response_message, notification_sent)
+ return response_status == 200
+
+ except requests.exceptions.Timeout:
+ error_msg = "Connection timeout - server took too long to respond"
+ print(f"โ Timeout Error: {error_msg}")
+ if config["notifications"]["on_network_error"]:
+ notifier.send(
+ "WiFi Auto-Auth: Timeout โฑ๏ธ",
+ error_msg,
+ urgency="critical"
+ )
+ notification_sent = True
+ log_attempt(username, password, a_value, "TIMEOUT", error_msg, notification_sent)
+ return False
+
except requests.exceptions.RequestException as e:
- print(f"โ Error: {e}")
- log_attempt(username, password, a_value, "FAILED", str(e))
+ error_msg = str(e)
+ print(f"โ Error: {error_msg}")
+ if config["notifications"]["on_failure"]:
+ notifier.send(
+ "WiFi Auto-Auth: Error โ",
+ f"Connection error: {error_msg[:100]}",
+ urgency="critical"
+ )
+ notification_sent = True
+ log_attempt(username, password, a_value, "FAILED", error_msg, notification_sent)
+ return False
def view_logs(limit=5):
"""Display login logs in a readable format."""
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
cursor.execute("""
- SELECT timestamp, username, a, response_status, response_message
+ SELECT timestamp, username, a, response_status, response_message, notification_sent
FROM login_attempts
ORDER BY timestamp DESC
LIMIT ?
""", (limit,))
-
+
logs = cursor.fetchall()
conn.close()
-
+
if not logs:
print("No login attempts found.")
return
-
- print("\n๐ Recent Login Attempts")
+
+ print("\n๐ Recent Login Attempts")
print("=" * 80)
-
+
for log in logs:
- timestamp, username, a, status, message = log
+ timestamp, username, a, status, message, notif = log
print(f"Time: {timestamp}")
print(f"Username: {username}")
- print(f"Session ID (a): {a}")
+ if a and a != "N/A":
+ print(f"Session ID (a): {a}")
print(f"Status: {status}")
print(f"Message: {message}")
+ print(f"Notification Sent: {'Yes' if notif else 'No'}")
print("-" * 80)
+def clear_old_logs(days=30):
+ """Clear logs older than specified days"""
+ conn = sqlite3.connect(DB_NAME)
+ cursor = conn.cursor()
+ cutoff = datetime.datetime.now() - datetime.timedelta(days=days)
+ cutoff_iso = cutoff.isoformat(sep=' ', timespec='seconds')
+ cursor.execute("DELETE FROM login_attempts WHERE timestamp < ?", (cutoff_iso,))
+ deleted = cursor.rowcount
+ conn.commit()
+ conn.close()
+ if deleted and deleted > 0:
+ print(f"๐๏ธ Cleared {deleted} old log entries")
+
+def parse_args():
+ """Parse command line arguments"""
+ parser = argparse.ArgumentParser(description='WiFi Auto-Login Script with Notifications')
+ parser.add_argument('--no-notify', action='store_true',
+ help='Disable notifications for this run')
+ parser.add_argument('--test-notify', action='store_true',
+ help='Test notification system and exit')
+ parser.add_argument('--view-logs', type=int, metavar='N',
+ help='View last N login attempts and exit')
+ parser.add_argument('--clear-logs', type=int, metavar='DAYS',
+ help='Clear logs older than DAYS and exit')
+ return parser.parse_args()
+
+def main():
+ """Main execution function"""
+ args = parse_args()
+
+ # Load configuration
+ config = Config.load()
+
+ # Handle test notification
+ if args.test_notify:
+ print("๐งช Testing notification system...")
+ test_notifier = NotificationHandler(enabled=True, sound=True)
+ test_notifier.send(
+ "WiFi Auto-Auth Test",
+ "โ
Notifications are working correctly!",
+ urgency="normal"
+ )
+ print("โ
Test notification sent. Check your desktop notifications!")
+ return
+
+ # Handle view logs
+ if args.view_logs is not None:
+ setup_database()
+ view_logs(args.view_logs)
+ return
+
+ # Handle clear logs
+ if args.clear_logs is not None:
+ setup_database()
+ clear_old_logs(args.clear_logs)
+ return
+
+ # Check if this is first run (default credentials)
+ if config["username"] == "your_username":
+ print("\nโ ๏ธ Please configure your WiFi credentials!")
+ print(f"Edit the config file at: {CONFIG_FILE}")
+ print("Then run this script again.")
+ return
+
+ # Override notification settings if --no-notify is used
+ if args.no_notify:
+ config["notifications"]["enabled"] = False
+ print("๐ Notifications disabled for this run")
+
+ # Initialize notification handler
+ notifier = NotificationHandler(
+ enabled=config["notifications"]["enabled"],
+ sound=config["notifications"].get("sound", True)
+ )
+
+ # Setup database
+ setup_database()
+
+ # Clear old logs (older than 30 days)
+ clear_old_logs(30)
+
+ # Attempt login with retry logic
+ max_retries = config.get("retry_attempts", 3)
+ retry_delay = config.get("retry_delay", 5)
+
+ for attempt in range(max_retries):
+ if attempt > 0:
+ print(f"\n๐ Retry attempt {attempt}/{max_retries - 1}")
+ time.sleep(retry_delay)
+
+ success = wifi_login(config, notifier)
+ if success:
+ break
+
+ # Show recent logs
+ view_logs(5)
+
if __name__ == "__main__":
- setup_database() # Ensure the database is set up
- wifi_login() # Attempt login
- view_logs(5) # Show last 5 login attempts
+ # Install plyer if not available
+ if not PLYER_AVAILABLE:
+ print("๐ฆ plyer not installed. For better notification support, run:")
+ print(" pip install plyer")
+ print(" Using fallback notification methods...\n")
+
+ main()
\ No newline at end of file