示例#1
0
def windows_to_steam_conversion(original_save_path: str) -> None:
    containers_list = Container.get_containers_list(original_save_path)

    Logger.logPrint('\nContainers found:' + str(containers_list))
    container_name = Scenario.ask_for_containers_to_convert(
        containers_list) if len(containers_list) > 1 else containers_list[0]
    container_url = utils.join_paths(original_save_path, container_name)

    Logger.logPrint('\nInitializing Astroneer save container...')
    container = Container(container_url)
    Logger.logPrint(f'Detected chunks: {container.chunk_count}')

    Logger.logPrint('Container file loaded successfully !\n')

    saves_to_export = Scenario.ask_saves_to_export(container.save_list)

    Scenario.ask_rename_saves(saves_to_export, container.save_list)

    to_path = utils.join_paths(original_save_path, 'Steam saves')
    utils.make_dir_if_doesnt_exists(to_path)

    Logger.logPrint(
        f'\nExtracting saves {str([i+1 for i in saves_to_export])}')
    Logger.logPrint(f'Container: {container.full_path} Export to: {to_path}',
                    "debug")

    for save_index in saves_to_export:
        save = container.save_list[save_index]

        Scenario.ask_overwrite_save_while_file_exists(save, to_path)
        Scenario.export_save_to_steam(save, original_save_path, to_path)

        Logger.logPrint(f"\nSave {save.name} has been exported succesfully.")
示例#2
0
def ask_copy_target(folder_main_name: str):
    ''' Requests a target folder to the user
    TODO [doc] to explain the folder name format
    Arguments:
        folder_main_name:

    Returns
        ...
    '''
    Logger.logPrint('Where would you like to copy your save folder ?')
    Logger.logPrint('\t1) New folder on my desktop')
    Logger.logPrint("\t2) New folder in a custom path")

    choice = input()
    while choice not in ('1', '2'):
        Logger.logPrint(f'\nPlease choose 1 or 2')
        choice = input()
        Logger.logPrint(f'copy_choice {choice}', 'debug')

    if choice == '1':
        # Winpath is needed here because Windows user can have a custom Desktop location
        save_path = utils.get_windows_desktop_path()
    elif choice == '2':
        Logger.logPrint(f'\nEnter your custom folder path:')
        save_path = input()
        Logger.logPrint(f'save_path {save_path}', 'debug')

    return utils.join_paths(save_path,
                            utils.create_folder_name(folder_main_name))
示例#3
0
 def parse_path(plugin_name, plugin_path):
     """
     Transforms the plugin path (along with the plugin name) into an
     absolute URL, taking into account the location of the plugin folders.
     """ 
     try:
         plugin_path = join_paths([[ConfParser.plugins_path], plugin_name, plugin_path])
     except Exception as e:
         print "[WARNING] Exception parsing settings from section 'paths'. Details: %s" % str(e)
     return plugin_path
示例#4
0
def get_data_set_from_path(path):
    abs_file_path = utils.join_paths(path)
    points_array = []
    with open(abs_file_path, "r") as f:
        whole_line_wo_whitespaces = [line.rstrip() for line in f]
        for line in whole_line_wo_whitespaces:
            array_of_x_label_y = line.split("    ")
            points_array.append(
                handle_any_number_of_spaces(array_of_x_label_y))
    return (points_array)
示例#5
0
 def parse_path(plugin_name, plugin_path):
     """
     Transforms the plugin path (along with the plugin name) into an
     absolute URL, taking into account the location of the plugin folders.
     """ 
     try:
         plugin_path = join_paths([[ConfParser.plugins_path], plugin_name, plugin_path])
     except Exception as e:
         print "[WARNING] Exception parsing settings from section 'paths'. Details: %s" % str(e)
     return plugin_path
示例#6
0
def ask_overwrite_if_file_exists(filename: str, target: str) -> bool:
    file_url = utils.join_paths(target, filename)

    if utils.is_path_exists(file_url):
        do_overwrite = None
        while do_overwrite not in ('y', 'n'):
            Logger.logPrint(
                f'\nFile {filename} already exists, overwrite it ? (y/n)')
            do_overwrite = input().lower()

        return do_overwrite == 'y'
    else:
        return True
