<commit_before>import pdb

import os.path

import translator as t
import map_manager as maps

class Mode:
    """
    A 'Mode' is pretty much a note mapping. You can have modes for different note mappings, like
    scales or anything fancy that comes to your mind.
    A mode is made from 3 files:
    . A file containing all the notes you want to map to
    . A file containing all the colors you want to assiciate to your notes
    . A file containing the properties of your mode
    The files must have the following names:
    - colors.txt
    - notes.txt
    - properties.txt
    They are txt files because we don't really want bullshit to edit them.
    They must be in a folder containing the mode name inside the "modes" folder in the {app} folder.
    This class will load the files from a given mode name folder and will store the data from the
    mode. It also contains the methods needed for triggering notes and etc.
    """

    # That has to be shared across all modes
    release_notes = {}

    def __init__(self, mode_folder_name):
        """

        """

        # Initialize the lists
        self.original_notes = None
        self.original_colors = None
        self.playfield_size = None
        self.colors = None
        self.playfield = []
        self.background = []
        self.root_notes = []

        # Initialize the properties
        self.properties = {
            'name': None,
            'layout': None,
            'default': None,
            'octave size': None,
            'root_notes': True
        }

        # Check if we have the files neeedd
        self.validate_files(mode_folder_name)

        # Load the data
        self.parse_notes(mode_folder_name)
        self.parse_colors(mode_folder_name)
        self.parse_properties(mode_folder_name)

        # Duplicate and store in the backups
        self.original_notes = list(self.notes)
        self.original_colors = list(self.colors)

        # Add the default padding
        #self.add_default_padding()

        # Get the default playfield size
        self.playfield_size = len(self.notes)
        
        # Make sure everything went fine
        self.validate_consistency()

        # Initialize status values
        self.current_root_note = 0
        self.padding = int(self.properties['padding'])
        self.current_row = int(self.properties['default row'])
        self.max_row = self.get_max_row()

        # Initialize the playfield
        self.refresh_playfield()

    def validate_files(self, mode_folder_name):
        """
        Will check if the files needed are present in the mode folder.
        """

        # Check if we have the folder and the files needed
        if not os.path.isdir(mode_folder_name):
            print("bad folder")
            # TODO trigger exception
            pass

        # Check if we have the files neeed
        for file in ['colors.txt', 'notes.txt', 'properties.txt']:
            if not os.path.isfile(mode_folder_name + os.sep + file):
                print("missing file")
                # TODO trigger exception
                pass

    def parse_notes(self, mode_folder_name):
        """
        Will load the notes file and store into a list.
        """

        # Load the notes file
        file_contents = open(mode_folder_name + os.sep + 'notes.txt').read()

        # Build the array
        file_array = file_contents.split('\n')

        # Initialize the notes array
        self.notes = []

        # Organizes the array
        for row in reversed(file_array):
            self.notes += row.split(",")

        # Convert everything to int
        self.notes = [int(c) for c in self.notes]

    def parse_colors(self, mode_folder_name):
        """
        Will load the colors file and store into a list.
        """

        # Load the notes file
        file_contents = open(mode_folder_name + os.sep + 'colors.txt').read()

        # Build the array
        file_array = file_contents.split('\n')

        # Initialize the notes array
        self.colors = []

        # Organizes the array
        for row in reversed(file_array):
            self.colors += row.split(",")

        # Convert everything to int
        self.colors = [int(c) for c in self.colors]

    def parse_properties(self, mode_folder_name):
        """
        Will parse the properties file.
        """

        # Load the properties file
        file_contents = open(mode_folder_name + os.sep + 'properties.txt').readlines()

        # Parse each option
        for row in file_contents:
            # TODO handle exception
            option_name, option_value = row.split(':')
            option_name = option_name.strip().lower()

            # Store the data
            if option_name in ['name', 'layout', 'default row', 'octave size', 'padding']:
                self.properties[option_name] = option_value.strip()
            elif option_name == 'root_notes':
                if option_value.strip().lower() in ('no', 'false', '0'):
                    self.properties[option_name] = False<commit_msg>Improves the mode files parsing<commit_after>import pdb

import os.path

import translator as t
import map_manager as maps

