Compare commits
	
		
			4 Commits
		
	
	
		
			8d7bc7e096
			...
			main
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 2f13e87774 | |||
| 9a4a8155e2 | |||
| 96b3f76ea2 | |||
| 91ff9625ec | 
							
								
								
									
										8
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,7 +1 @@ | ||||
| *.txt | ||||
| *.sgf | ||||
| *.png | ||||
| *.out | ||||
| *.sh | ||||
| __pycache__/ | ||||
| rengobot_venv/ | ||||
| portable_python | ||||
							
								
								
									
										12
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								README.md
									
									
									
									
									
								
							| @@ -1,12 +1,2 @@ | ||||
| A fork of  | ||||
| this is a repository of useful python scripts | ||||
|  | ||||
| https://github.com/ReneCareenium/rengobot | ||||
|  | ||||
| A discord bot for playing rengo games! | ||||
|  | ||||
| # Dependencies | ||||
| - sgf-render | ||||
| - python-discord | ||||
| - python-sgfmill | ||||
|  | ||||
| Make sure to run the bot in an environment with read/write permissions | ||||
							
								
								
									
										1
									
								
								caldav/htpasswd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								caldav/htpasswd
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| username:password | ||||
							
								
								
									
										26
									
								
								caldav/readme.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								caldav/readme.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
|  | ||||
|  | ||||
| how to make python portable | ||||
|  | ||||
| https://chat.mistral.ai/chat/ab946d87-22e6-47d4-a99c-e8522c077347 | ||||
|  | ||||
| ``` | ||||
| wget https://www.python.org/ftp/python/3.13.7/Python-3.13.7.tgz | ||||
| tar -xzf Python-3.13.7.tgz | ||||
| rm Python-3.13.7.tgz | ||||
| cd Python-3.13.7 | ||||
| ./configure --enable-optimizations --with-ensurepip=install --prefix=$(pwd)/portable_python | ||||
| make -j$(nproc) | ||||
| make install | ||||
| # now in portable_python install packages that are needed | ||||
| ./portable_python/bin/pip3 install bcrypt | ||||
| ./portable_python/bin/pip3 install radicale | ||||
| cd .. | ||||
| mv Python-3.13.7/portable_python portable_python | ||||
| rm -rf Python-3.13.7  | ||||
| cd .. | ||||
| tar -czvf caldav.tar.gz caldav/ | ||||
| ``` | ||||
|  | ||||
|  | ||||
| tar -xzf caldav.tar.gz | ||||
							
								
								
									
										34
									
								
								caldav/server.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								caldav/server.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| from radicale import Application, config | ||||
| from wsgiref.simple_server import make_server | ||||
| import os | ||||
|  | ||||
| def run_server(): | ||||
|     # Load default configuration | ||||
|     configuration = config.load() | ||||
|  | ||||
|     # Customize settings | ||||
|     configuration.update({ | ||||
|         "server": { | ||||
|             "hosts": "0.0.0.0:5232",  # Listen on all interfaces | ||||
|         }, | ||||
|         | ||||
|         "storage": { | ||||
|             "filesystem_folder": "./calendars",  # Store calendars here | ||||
|         }, | ||||
|         "auth": { | ||||
|             "type": "htpasswd", | ||||
|             "htpasswd_filename": "./htpasswd",  # Path to htpasswd file | ||||
|             "htpasswd_encryption": "autodetect",  # or "sha1", "md5" (bcrypt is most secure) | ||||
|         }, | ||||
|        | ||||
|     }) | ||||
|  | ||||
|     # Create and run the app | ||||
|     app = Application(configuration=configuration) | ||||
|     server = make_server("0.0.0.0", 5232, app) | ||||
|     print("✅ Secure CalDAV server running on http://0.0.0.0:5232") | ||||
|     print("🔐 Authentication required. Default user: admin / password") | ||||
|     server.serve_forever() | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|     run_server() | ||||
							
								
								
									
										18
									
								
								python_website_monitor/config.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								python_website_monitor/config.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| { | ||||
|   "website": { | ||||
|     "url": "http://petrovv.com", | ||||
|     "check_interval_seconds": 600, | ||||
|     "timeout_seconds": 5 | ||||
|   }, | ||||
|   "email": { | ||||
|     "smtp_server": "mail.petrovv.com", | ||||
|     "smtp_port": 465, | ||||
|     "from_email": "monitor@petrovv.com", | ||||
|     "to_email": "nikola@petrovv.com", | ||||
|     "credentials_file": "credentials.txt" | ||||
|   }, | ||||
|   "database": { | ||||
|     "path": "website_status.db", | ||||
|     "log_retention_days": 10 | ||||
|   } | ||||
| } | ||||
							
								
								
									
										2
									
								
								python_website_monitor/credentials.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								python_website_monitor/credentials.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| email | ||||
