Compare commits
	
		
			4 Commits
		
	
	
		
			8d7bc7e096
			...
			main
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 2f13e87774 | |||
| 9a4a8155e2 | |||
| 96b3f76ea2 | |||
| 91ff9625ec | 
							
								
								
									
										8
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,7 +1 @@ | |||||||
| *.txt | portable_python | ||||||
| *.sgf |  | ||||||
| *.png |  | ||||||
| *.out |  | ||||||
| *.sh |  | ||||||
| __pycache__/ |  | ||||||
| rengobot_venv/ |  | ||||||
							
								
								
									
										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