def process_net(model, swa_model, model_immutable, train_iter, valid_iter, test_iter, 
                optimizer, criterion, swa_epochs, pretrain_epochs, cpt_filename, 
                swa_lr_set = [0.001, 0.05, 0.1], cycle_length_set = [1, 5, 10], device = 'cpu'):
    print('Training')
    with open(utils.join_paths(csv_directory, cpt_filename + "-" + date + '.csv'), 'w', newline='') as csv_file:
        writer = csv.writer(csv_file)
        writer.writerow(columns)
        train(model, train_iter, valid_iter, optimizer, criterion, pretrain_epochs, device, writer, cpt_filename)
        model_immutable.load_state_dict(copy.deepcopy(model.state_dict()))
    csv_file.close()

    print('SWA Training')

    for swa_lr in swa_lr_set:
        print('LEARNING RATE-{:2.4f}'.format(swa_lr))
        for cycle_length in cycle_length_set:
            with open(utils.join_paths(csv_directory, '{}-SWA-{:03}-{}-{}.csv'.format(cpt_filename, swa_lr, cycle_length, date)), 'w', newline='') as csv_file:
                writer = csv.writer(csv_file)
                writer.writerow(columns)
                print('CYCLE LENGTH-{:03}'.format(cycle_length))
                model.load_state_dict(copy.deepcopy(model_immutable.state_dict()))
                swa_train(model, swa_model, train_iter, valid_iter, optimizer, criterion, pretrain_epochs, swa_epochs,
                          swa_lr, cycle_length, device, writer, cpt_filename)
                test(model, swa_model, test_iter, criterion, device, writer)
示例#8
0
def get_save_folders_from_path(path) -> list:
    microsoft_save_folders = []

    for root, _, files in os.walk(path):
        for file in files:
            if re.search(r'^container\.', file):
                container_full_path = utils.join_paths(root, file)

                Logger.logPrint(f'Container file found:{container_full_path}', 'debug')

                container_text = read_container_text_from_path(container_full_path)

                if do_container_text_match_date(container_text):
                    Logger.logPrint(f'Matching save folder {root}', 'debug')
                    microsoft_save_folders.append(root)

    return microsoft_save_folders
示例#9
0
class ConfParser():

    from localsettings import SRC_DIR
    # Note: surround inside list whenever treated as a unit
    plugins_path = join_paths([SRC_DIR, "python", "plugins"])

    @staticmethod
    def parse_config(plugin_name, path="./settings.conf"):
        """
        Reads and parses every setting defined in the 'settings.conf' within
        the plugin that goes under the name 'plugin_name'.
        """
        ConfParser.plugin_name = plugin_name
        settings = {}
        try:
            confparser = ConfigParser.RawConfigParser()
            confparser.readfp(open(path))
            for section in confparser.sections():
                settings[section] = {}
                for (key, val) in confparser.items(section):
                    # Any Python structure inside a string is to be converted into the desired structure
                    settings[section][key] = ast.literal_eval(val)
                    # Postprocessing: complete content folders with each plugin absolute path (keeps a copy previously)
                    if section == "paths":
                        settings[section]["relative__%s" %
                                          key] = settings[section][key]
                        settings[section][key] = ConfParser.parse_path(
                            plugin_name, settings[section][key])
        except Exception as e:
            print "[WARNING] Exception parsing configuration file '%s'. Details: %s" % (
                str(path), str(e))
        return settings

    @staticmethod
    def parse_path(plugin_name, plugin_path):
        """
        Transforms the plugin path (along with the plugin name) into an
        absolute URL, taking into account the location of the plugin folders.
        """
        try:
            plugin_path = join_paths([[ConfParser.plugins_path], plugin_name,
                                      plugin_path])
        except Exception as e:
            print "[WARNING] Exception parsing settings from section 'paths'. Details: %s" % str(
                e)
        return plugin_path
示例#10
0
    def convert_to_steam(self, source) -> BytesIO:
        """Exports a save to the disk in its Steam file format

        The save is returned in a buffer representing a unique file
        obtained by concatenating all its chunks

        Arguments:
            source: Where to read the chunks of the save

        Returns:
            A buffer containing the Steam save
        """
        buffer = BytesIO()
        for chunk_name in self.chunks_names:
            chunk_file_path = join_paths(source, chunk_name)

            with open(chunk_file_path, 'rb') as chunk_file:
                buffer.write(chunk_file.read())
        return buffer
