Ejemplo n.º 1
0
 def send_file(self, file_name, window):
     """
     Send the data in a single file to the Discord Bot Server. This
     is done in a few steps.
     # TODO: Optimize amount of times the file is looped over
     # TODO: Split this into multiple shorter functions
     1. Retrieve basic information for this CombatLog that is
        required for sending it, including the date it was created
        and the player name.
     2. Check the requirement that the server for this character is
        known. This is only the case if the character name is unique
        for this system across all servers. If the server cannot
        reliably be determined, the CombatLog data cannot be sent.
     3. Check the files.db database in the temporary data directory
        if this file is in it. If it is not, this is  the first time
        this file is processed. If it is, this file has already been
        processed at least once.
     4. Parse the file, determining individual matches and the times
        they started at.
     5. Retrieve data from the character database (managed by the
        MainWindow.characters_frame in the :characters: attribute.
     6. If Discord sharing is enabled for the character, make sure
        the Discord Bot Server knows about it by sending the command
        for registering a character to the server.
        Note that this may cause duplicate registration requests
        among multiple files, but the Discord Bot Server will ignore
        them if the character is already registered.
     7. Loop over the matches to send.
        7.1. Retrieve match-specific required information such as
             the player ID format and the results.
        7.2. Check if the match is a tutorial match. If it is, the
             character was the only participant and sending it would
             only clutter the database.
        7.3. Check if the non-personal match data has already been
             sent for this file and if not send it to the server.
             # TODO: Extend this part for sending the map type
        7.4. Check if personal data sharing is enabled for this
             character and it has not already been sent. Then send
             the personal match data to the server.
     8. Update the files.db database with whether the sharing of
        data was successful. Only if *all* matches were successfully
        synchronized will the state be set to True. If the state is
        False, a new attempt will be made at some later point.
     9. Save the database to file to prevent loss of data if the user
        exits the process unexpectedly.
     :param file_name: Absolute path to the CombatLog to sync
     :param window: MainWindow instance of this GSF Parser
     """
     date = Parser.parse_filename(file_name)
     lines = Parser.read_file(file_name)
     player_name = Parser.get_player_name(lines)
     server = window.characters_frame.characters.get_server_for_character(player_name)
     basename = os.path.basename(file_name)
     # Actually send the file data to the server
     if date is None or server is None:
         return
     print("[DiscordClient] Synchronizing file: {}".format(basename))
     if basename not in self.db:
         self.db[basename] = {"match": False, "char": False}
     match_s, char_s = self.db[basename]["match"], self.db[basename]["char"]
     player_id_list = Parser.get_player_id_list(lines)
     file_cube, matches, spawns = Parser.split_combatlog(lines, player_id_list)
     character = window.characters_frame.characters[(server, player_name)]
     character_enabled = character["Discord"]
     if character_enabled is True:
         server, name, faction = character["Server"], character["Name"], character["Faction"]
         self.send_character(server, faction, name)
     print("[DiscordClient] Character sharing {} for {} on {}".format(
         "enabled" if character_enabled else "disabled", player_name, server))
     for index, (start, end) in enumerate(zip(matches[::2], matches[1::2])):
         match = file_cube[index]
         id_fmt = Parser.get_id_format(match[0])
         start, end = map(lambda time: datetime.combine(date.date(), time.time()), (start, end))
         results = Parser.parse_match(match, player_id_list)
         abls, dmg_d, dmg_t, _, _, _, _, _, enemies, _, _, ships, _ = results
         if Parser.is_tutorial(match):
             continue
         if self.db[basename]["match"] is False:
             match_s = self.send_match_start(server, date, start, id_fmt) and match_s
             match_s = self.send_match_end(server, date, start, id_fmt, end) and match_s
         else:
             print("[DiscordClient] Ignored {}".format(basename))
         data = FileHandler.get_data_dictionary()
         spawn_dict = None
         for spawn in spawns[index]:
             result = FileHandler.get_spawn_dictionary(data, basename, start, spawn)
             if isinstance(result, dict):
                 spawn_dict = result
         if isinstance(spawn_dict, dict):
             if "map" in spawn_dict and isinstance(spawn_dict["map"], tuple) and None not in spawn_dict["map"]:
                 self.send_match_map(server, date, start, id_fmt, spawn_dict["map"])
             if "score" in spawn_dict and isinstance(spawn_dict["score"], float):
                 self.send_match_score(server, date, start, id_fmt, character["Faction"], spawn_dict["score"])
         if character_enabled is True:
             if self.db[basename]["char"] is False:
                 # Parse the file with results and send the results
                 ship = ship_tiers[max(ships, key=ships.__getitem__)] if len(ships) != 0 else "Unknown"
                 deaths = len(match) - 1
                 char_s = self.send_result(
                     server, date, start, id_fmt, player_name, len(enemies), dmg_d, dmg_t, deaths, ship)
                 print("[DiscordClient] {} to send character result for ({}, {})".format(
                     "Succeeded" if char_s is True else "Failed", server, player_name))
             else:
                 print("[DiscordClient] Not sending character result because already sent.")
         else:
             print("[DiscordClient] Not sending character result because not enabled.")
     self.db[basename] = {"match": match_s, "char": char_s}
     self.save_database()