import gradio as gr from textblob import TextBlob import gradio as gr from textblob import TextBlob import requests from bs4 import BeautifulSoup def get_nation_issues(NATION, X_PASSWORD): url = f"https://www.nationstates.net/cgi-bin/api.cgi" headers = { "X-Password": X_PASSWORD, "User-Agent": "Nationstate LLM" } params = { "nation": NATION, "q": "issues" } response = requests.get(url, headers=headers, params=params) def get_nation_issues_JSON(sml_data): """ Fetches and reformats issues from the NationStates API. Args: nation (str): The nation name. password (str): The API password. Returns: dict: A dictionary containing the nation ID and a list of issue details. """ # Parse the SML/XML soup = BeautifulSoup(sml_data, "xml") # Extract nation info nation_elem = soup.find("NATION") nation_id = nation_elem.get("id") if nation_elem else "Unknown" # List to store issues issues_list = [] # Extract issues if nation_elem: for issue in nation_elem.find_all("ISSUE"): issue_data = { "issue_id": issue.get("id", "Unknown"), "title": issue.TITLE.get_text() if issue.TITLE else "No title available", "text": issue.TEXT.get_text() if issue.TEXT else "No text available", "author": issue.AUTHOR.get_text() if issue.AUTHOR else "Unknown author", "editor": issue.EDITOR.get_text() if issue.EDITOR else "Unknown editor", "pic1": issue.PIC1.get_text() if issue.PIC1 else "No image 1", "pic2": issue.PIC2.get_text() if issue.PIC2 else "No image 2", "options": [] } # Extract options within the issue for option in issue.find_all("OPTION"): option_data = { "option_id": option.get("id", "Unknown"), "text": option.get_text() if option else "No option text" } issue_data["options"].append(option_data) # Add issue data to list issues_list.append(issue_data) return {"nation_id": nation_id, "issues": issues_list} return get_nation_issues_JSON(response.text) def address_nation_issues(NATION, X_PASSWORD, issue_id, option_id): """ Address a specific issue for a nation in NationStates API. Args: NATION (str): The nation name. X_PASSWORD (str): The API password. issue_id (int): The issue ID to address. option_id (int): The chosen option ID for the issue. Returns: str: API response text. """ url = "https://www.nationstates.net/cgi-bin/api.cgi" headers = { "X-Password": X_PASSWORD, "User-Agent": "Nationstate LLM" } data = { "nation": NATION, "c": "issue", "issue": issue_id, "option": option_id } response = requests.post(url, headers=headers, data=data) def reformat_nation_data(xml_data): """ Parses and reformats NationStates XML data into a structured dictionary. Args: xml_data (str): Raw XML data. Returns: dict: A dictionary containing nation details, issue info, rankings, reclassifications, and headlines. """ soup = BeautifulSoup(xml_data, "xml") nation_elem = soup.find("NATION") nation_id = nation_elem.get("id") if nation_elem else "Unknown" issue_elem = nation_elem.find("ISSUE") if nation_elem else None issue_data = { "issue_id": issue_elem.get("id") if issue_elem else "Unknown", "choice": issue_elem.get("choice") if issue_elem else "Unknown", "ok": issue_elem.OK.get_text() if issue_elem and issue_elem.OK else "Unknown", "description": issue_elem.DESC.get_text() if issue_elem and issue_elem.DESC else "No description available", "rankings": [], "reclassifications": [], "headlines": [] } # Extract rankings rankings_elem = issue_elem.find("RANKINGS") if issue_elem else None if rankings_elem: for rank in rankings_elem.find_all("RANK"): issue_data["rankings"].append({ "rank_id": rank.get("id", "Unknown"), "score": rank.SCORE.get_text() if rank.SCORE else "Unknown", "change": rank.CHANGE.get_text() if rank.CHANGE else "Unknown", "pchange": rank.PCHANGE.get_text() if rank.PCHANGE else "Unknown" }) # Extract reclassifications reclassifications_elem = issue_elem.find("RECLASSIFICATIONS") if issue_elem else None if reclassifications_elem: for reclassify in reclassifications_elem.find_all("RECLASSIFY"): issue_data["reclassifications"].append({ "type": reclassify.get("type", "Unknown"), "from": reclassify.FROM.get_text() if reclassify.FROM else "Unknown", "to": reclassify.TO.get_text() if reclassify.TO else "Unknown" }) # Extract headlines headlines_elem = issue_elem.find("HEADLINES") if issue_elem else None if headlines_elem: issue_data["headlines"] = [headline.get_text() for headline in headlines_elem.find_all("HEADLINE")] return {"nation_id": nation_id, "issue": issue_data} return reformat_nation_data(response.text) # Create the Gradio interface get_nation_issues_interface = gr.Interface( fn=get_nation_issues, inputs=[ gr.Textbox(label="Nation Name", placeholder="Enter the nation name"), gr.Textbox(label="API Password", placeholder="Enter your API password"), ], outputs=gr.JSON(), title="Get Nation Issues as JSON", description="Fetch and reformat issues from the NationStates API", api_name="get_nation_issues_JSON", ) address_nation_issues_interface = gr.Interface( fn=address_nation_issues, inputs=[ gr.Textbox(label="Nation Name", placeholder="Enter the nation name"), gr.Textbox(label="API Password", placeholder="Enter your API password"), gr.Textbox(label="Issue ID", placeholder="Enter the issue ID to address"), gr.Textbox(label="Option ID", placeholder="Enter the option ID to choose") ], outputs=gr.Textbox(label="Response"), title="Address Nation Issues", description="Address a specific issue for a nation in NationStates API", api_name="address_nation_issues", ) demo = gr.TabbedInterface( interface_list=[get_nation_issues_interface, address_nation_issues_interface], tab_names=["Get Nation Issues JSON", "Address Nation Issues"]) # Launch the interface and MCP server if __name__ == "__main__": demo.launch(mcp_server=True)