# This is an quote and post library for a specific thread in the WarOnline forum. import WarClient import requests import re from bs4 import BeautifulSoup import urllib.request as urllib import warnings warnings.filterwarnings("ignore") # Define the login URL and the thread URL login_url = 'https://waronline.org/fora/index.php?login/login' thread_url = 'https://waronline.org/fora/index.php?threads/warbot-playground.17636/' post_url = "https://waronline.org/fora/index.php?threads/warbot-playground.17636/add-reply" # Sending the message (change that!) message = "Test" # Define the login credentials username = 'WarBot' password = 'naP2tion' # Start a session to persist the login cookie across requests session = requests.Session() def compare_pages(url1, url2): #Compares 2 pages and returns True if they are the same return urllib.urlopen(url1).geturl() == urllib.urlopen(url2).geturl() def login(username=username, password=password, thread_url=thread_url): # Log-In to the forum and redirect to thread # Retrieve the login page HTML to get the CSRF token login_page_response = session.get(login_url) soup = BeautifulSoup(login_page_response.text, 'html.parser') csrf_token = soup.find('input', {'name': '_xfToken'})['value'] # Login to the website login_data = { 'login': username, 'password': password, 'remember': '1', '_xfRedirect': thread_url, '_xfToken': csrf_token } response = session.post(login_url, data=login_data) # Check if the login was successful if 'Invalid login' in response.text: print('Login failed!') exit() def post(message=message, thread_url=thread_url, post_url=post_url, quoted_by="",quote_text="",quote_source=""): #Post a message to the forum (with or without the quote #quote_source is in format 'post-3920992' quote_source = quote_source.split('-')[-1] # Take the numbers only if quoted_by: message = f'[QUOTE="{quoted_by}, post: {quote_source}"]{quote_text}[/QUOTE]{message}' # optionally add @{quoted_by} to indent the quoter # Retrieve the thread page HTML response = session.get(thread_url) # Parse the HTML with BeautifulSoup soup = BeautifulSoup(response.text, 'html.parser') # Extract the _xfToken value from the hidden form field xf_token = soup.find('input', {'name': '_xfToken'}).get('value') # Construct the message data for the POST request message_data = { '_xfToken': xf_token, 'message': message, 'attachment_hash': '', 'last_date': '', '_xfRequestUri': post_url, '_xfWithData': '1', '_xfResponseType': 'json' } response = session.post(post_url, data=message_data) # Check if the post was successful if not response.ok: print('Post failed!') exit() print('Post submitted successfully.') def allQuotesFor(thread_url=thread_url, username=username, startingPage=1): # Returns all the quotes for #username in the specific multi-page thread url allquotes =[] page = startingPage # Counter lastPage = False # Initial values for messangerName and the message ID messengerName = "" messageID = "" # Patterns to search in the last quote. namePattern = re.compile('data-lb-caption-desc="(.*?) ·') messageIDPattern = re.compile('data-lb-id="(.*?)"') while not lastPage: response = requests.get(thread_url + 'page-' + str(page)) if response.status_code == 200: # Payload of the function response = session.get(thread_url) html_content = response.content # Parse the HTML content using BeautifulSoup soup = BeautifulSoup(html_content, 'html.parser') # Find all the message in the thread page messageData = soup.find_all('div', {'class': 'message-userContent'}) for data in messageData: if username in data.text: try: # Get the messager username matchName = namePattern.search(str(data)) if matchName: messengerName = matchName.group(1) # Get the message ID matchID = messageIDPattern.search(str(data)) if matchID: messageID = matchID.group(1) reply = data.text.split("Click to expand...")[-1].replace('\n', ' ').strip() allquotes.append({'reply': reply, 'messengerName': messengerName, 'messageID': messageID}) except: continue # There was no text in quote, move next #check if that is not a last page if not compare_pages(thread_url + 'page-' + str(page), thread_url + 'page-' + str(page + 1)): page += 1 else: lastPage = True else: lastPage = True return allquotes if __name__ == '__main__': login(username=username, password=password, thread_url=thread_url) #post(message=message, thread_url=thread_url, post_url=post_url,quoted_by='Василий Пупкин',quote_text='Testing the XenForo response mechanism') # Get All Quotes quotes = allQuotesFor(thread_url=thread_url, username=username, startingPage=1) # Search for quotes withou the relpy and answer them for quote in quotes: reply = allQuotesFor(thread_url=thread_url, username=quote['messengerName'], startingPage=1) if not reply: print('Quote: ',quote['reply']) print(WarClient2.getReply(message=quote['reply']))