示例#11
0
    def get_containers_list(path) -> list:
        """
        List all containers in a folder
        Arguments:
            path -- path for search containers
        Returns:
            Returns a list of all containers found (only filename of container)
        Exception:
            None
        """
        folder_content = list_folder_content(path)
        containers_list = [
            file for file in folder_content
            if AstroSaveContainer.is_a_container_file(join_paths(path, file))
        ]

        if not containers_list or len(containers_list) == 0:
            raise FileNotFoundError

        return containers_list
示例#12
0
def ask_copy_target():
    Logger.logPrint('Where would you like to copy your save folder ?')
    Logger.logPrint('\t1) New folder on my desktop')
    Logger.logPrint("\t2) New folder in a custom path")

    choice = input()
    while choice not in ('1', '2'):
        Logger.logPrint(f'\nPlease choose 1 or 2')
        choice = input()
        Logger.logPrint(f'copy_choice {choice}', 'debug')

    if choice == '1':
        # Winpath is needed here because Windows user can have a custom Desktop location
        save_path = utils.get_windows_desktop_path()
    elif choice == '2':
        Logger.logPrint(f'\nEnter your custom folder path:')
        save_path = input()
        Logger.logPrint(f'save_path {save_path}', 'debug')

    return utils.join_paths(save_path,
                            utils.create_folder_name('AstroSaveFolder'))
示例#13
0
def steam_to_windows_conversion(original_save_path: str) -> None:
    Logger.logPrint('\n\n/!\\ WARNING /!\\')
    Logger.logPrint(
        '/!\\ Astroneer needs to be closed longer than 20 seconds before we can start exporting your saves /!\\'
    )
    Logger.logPrint(
        '/!\\ More info and save restoring procedure are available on Github (cf. README) /!\\'
    )
    loading_bar = LoadingBar(15)
    loading_bar.start_loading()

    xbox_astroneer_save_folder = Scenario.backup_win_before_steam_export()

    steamsave_files_list = AstroSave.get_steamsaves_list(original_save_path)

    saves_list = AstroSave.init_saves_list_from(steamsave_files_list)

    original_saves_name = []
    for save in saves_list:
        original_saves_name.append(save.name)

    saves_indexes_to_export = Scenario.ask_saves_to_export(saves_list)

    Scenario.ask_rename_saves(saves_indexes_to_export, saves_list)

    Logger.logPrint(
        f'\nExtracting saves {str([i+1 for i in saves_indexes_to_export])}')
    Logger.logPrint(
        f'Working folder: {original_save_path} Export to: {xbox_astroneer_save_folder}',
        "debug")

    for save_index in saves_indexes_to_export:
        save = saves_list[save_index]
        original_save_full_path = utils.join_paths(
            original_save_path, original_saves_name[save_index] + '.savegame')
        Scenario.export_save_to_xbox(save, original_save_full_path,
                                     xbox_astroneer_save_folder)

        Logger.logPrint(f"\nSave {save.name} has been exported succesfully.")
示例#14
0
    def get_steamsaves_list(path) -> list:
        """List all Steam saves in a folder

        Arguments:
            path -- path where to search for Steam saves

        Returns:
            Returns a list of all Steam saves found (only filenames)

        Exception:
            None
        """
        folder_content = list_folder_content(path)
        steamsaves_list = [
            file for file in folder_content
            if AstroSave.is_a_steamsave_file(join_paths(path, file))
        ]

        if not steamsaves_list or len(steamsaves_list) == 0:
            raise FileNotFoundError

        return steamsaves_list
示例#15
0
def export_save_to_steam(save: AstroSave, from_path: str,
                         to_path: str) -> None:
    target_full_path = utils.join_paths(to_path, save.get_file_name())
    converted_save = save.convert_to_steam(from_path)
    utils.write_buffer_to_file(target_full_path, converted_save)
示例#16
0
def export_save(save, from_path, to_path):
    target_full_path = utils.join_paths(to_path, save.get_file_name())
    converted_save = save.convert_to_steam(from_path)
    utils.write_buffer_to_file(target_full_path, converted_save)
