From 090230f11a8148dc15b72b563d02ce261eb0e7d2 Mon Sep 17 00:00:00 2001 From: tamservo Date: Mon, 24 Jul 2023 16:36:36 -0400 Subject: [PATCH] Removed DeVries. Added process monitoring to collection process so it will restart if it dies. Seems to be a 2h limit on API, so reporting has been failing at the end of long races. --- create_queue_db.py | 23 ++++---- robottas.py | 53 +++++++++++++++++- robottas_collector.py | 121 +++++++++++++++++++++--------------------- 3 files changed, 124 insertions(+), 73 deletions(-) mode change 100644 => 100755 create_queue_db.py mode change 100644 => 100755 robottas_collector.py diff --git a/create_queue_db.py b/create_queue_db.py old mode 100644 new mode 100755 index 6d47855..275446d --- a/create_queue_db.py +++ b/create_queue_db.py @@ -1,11 +1,12 @@ -import sqlite3 - -if __name__ == '__main__': - con = sqlite3.connect('messages.db') - cur = con.cursor() - #cur.execute("""drop table messages""") - cur.execute("""create table messages( id integer primary key, message );""") - con.commit() - cur.close() - con.close() - +#!/usr/bin/python3 +import sqlite3 + +if __name__ == '__main__': + con = sqlite3.connect('messages.db') + cur = con.cursor() + #cur.execute("""drop table messages""") + cur.execute("""create table messages( id integer primary key, message );""") + con.commit() + cur.close() + con.close() + diff --git a/robottas.py b/robottas.py index 4149fb1..80ef5e9 100755 --- a/robottas.py +++ b/robottas.py @@ -1,9 +1,12 @@ #!/usr/bin/python3 import asyncio +from asyncio.subprocess import PIPE, STDOUT import collections.abc import json +import os import sqlite3 +from subprocess import Popen import time import discord @@ -497,6 +500,7 @@ class Robottas(commands.Bot): async def _report(self, ctx): self.is_reporting = True self.channel = ctx.channel + await self.start_collect() while self.is_reporting: # Do processing @@ -515,17 +519,46 @@ class Robottas(commands.Bot): # process any messages in the delay queue await self.process_delay_messages() + #If collecting, make sure the collection process is running + if self.is_collecting: + if self.collector_proc == None or \ + self.collector_proc.poll() != None: + await self.start_collect() + def get_token(self, token_file): with open(token_file) as tok: return tok.readline().strip() + + async def start_collect(self): + self.is_collecting = True + dir_path = os.path.dirname(os.path.realpath(__file__)) + command_txt = os.path.join(dir_path, self.collector_command) + command_txt += self.collector_params + print(f"command_txt: {command_txt}") + self.collector_proc = Popen(command_txt.split()) + + + async def stop_collect(self): + self.is_collecting = False + try: + if self.collector_proc != None: + self.collector_proc.kill() + except: + print("Tried to kill collection process") + + def __init__(self): # Set debug or not self.debug = True # Discord authentication token self.token = self.get_token("token.txt") + self.collector_command = "robottas_collector.py" + self.collector_params = " save dummy.txt" + self.collector_proc = None + self.is_collecting = False # Preface messages with the following self.report_preamble = ':robot::peach: Alert!' @@ -580,7 +613,6 @@ class Robottas(commands.Bot): '20': '<:MAG:1067883814992486510>', '23': '<:ALB:1067874026871074887>', '2': '<:SAR:1067890949197414410>', - '21': '<:DEV:1067891622727131248>' } # Holds dictionary for driver 3 letter code to icon @@ -606,7 +638,6 @@ class Robottas(commands.Bot): 'MAG': '<:MAG:1067883814992486510>', 'ALB': '<:ALB:1067874026871074887>', 'SAR': '<:SAR:1067890949197414410>', - 'DEV': '<:DEV:1067891622727131248>' } # Holds dictionary for race states to icons @@ -710,6 +741,7 @@ class Robottas(commands.Bot): async def rbstop(ctx): self.is_reporting = False self.report_id = None + await self.stop_collect() await ctx.send(":robot::peach: powering down") @@ -778,6 +810,23 @@ class Robottas(commands.Bot): await self._test_file(ctx) + @self.command() + async def start_collect(ctx): + if str(ctx.author) == "tamservo#0" or ctx.author.guild_permissions.administrator: + # if an authorized user, start the collection script that + # puts records into the database + await self.start_collect() + + + @self.command() + async def calm(ctx): + file_name = os.path.dirname(os.path.realpath(__file__)) + file_name = os.path.join(file_name, "images/calm.png") + with open(file_name, "rb") as handle: + df = discord.File(handle, filename=file_name) + await ctx.send(file = df) + + if __name__ == '__main__': rb = Robottas() rb.run_robottas() diff --git a/robottas_collector.py b/robottas_collector.py old mode 100644 new mode 100755 index 12ac3e7..d30b957 --- a/robottas_collector.py +++ b/robottas_collector.py @@ -1,60 +1,61 @@ -import argparse -import sys -from RobottasSignalr import SignalRClient, messages_from_raw - - -def save(args): - mode = 'a' if args.append else 'w' - client = SignalRClient(args.file, filemode=mode, debug=args.debug, - timeout=args.timeout) - client.start() - - -def convert(args): - with open(args.input, 'r') as infile: - messages = infile.readlines() - data, ec = messages_from_raw(messages) - with open(args.output, 'w') as outfile: - for elem in data: - outfile.write(str(elem)+'\n') - print(f"Completed with {ec} error(s)") - - -parser = argparse.ArgumentParser( - prog="python -m fastf1.livetiming", - description="Save live timing data during a session", - formatter_class=argparse.ArgumentDefaultsHelpFormatter -) - -subparsers = parser.add_subparsers() - -rec_parser = subparsers.add_parser( - 'save', help='Save live timing data' -) -conv_parser = subparsers.add_parser( - 'extract', help='Extract messages from saved debug-mode data' -) - -rec_parser.add_argument('file', type=str, help='Output file name') -rec_parser.add_argument('--append', action='store_true', default=False, - help="Append to output file. By default the file is " - "overwritten if it exists already.") -rec_parser.add_argument('--debug', action='store_true', default=False, - help='Enable debug mode: save full SignalR message, ' - 'not just the data.') -rec_parser.add_argument('--timeout', type=int, default=60, - help='Timeout in seconds after which the client will ' - 'automatically exit if no data is received.') -rec_parser.set_defaults(func=save) - -conv_parser.add_argument("input", type=str, help='Input file name') -conv_parser.add_argument("output", type=str, help='Output file name') -conv_parser.set_defaults(func=convert) - -if not len(sys.argv) > 1: - # user did not provide any arguments - parser.print_help() - parser.exit(1) - -args = parser.parse_args() -args.func(args) # call function associated with subparser \ No newline at end of file +#!/usr/bin/python3 +import argparse +import sys +from RobottasSignalr import SignalRClient, messages_from_raw + + +def save(args): + mode = 'a' if args.append else 'w' + client = SignalRClient(args.file, filemode=mode, debug=args.debug, + timeout=args.timeout) + client.start() + + +def convert(args): + with open(args.input, 'r') as infile: + messages = infile.readlines() + data, ec = messages_from_raw(messages) + with open(args.output, 'w') as outfile: + for elem in data: + outfile.write(str(elem)+'\n') + print(f"Completed with {ec} error(s)") + + +parser = argparse.ArgumentParser( + prog="python -m fastf1.livetiming", + description="Save live timing data during a session", + formatter_class=argparse.ArgumentDefaultsHelpFormatter +) + +subparsers = parser.add_subparsers() + +rec_parser = subparsers.add_parser( + 'save', help='Save live timing data' +) +conv_parser = subparsers.add_parser( + 'extract', help='Extract messages from saved debug-mode data' +) + +rec_parser.add_argument('file', type=str, help='Output file name') +rec_parser.add_argument('--append', action='store_true', default=False, + help="Append to output file. By default the file is " + "overwritten if it exists already.") +rec_parser.add_argument('--debug', action='store_true', default=False, + help='Enable debug mode: save full SignalR message, ' + 'not just the data.') +rec_parser.add_argument('--timeout', type=int, default=60, + help='Timeout in seconds after which the client will ' + 'automatically exit if no data is received.') +rec_parser.set_defaults(func=save) + +conv_parser.add_argument("input", type=str, help='Input file name') +conv_parser.add_argument("output", type=str, help='Output file name') +conv_parser.set_defaults(func=convert) + +if not len(sys.argv) > 1: + # user did not provide any arguments + parser.print_help() + parser.exit(1) + +args = parser.parse_args() +args.func(args) # call function associated with subparser