class Mode:
    """
    A 'Mode' is pretty much a note mapping. You can have modes for different note mappings, like
    scales or anything fancy that comes to your mind.
    A mode is made from 3 files:
    . A file containing all the notes you want to map to
    . A file containing all the colors you want to assiciate to your notes
    . A file containing the properties of your mode
    The files must have the following names:
    - colors.txt
    - notes.txt
    - properties.txt
    They are txt files because we don't really want bullshit to edit them.
    They must be in a folder containing the mode name inside the "modes" folder in the {app} folder.
    This class will load the files from a given mode name folder and will store the data from the
    mode. It also contains the methods needed for triggering notes and etc.
    """

    # That has to be shared across all modes
    release_notes = {}

    def __init__(self, mode_folder_name):
        """

        """

        # Initialize the lists
        self.original_notes = None
        self.original_colors = None
        self.playfield_size = None
        self.colors = None
        self.playfield = []
        self.background = []
        self.root_notes = []

        # Initialize the properties
        self.properties = {
            'name': None,
            'layout': None,
            'default': None,
            'octave size': None,
            'root_notes': True
        }

        # Check if we have the files neeedd
        self.validate_files(mode_folder_name)

        # Load the data
        self.parse_notes(mode_folder_name)
        self.parse_colors(mode_folder_name)
        self.parse_properties(mode_folder_name)

        # Duplicate and store in the backups
        self.original_notes = list(self.notes)
        self.original_colors = list(self.colors)

        # Add the default padding
        #self.add_default_padding()

        # Get the default playfield size
        self.playfield_size = len(self.notes)
        
        # Make sure everything went fine
        self.validate_consistency()

        # Initialize status values
        self.current_root_note = 0
        self.padding = int(self.properties['padding'])
        self.current_row = int(self.properties['default row'])
        self.max_row = self.get_max_row()

        # Initialize the playfield
        self.refresh_playfield()

    def validate_files(self, mode_folder_name):
        """
        Will check if the files needed are present in the mode folder.
        """

        # Check if we have the folder and the files needed
        if not os.path.isdir(mode_folder_name):
            print("bad folder")
            # TODO trigger exception
            pass

        # Check if we have the files neeed
        for file in ['colors.txt', 'notes.txt', 'properties.txt']:
            if not os.path.isfile(mode_folder_name + os.sep + file):
                print("missing file")
                # TODO trigger exception
                pass

    def parse_notes(self, mode_folder_name):
        """
        Will load the notes file and store into a list.
        """

        # Load the notes file
        file_contents = open(mode_folder_name + os.sep + 'notes.txt').readlines()

        # Initialize the notes array
        self.notes = []

        # Organizes the array
        for row in reversed(file_contents):
            self.notes += row.split(",")

        # Convert everything to int
        self.notes = [int(c) for c in self.notes]

    def parse_colors(self, mode_folder_name):
        """
        Will load the colors file and store into a list.
        """

        # Load the colors file
        file_contents = open(mode_folder_name + os.sep + 'colors.txt').readlines()

        # Initialize the notes array
        self.colors = []

        # Organizes the array
        for row in reversed(file_contents):
            self.colors += row.split(",")

        # Convert everything to int
        self.colors = [int(c) for c in self.colors]

    def parse_properties(self, mode_folder_name):
        """
        Will parse the properties file.
        """

        # Load the properties file
        file_contents = open(mode_folder_name + os.sep + 'properties.txt').readlines()

        # Parse each option
        for row in file_contents:
            # TODO handle exception
            option_name, option_value = row.split(':')
            option_name = option_name.strip().lower()

            # Store the data
            if option_name in ['name', 'layout', 'default row', 'octave size', 'padding']:
                self.properties[option_name] = option_value.strip()
            elif option_name == 'root_notes':
                if option_value.strip().lower() in ('no', 'false', '0'):
                    self.properties[option_name] = False
{'fraction_non_alphanumeric': 0.08290981564524165, 'fraction_numerical': 0.0005979073243647235, 'mean_word_length': 2.0201625037616613, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2164632', 'n_tokens_mistral': 2692, 'n_tokens_neox': 2606, 'n_words': 923}