Add in IP cache for Wiki and just the def for bugzilla
This commit is contained in:
		| @@ -28,6 +28,33 @@ FEED_TO_CHAT_MAP = { | ||||
|     } | ||||
| } | ||||
|  | ||||
| def get_ip_address(domain, retries=10, delay=1): | ||||
|     """ | ||||
|     Resolves the IP address of a domain, retrying up to `retries` times if it fails. | ||||
|      | ||||
|     Args: | ||||
|         domain (str): The domain name to resolve. | ||||
|         retries (int): Number of retry attempts (default is 10). | ||||
|         delay (int): Delay between retries in seconds (default is 1 second). | ||||
|      | ||||
|     Returns: | ||||
|         str: The IP address if resolved successfully. | ||||
|      | ||||
|     Raises: | ||||
|         RuntimeError: If unable to resolve the domain after all attempts. | ||||
|     """ | ||||
|     for attempt in range(1, retries + 1): | ||||
|         try: | ||||
|             ip_address = socket.gethostbyname(domain) | ||||
|             logging.info(f"Successfully resolved {domain} to {ip_address}") | ||||
|             return ip_address | ||||
|         except socket.gaierror: | ||||
|             logging.warning(f"Attempt {attempt} failed. Retrying...") | ||||
|             time.sleep(delay) | ||||
|      | ||||
|     raise RuntimeError(f"Unable to resolve domain '{domain}' after {retries} attempts.") | ||||
|  | ||||
|  | ||||
| # Set up logging to the current directory | ||||
| log_file = "/var/log/BugzillaToRocket.log" | ||||
| logging.basicConfig(filename=log_file, level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') | ||||
| @@ -247,4 +274,4 @@ def main(): | ||||
|             break  # Exit loop after one iteration if --one-off is set | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|     main() | ||||
|     main() | ||||
| @@ -4,52 +4,34 @@ import requests | ||||
| import sqlite3 | ||||
| import logging | ||||
| import os | ||||
| from bs4 import BeautifulSoup | ||||
| import json | ||||
| import re | ||||
| import argparse | ||||
|  | ||||
| # Example structure from Wiki | ||||
| # { | ||||
| # "title": "Koozali SME Server Debugging (French)", | ||||
| # "recent_changes": { | ||||
| # "last_updated": "February 16, 2025, at 20:26 GMT", | ||||
| # "author": "Gieres" | ||||
| # }, | ||||
| # "summary_of_changes": { | ||||
| # "description": "The recent update to the page discusses using Perl with Visual Studio.", | ||||
| # "server_commands": { | ||||
| # "removed_commands": "yum --enablerepo=* install gcc gcc-c++ perl-App-cpanminus perl-AnyEvent-AIO perl-Coro", | ||||
| # "updated_commands": "yum --enablerepo=* install gcc gcc-c++" | ||||
| # }, | ||||
| # "package_changes": { | ||||
| # "changed_from": "cpanm Class::Refresh", | ||||
| # "changed_to": "cpan App::cpanminus", | ||||
| # "additional_commands": [ | ||||
| # "cpanm Compiler::Lexer", | ||||
| # "cpanm Perl::LanguageServer" | ||||
| # ] | ||||
| # } | ||||
| # }, | ||||
| # "links": { | ||||
| # "full_revision": "https://wiki.koozali.org/index.php?title=Koozali_SME_Server_Debugging/fr&diff=43309&oldid=43107", | ||||
| # "comments": "https://wiki.koozali.org/Talk:Koozali_SME_Server_Debugging/fr" | ||||
| # } | ||||
| # } | ||||
| import socket | ||||
|  | ||||
| def join_lines_with_newline(lines): | ||||
|     return "\n".join(lines) | ||||
|  | ||||
| # Wiki RSS feed URL | ||||
| Wiki_RSS_URL = "https://wiki.koozali.org/api.php?hidebots=1&urlversion=2&days=7&limit=50&action=feedrecentchanges&feedformat=rss" | ||||
| # Updated Rocket.Chat webhook URL | ||||
| def get_ip_address(domain, retries=10, delay=1): | ||||
|     for attempt in range(1, retries + 1): | ||||
|         try: | ||||
|             ip_address = socket.gethostbyname(domain) | ||||
|             logging.info(f"Successfully resolved {domain} to {ip_address}") | ||||
|             return ip_address | ||||
|         except socket.gaierror: | ||||
|             logging.warning(f"Attempt {attempt} failed. Retrying...") | ||||
|             time.sleep(delay) | ||||
|      | ||||
|     raise RuntimeError(f"Unable to resolve domain '{domain}' after {retries} attempts.") | ||||
|  | ||||
| WIKI_DOMAIN = "wiki.koozali.org" | ||||
| Wiki_RSS_URL = None | ||||
|  | ||||
| ROCKET_CHAT_URL = "https://chat.koozali.org/hooks/67b8a0fc1f56a124fa47dbec/Dee9hFcASKvvBsW9uRyy7Xjg2m3NTxDprt2HQKTRNuWv8SFr" | ||||
|  | ||||
| # Set up logging | ||||
| log_file = "/var/log/Wiki2Rocket.log"  | ||||
| log_file = "/var/log/Wiki2Rocket.log" | ||||
| logging.basicConfig(filename=log_file, level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') | ||||
|  | ||||
| # Database setup | ||||
| def setup_database(): | ||||
|     conn = sqlite3.connect('sent_wikis.db') | ||||
|     cursor = conn.cursor() | ||||
| @@ -61,7 +43,6 @@ def setup_database(): | ||||
|     conn.commit() | ||||
|     conn.close() | ||||
|  | ||||
| # Function to check if a wiki ID has been sent | ||||
| def has_wiki_been_sent(wiki_id): | ||||
|     conn = sqlite3.connect('sent_wikis.db') | ||||
|     cursor = conn.cursor() | ||||
| @@ -70,7 +51,6 @@ def has_wiki_been_sent(wiki_id): | ||||
|     conn.close() | ||||
|     return exists | ||||
|  | ||||
| # Function to mark a wiki ID as sent | ||||
| def mark_wiki_as_sent(wiki_id): | ||||
|     conn = sqlite3.connect('sent_wikis.db') | ||||
|     cursor = conn.cursor() | ||||
| @@ -78,9 +58,7 @@ def mark_wiki_as_sent(wiki_id): | ||||
|     conn.commit() | ||||
|     conn.close() | ||||
|  | ||||
| # Function to send message to Rocket.Chat | ||||
| def send_to_rocket_chat(wiki_title, wiki_link, wiki_id, description): | ||||
|     #logging.info(f"Logging link:{wiki_link}") | ||||
|     payload = { | ||||
|         "alias": "Wiki", | ||||
|         "text": f"{description}", | ||||
| @@ -98,7 +76,6 @@ def send_to_rocket_chat(wiki_title, wiki_link, wiki_id, description): | ||||
|     else: | ||||
|         logging.error(f"Failed to send wiki notification: {response.status_code} - {response.text}") | ||||
|  | ||||
| # Function to send startup message to Rocket.Chat | ||||
| def send_startup_message(): | ||||
|     payload = { | ||||
|         "alias": "Wiki", | ||||
| @@ -110,12 +87,19 @@ def send_startup_message(): | ||||
|     else: | ||||
|         logging.error(f"Failed to send startup message: {response.status_code} - {response.text}") | ||||
|  | ||||
| # Function to fetch and parse the Wiki RSS feed | ||||
| def fetch_Wiki_feed(): | ||||
|     feed = feedparser.parse(Wiki_RSS_URL) | ||||
|     return feed.entries | ||||
| def fetch_Wiki_feed(original_domain): | ||||
|     try: | ||||
|         response = requests.get( | ||||
|             Wiki_RSS_URL, | ||||
|             headers={'Host': original_domain}, | ||||
|             verify=True | ||||
|         ) | ||||
|         feed = feedparser.parse(response.content) | ||||
|         return feed.entries | ||||
|     except Exception as e: | ||||
|         logging.error(f"RSS request to wiki failed: {str(e)}") | ||||
|         return [] | ||||
|  | ||||
| # Function to clear the sent wiki database | ||||
| def clear_sent_wiki_database(): | ||||
|     conn = sqlite3.connect('sent_wikis.db') | ||||
|     cursor = conn.cursor() | ||||
| @@ -124,56 +108,62 @@ def clear_sent_wiki_database(): | ||||
|     conn.close() | ||||
|     logging.info("Cleared the sent database.") | ||||
|  | ||||
| # Main polling loop | ||||
| def main(one_shot=False, empty_db=False): | ||||
| 	setup_database()  # Initialize the database | ||||
|     global Wiki_RSS_URL | ||||
|      | ||||
|     try: | ||||
|         wiki_ip = get_ip_address(WIKI_DOMAIN) | ||||
|         Wiki_RSS_URL = f"http://{wiki_ip}/api.php?hidebots=1&urlversion=2&days=7&limit=50&action=feedrecentchanges&feedformat=rss" | ||||
|         logging.info(f"Resolved Wiki URL to: {Wiki_RSS_URL}") | ||||
|     except RuntimeError as e: | ||||
|         logging.error(str(e)) | ||||
|         return | ||||
|  | ||||
| 	if empty_db: | ||||
| 		clear_sent_wiki_database() | ||||
|     setup_database() | ||||
|  | ||||
| 	send_startup_message()  # Send startup message | ||||
|     if empty_db: | ||||
|         clear_sent_wiki_database() | ||||
|  | ||||
| 	while True: | ||||
| 		entries = fetch_Wiki_feed() | ||||
|     send_startup_message() | ||||
|  | ||||
| 		for entry in entries: | ||||
| 			json_data = json.dumps(entry, indent=2) | ||||
| 			data = json.loads(json_data) | ||||
|     while True: | ||||
|         entries = fetch_Wiki_feed(WIKI_DOMAIN) | ||||
|  | ||||
| 			title = data["title"] | ||||
| 			published_date = data["published"] | ||||
| 			author = data["author"] | ||||
| 			revision_link = data["link"] | ||||
|         for entry in entries: | ||||
|             json_data = json.dumps(entry, indent=2) | ||||
|             data = json.loads(json_data) | ||||
|  | ||||
| 			formatted_string = ( | ||||
| 				f"Title: {title}\n" | ||||
| 				f"Published Date: {published_date}\n" | ||||
| 				f"Author: {author}\n" | ||||
| 				f"Link to Comparison (old vs new): {revision_link}" | ||||
| 			) | ||||
| 			 | ||||
| 			match = re.search(r'(.*?title=.*?)(.*)', data["id"]) | ||||
|             title = data["title"] | ||||
|             published_date = data["published"] | ||||
|             author = data["author"] | ||||
|             revision_link = data["link"] | ||||
|  | ||||
| 			if match: | ||||
| 				wiki_link = match.group(1)+title  # Everything up to and including "title=<whatever>" | ||||
| 				wiki_id = match.group(2)     # Everything from (and including) <whatever> to the end | ||||
| 			else: | ||||
| 				wiki_id = "Unexpected link" | ||||
| 				wiki_link = "Unexpected link" | ||||
| 				 | ||||
| 			#logging.info(f"{wiki_link} {wiki_id} {title}") | ||||
|             formatted_string = ( | ||||
|                 f"Title: {title}\n" | ||||
|                 f"Published Date: {published_date}\n" | ||||
|                 f"Author: {author}\n" | ||||
|                 f"Link to Comparison (old vs new): {revision_link}" | ||||
|             ) | ||||
|              | ||||
|             match = re.search(r'(.*?title=.*?)(.*)', data["id"]) | ||||
|  | ||||
| 			if not has_wiki_been_sent(wiki_id):  # Check if the wiki has been sent | ||||
| 				send_to_rocket_chat(title, wiki_link, wiki_id, formatted_string) | ||||
| 				mark_wiki_as_sent(wiki_id)  # Mark the wiki ID as sent | ||||
| 				 | ||||
| 				if one_shot: | ||||
| 					logging.info("One-shot mode activated; exiting after sending one message.") | ||||
| 					return  # Exit after sending the first message | ||||
|             if match: | ||||
|                 wiki_link = match.group(1) + title | ||||
|                 wiki_id = match.group(2) | ||||
|             else: | ||||
|                 wiki_id = "Unexpected link" | ||||
|                 wiki_link = "Unexpected link" | ||||
|  | ||||
| 		if not one_shot: | ||||
| 			# Wait for 1 minute before polling again | ||||
| 			time.sleep(60) | ||||
|             if not has_wiki_been_sent(wiki_id): | ||||
|                 send_to_rocket_chat(title, wiki_link, wiki_id, formatted_string) | ||||
|                 mark_wiki_as_sent(wiki_id) | ||||
|                  | ||||
|                 if one_shot: | ||||
|                     logging.info("One-shot mode activated; exiting after sending one message.") | ||||
|                     return | ||||
|  | ||||
|         if not one_shot: | ||||
|             time.sleep(60) | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|     parser = argparse.ArgumentParser(description="Wiki to Rocket.Chat integration.") | ||||
| @@ -182,4 +172,4 @@ if __name__ == "__main__": | ||||
|  | ||||
|     args = parser.parse_args() | ||||
|      | ||||
|     main(one_shot=args.one_shot, empty_db=args.empty_db) | ||||
|     main(one_shot=args.one_shot, empty_db=args.empty_db) | ||||
		Reference in New Issue
	
	Block a user