| password | ||||
							
								
								
									
										162
									
								
								python_website_monitor/server.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								python_website_monitor/server.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,162 @@ | ||||
| import requests | ||||
| import time | ||||
| import smtplib | ||||
| from email.mime.text import MIMEText | ||||
| import sqlite3 | ||||
| from datetime import datetime, timedelta | ||||
| import json | ||||
| import os | ||||
|  | ||||
| def read_credentials(file_path): | ||||
|     with open(file_path, 'r') as file: | ||||
|         lines = file.readlines() | ||||
|         email = lines[0].strip() | ||||
|         password = lines[1].strip() | ||||
|     return email, password | ||||
|  | ||||
| def check_website(url, timeout=5): | ||||
|     try: | ||||
|         response = requests.get(url, timeout=timeout) | ||||
|         return response.status_code == 200 | ||||
|     except requests.RequestException: | ||||
|         return False | ||||
|  | ||||
| def send_email(subject, body, to_email, from_email, from_password, smtp_server, smtp_port): | ||||
|     msg = MIMEText(body) | ||||
|     msg['Subject'] = subject | ||||
|     msg['From'] = from_email | ||||
|     msg['To'] = to_email | ||||
|  | ||||
|     with smtplib.SMTP_SSL(smtp_server, smtp_port) as server: | ||||
|         server.login(from_email, from_password) | ||||
|         server.sendmail(from_email, to_email, msg.as_string()) | ||||
|  | ||||
| def create_database(db_path): | ||||
|     conn = sqlite3.connect(db_path) | ||||
|     cursor = conn.cursor() | ||||
|     cursor.execute(''' | ||||
|         CREATE TABLE IF NOT EXISTS website_status ( | ||||
|             id INTEGER PRIMARY KEY AUTOINCREMENT, | ||||
|             timestamp DATETIME NOT NULL, | ||||
|             current_status INTEGER NOT NULL, | ||||
|             previous_status INTEGER | ||||
|         ) | ||||
|     ''') | ||||
|     conn.commit() | ||||
|     conn.close() | ||||
|  | ||||
| def log_website_status(db_path, current_status, previous_status): | ||||
|     conn = sqlite3.connect(db_path) | ||||
|     cursor = conn.cursor() | ||||
|     timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S') | ||||
|     cursor.execute(''' | ||||
|         INSERT INTO website_status (timestamp, current_status, previous_status) | ||||
|         VALUES (?, ?, ?) | ||||
|     ''', (timestamp, 1 if current_status else 0, previous_status)) | ||||
|     conn.commit() | ||||
|     conn.close() | ||||
|  | ||||
| def get_last_status(db_path): | ||||
|     conn = sqlite3.connect(db_path) | ||||
|     cursor = conn.cursor() | ||||
|     cursor.execute(''' | ||||
|         SELECT current_status FROM website_status | ||||
|         ORDER BY id DESC LIMIT 1 | ||||
|     ''') | ||||
|     result = cursor.fetchone() | ||||
|     conn.close() | ||||
|     return result[0] if result else None | ||||
|  | ||||
| def print_email_sent(status_str, timestamp): | ||||
|     print(f"[{timestamp}] Email sent: Website is now {status_str}") | ||||
|  | ||||
| def cleanup_old_logs(db_path, days_to_keep=10): | ||||
|     cutoff_date = (datetime.now() - timedelta(days=days_to_keep)).strftime('%Y-%m-%d %H:%M:%S') | ||||
|     conn = sqlite3.connect(db_path) | ||||
|     cursor = conn.cursor() | ||||
|  | ||||
|     # Delete rows where current_status equals previous_status and timestamp is older than 10 days | ||||
|     cursor.execute(''' | ||||
|         DELETE FROM website_status | ||||
|         WHERE timestamp < ? AND current_status = previous_status | ||||
|     ''', (cutoff_date,)) | ||||
|  | ||||
|     deleted_rows = cursor.rowcount | ||||
|     conn.commit() | ||||
|     conn.close() | ||||
|     return deleted_rows | ||||
|  | ||||
| def print_config_example(): | ||||
|     example_config = { | ||||
|         "website": { | ||||
|             "url": "http://petrovv.com", | ||||
|             "check_interval_seconds": 600, | ||||
|             "timeout_seconds": 5 | ||||
|         }, | ||||
|         "email": { | ||||
|             "smtp_server": "mail.petrovv.com", | ||||
|             "smtp_port": 465, | ||||
|             "from_email": "monitor@petrovv.com", | ||||
|             "to_email": "nikola@petrovv.com", | ||||
|             "credentials_file": "credentials.txt" | ||||
|         }, | ||||
|         "database": { | ||||
|             "path": "website_status.db", | ||||
|             "log_retention_days": 10 | ||||
|         } | ||||
|     } | ||||
|     print("Example config.json:") | ||||
|     print(json.dumps(example_config, indent=2)) | ||||
|  | ||||
| def main(): | ||||
|     # Check if config.json exists | ||||
|     if not os.path.exists("config.json"): | ||||
|         print("Error: config.json not found.") | ||||
|         print_config_example() | ||||
|         return | ||||
|  | ||||
|     # Load configuration | ||||
|     with open("config.json", "r") as f: | ||||
|         config = json.load(f) | ||||
|  | ||||
|     url = config["website"]["url"] | ||||
|     to_email = config["email"]["to_email"] | ||||
|     check_interval = config["website"]["check_interval_seconds"] | ||||
|     credentials_file = config["email"]["credentials_file"] | ||||
|     db_path = config["database"]["path"] | ||||
|     smtp_server = config["email"]["smtp_server"] | ||||
|     smtp_port = config["email"]["smtp_port"] | ||||
|     log_retention_days = config["database"]["log_retention_days"] | ||||
|  | ||||
|     create_database(db_path) | ||||
|     from_email, from_password = read_credentials(credentials_file) | ||||
|  | ||||
|     last_status = get_last_status(db_path) | ||||
|     last_cleanup = datetime.now() | ||||
|  | ||||
|     while True: | ||||
|         current_time = datetime.now() | ||||
|         current_status = check_website(url) | ||||
|         log_website_status(db_path, current_status, last_status) | ||||
|  | ||||
|         if last_status is None or current_status != (last_status == 1): | ||||
|             status_str = "up" if current_status else "down" | ||||
|             subject = f"Website Status Change: {status_str}" | ||||
|             body = f"The website {url} is now {status_str} at {current_time.strftime('%Y-%m-%d %H:%M:%S')}." | ||||
|             send_email(subject, body, to_email, from_email, from_password, smtp_server, smtp_port) | ||||
|             print_email_sent(status_str, current_time.strftime('%Y-%m-%d %H:%M:%S')) | ||||
|             last_status = 1 if current_status else 0 | ||||
|  | ||||
|         # Perform cleanup once per day | ||||
|         if (current_time - last_cleanup).days >= 1: | ||||
|             deleted = cleanup_old_logs(db_path, log_retention_days) | ||||
|             if deleted > 0: | ||||
|                 print(f"[{current_time.strftime('%Y-%m-%d %H:%M:%S')}] Cleanup: Deleted {deleted} logs older than {log_retention_days} days (keeping status changes)") | ||||
|             last_cleanup = current_time | ||||
|  | ||||
|         time.sleep(check_interval) | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|     main() | ||||
|  | ||||
|  | ||||
							
								
								
									
										7
									
								
								rengobot/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								rengobot/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| *.txt | ||||
| *.sgf | ||||
| *.png | ||||
| *.out | ||||
| *.sh | ||||
| __pycache__/ | ||||
| rengobot_venv/ | ||||
							
								
								
									
										12
									
								
								rengobot/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								rengobot/README.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| A fork of  | ||||
|  | ||||
| https://github.com/ReneCareenium/rengobot | ||||
|  | ||||
| A discord bot for playing rengo games! | ||||
|  | ||||
| # Dependencies | ||||
| - sgf-render | ||||
| - python-discord | ||||
| - python-sgfmill | ||||
|  | ||||
| Make sure to run the bot in an environment with read/write permissions | ||||
		Reference in New Issue
	
	Block a user