示例#17
0
class PluginLoader():

    # Allows only one instance of this class
    __metaclass__ = Singleton
    plugin_settings = {}
    from settings import SRC_DIR
    # Note: surround inside list whenever treated as a unit
    plugins_path = join_paths([SRC_DIR, "python", "plugins"])

    @staticmethod
    def generate_static_content_urls(media_url=""):
        """
        Crafts URLs for static content (img, css, js) inside plugins.
        Note: content inside plugin is expected to follow the same structure as in settings.MEDIA_URL
        (e.g. '/static/media/default'). The generated URLs will have the associated name X_media_Y,
        where X = {"img","css","js"} and Y = (plugin name)
        """
        from django.conf.urls.defaults import patterns, url
        urlpatterns = []

        # 'plugins_path' already setted before but just checking
        # for format since that is very important
        default_plugins_path = PluginLoader.plugins_path
        if default_plugins_path[0] == "/":
            default_plugins_path = default_plugins_path[1:]
        if default_plugins_path[-1] == "/":
            default_plugins_path = default_plugins_path[:-1]

        for plugin in PluginLoader.plugin_settings:
            for url_type in ["img", "css", "js"]:
                content_route = PluginLoader.plugin_settings.get(plugin).get(
                    "paths").get("relative__%s_dirs" % url_type)
                urlpatterns += patterns(
                    '',
                    #                    url(r'^%s%s/%s/(?P<path>.*)$' % (str(plugin), media_url, url_type),
                    url(
                        r'^%s%s/%s/(?P<path>.*)$' %
                        (str(plugin), media_url, content_route),
                        'django.views.static.serve',
                        #                    {'document_root': "/%s%s%s/%s" % (PluginLoader.plugins_path, str(plugin), media_url, url_type)}, name="%s_media_%s" % (url_type, str(plugin)))
                        {
                            'document_root':
                            "/%s/%s/%s" %
                            (default_plugins_path, str(plugin), content_route)
                        },
                        name="%s_media_%s" % (url_type, str(plugin))))
        return urlpatterns

    @staticmethod
    def load_settings(path=None):
        """
        Entry point for the load of settings. If settings were not already defined, load these.
        """
        try:
            pl = PluginLoader()
            # If settings were already loaded, do not attempt again
            if not pl.plugin_settings:
                if not path:
                    path = pl.plugins_path
                else:
                    pl.set_plugins_path(path)
                PluginLoader.plugin_settings = pl.load_settings_from_folder(
                    path)
        except Exception as e:
            print "[WARNING] There may be some problem with the plugin configuration files. Exception: %s" % str(
                e)
        return PluginLoader.plugin_settings

    def load_settings_from_folder(self, plugins_path="."):
        """
        Iterates over the folders inside the plugins path and loads each
        one's settings in a big dictionary that follows the structure:
        {
            'plugin_name': {
                'section_name': {
                    'attribute_name': 'attribute_value',
                    ...
                },
                ...
            },
            ...
        }
        """
        try:
            for plugin_name in os.listdir(plugins_path):
                if os.path.isdir(os.path.join(plugins_path, plugin_name)):
                    try:
                        plugin_path = os.path.join(plugins_path, plugin_name)
                        plugin_data = self.load_settings_from_plugin(
                            plugin_path)
                        if plugin_data:
                            self.plugin_settings[plugin_name] = plugin_data
                    except:
                        pass
        except:
            pass
        return self.plugin_settings

    def load_settings_from_plugin(self, path="./"):
        """
        Read the plugin's configuration file into a dictionary where each
        section of the config is a sub-dictionary that contains some properties.
        """
        plugin_name = ""
        # Remove last slash to parse data
        if path[-1] == "/":
            path = path[:-1]
        plugin_name = path.split("/")[-1]
        path = path + "/settings.conf"
        return ConfParser.parse_config(plugin_name, path)

    @staticmethod
    def set_plugins_path(plugins_path):
        """
        Sets the folder where plugins are contained.
        """
        PluginLoader.plugins_path = plugins_path
示例#18
0
def export_save_to_xbox(save: AstroSave, from_file: str, to_path: str) -> None:
    chunk_uuids, converted_chunks = save.convert_to_xbox(from_file)

    chunk_count = len(chunk_uuids)

    if chunk_count >= 10:
        Logger.logPrint(
            f'The selected save contains {chunk_count} which is over the 9 chunks limit AstroSaveconverter can handle yet'
        )
        Logger.logPrint(
            f'Congrats for having such a huge save, please open an issue on the GitHub :D'
        )

    for i in range(chunk_count):

        # The file name is the HEX upper form of the uuid
        chunk_name = save.chunks_names[i]
        Logger.logPrint(f'UUID as file name: {chunk_name}', "debug")

        target_full_path = utils.join_paths(to_path, chunk_name)
        Logger.logPrint(f'Chunk file written to: {target_full_path}', "debug")

        # Regenerating chunk name if it already exists. Very, very unlikely
        while utils.is_path_exists(target_full_path):
            Logger.logPrint(f'UUID: {chunk_name} already exists ! (omg)',
                            "debug")

            chunk_uuids[i] = save.regenerate_uuid(i)
            chunk_name = save.chunks_names[i]

            Logger.logPrint(f'Regenerated UUID: {chunk_name}', "debug")
            target_full_path = utils.join_paths(to_path, chunk_name)

        # TODO [enhance] raise exception if can't write, catch it then delete all the chunks already written and exit
        utils.write_buffer_to_file(target_full_path, converted_chunks[i])

    # Container is updated only after all the chunks of the save have been written successfully
    container_file_name = Container.get_containers_list(to_path)[0]

    container_full_path = utils.join_paths(to_path, container_file_name)

    with open(container_full_path, "r+b") as container:
        container.read(4)

        current_container_chunk_count = int.from_bytes(container.read(4),
                                                       byteorder='little')

        new_container_chunk_count = current_container_chunk_count + chunk_count

        container.seek(-4, 1)
        container.write(
            new_container_chunk_count.to_bytes(4, byteorder='little'))

    chunks_buffer = BytesIO()
    for i in range(chunk_count):

        total_written_len = 0

        encoded_save_name = save.name.encode('utf-16le', errors='ignore')
        total_written_len += chunks_buffer.write(encoded_save_name)

        if chunk_count > 1:
            # Multi-chunks save. Adding metadata, format: '$${i}${chunk_count}$1'
            chunk_metadata = f'$${i}${chunk_count}$1'

            encoded_metadata = chunk_metadata.encode('utf-16le',
                                                     errors='ignore')
            total_written_len += chunks_buffer.write(encoded_metadata)

        chunks_buffer.write(b"\00" * (144 - total_written_len))

        chunks_buffer.write(chunk_uuids[i].bytes_le)

    Logger.logPrint(f'Editing container: {container_full_path}', "debug")
    utils.append_buffer_to_file(container_full_path, chunks_buffer)
示例#19
0
def main():

    # user input
    if not g_args.type:
        g_args.type = utils.read_string_input(msg="type",
                                              init_value=DEFAULT_TEMPLATE)
    if not g_args.output:
        g_args.output = utils.read_path_input(msg="file path")
    g_args.author = utils.read_string_input(msg="author",
                                            init_value=g_args.author)
    if not g_args.description:
        g_args.description = utils.read_string_input(
            msg="description", init_value=HEADER_DESCRIPTION)
    g_args.description = format_description(g_args.description)
    if g_args.type != "bash":
        g_args.copy_utils = utils.confirm("Copy utilities?",
                                          "y" if g_args.copy_utils else "n")

    template_path = utils.join_paths_str(g_args.script_dir,
                                         TEMPLATE_OPTIONS[g_args.type])

    if utils.exists_dir(g_args.output):
        print(f"Error: target path is a directory!")
        sys.exit(0)
    elif utils.exists_file(g_args.output):
        if not utils.confirm_delete_file(g_args.output, "n"):
            utils.exit("Aborted")

    out_folder = utils.get_file_path(g_args.output)
    out_file = utils.get_file_name(g_args.output)

    if not utils.exists_dir(out_folder):
        utils.make_dir(g_args.output)

    # copy template
    utils.copy_to(template_path, g_args.output)
    print(f"Created file {g_args.output}")

    if g_args.type == "class":
        utils.replace_file_text(g_args.output, CLASS_NAME, out_file)

    if g_args.type != "bash":
        if g_args.copy_utils:
            utils_folder = PY_UTILS_DIR
            out_py_utils_dir = utils.join_paths(out_folder, utils_folder)
            utils.make_dir(out_py_utils_dir)
            utils.copy_to(PY_UTILS_FILE, out_py_utils_dir)
            print(f"Created file {out_py_utils_dir}/{PY_UTILS_FILE}")
        else:
            print("""
            Important: Please make sure that python utils are available, i.e. inside PYTHONPATH.
            Clone repository via: git clone https://github.com/amplejoe/py_utils.git
            """)

    # header information
    date = utils.get_date_str()
    utils.replace_file_text(g_args.output, HEADER_DATE, date)
    utils.replace_file_text(g_args.output, HEADER_AUTHOR, g_args.author)
    if g_args.description:
        utils.replace_file_text(g_args.output, HEADER_DESCRIPTION,
                                g_args.description)