def load_after_export(): """Read the 'After Export' radio set.""" AFTER_EXPORT_ACTION.set(GEN_OPTS.get_int( 'General', 'after_export_action', AFTER_EXPORT_ACTION.get() ))
def refresh_cache(self): """Copy over the resource files into this game.""" screen_func = export_screen.step copy2 = shutil.copy2 def copy_func(src, dest): screen_func('RES') copy2(src, dest) for folder in os.listdir('../cache/resources/'): source = os.path.join('../cache/resources/', folder) if folder == 'instances': dest = self.abs_path(INST_PATH) elif folder.casefold() == 'bee2': continue # Skip app icons else: dest = self.abs_path(os.path.join('bee2', folder)) LOGGER.info('Copying to "{}" ...', dest) try: shutil.rmtree(dest) except (IOError, shutil.Error): pass shutil.copytree(source, dest, copy_function=copy_func) LOGGER.info('Cache copied.') # Save the new cache modification date. self.mod_time = GEN_OPTS.get_int('General', 'cache_time', 0) self.save() CONFIG.save_check()
def refresh_cache(self): """Copy over the resource files into this game.""" screen_func = export_screen.step copy = shutil.copy def copy_func(src, dest): screen_func("RES") copy(src, dest) for folder in os.listdir("../cache/resources/"): source = os.path.join("../cache/resources/", folder) if not os.path.isdir(source): continue # Skip DS_STORE, desktop.ini, etc. if folder == "instances": dest = self.abs_path(INST_PATH) elif folder.casefold() == "bee2": continue # Skip app icons else: dest = self.abs_path(os.path.join("bee2", folder)) LOGGER.info('Copying to "{}" ...', dest) try: shutil.rmtree(dest) except (IOError, shutil.Error): pass # This handles existing folders, without raising in os.makedirs(). utils.merge_tree(source, dest, copy_function=copy_func) LOGGER.info("Cache copied.") # Save the new cache modification date. self.mod_time = GEN_OPTS.get_int("General", "cache_time", 0) self.save() CONFIG.save_check()
def check_cache(zip_list): """Check to see if any zipfiles are invalid, and if so extract the cache.""" global copy_process from BEE2_config import GEN_OPTS LOGGER.info('Checking cache...') cache_packs = GEN_OPTS.get_int('General', 'cache_pack_count') # We need to match the number of packages too, to account for removed ones. cache_stale = (len(packageLoader.packages) == cache_packs) or any( pack.is_stale() for pack in packageLoader.packages.values()) if not cache_stale: # We've already done the copying.. LOGGER.info('Cache is still fresh, skipping extraction') done_callback() return copy_process = multiprocessing.Process( target=do_copy, args=(zip_list, currently_done), ) copy_process.daemon = True LOGGER.info('Starting background extraction process!') copy_process.start() TK_ROOT.after(UPDATE_INTERVAL, update)
def refresh_cache(self): """Copy over the resource files into this game.""" screen_func = export_screen.step copy = shutil.copy def copy_func(src, dest): screen_func('RES') copy(src, dest) for folder in os.listdir('../cache/resources/'): source = os.path.join('../cache/resources/', folder) if not os.path.isdir(source): continue # Skip DS_STORE, desktop.ini, etc. if folder == 'instances': dest = self.abs_path(INST_PATH) elif folder.casefold() == 'bee2': continue # Skip app icons else: dest = self.abs_path(os.path.join('bee2', folder)) LOGGER.info('Copying to "{}" ...', dest) try: shutil.rmtree(dest) except (IOError, shutil.Error): pass # This handles existing folders, without raising in os.makedirs(). utils.merge_tree(source, dest, copy_function=copy_func) LOGGER.info('Cache copied.') # Save the new cache modification date. self.mod_time = GEN_OPTS.get_int('General', 'cache_time', 0) self.save() CONFIG.save_check()
def check_cache(zip_list): """Check to see if any zipfiles are invalid, and if so extract the cache.""" global copy_process from BEE2_config import GEN_OPTS LOGGER.info('Checking cache...') cache_packs = GEN_OPTS.get_int('General', 'cache_pack_count') # We need to match the number of packages too, to account for removed ones. cache_stale = (len(packageLoader.packages) == cache_packs) or any( pack.is_stale() for pack in packageLoader.packages.values() ) if not cache_stale: # We've already done the copying.. LOGGER.info('Cache is still fresh, skipping extraction') done_callback() return copy_process = multiprocessing.Process( target=do_copy, args=(zip_list, currently_done), ) copy_process.daemon = True LOGGER.info('Starting background extraction process!') copy_process.start() TK_ROOT.after(UPDATE_INTERVAL, update)
def init_backup_settings() -> None: """Initialise the auto-backup settings widget.""" from BEE2_config import GEN_OPTS check_var = tk.IntVar( value=GEN_OPTS.get_bool('General', 'enable_auto_backup')) count_value = GEN_OPTS.get_int('General', 'auto_backup_count', 0) back_dir = GEN_OPTS.get_val('Directories', 'backup_loc', 'backups/') def check_callback(): GEN_OPTS['General']['enable_auto_backup'] = srctools.bool_as_int( check_var.get()) def count_callback(): GEN_OPTS['General']['auto_backup_count'] = str(count.value) def directory_callback(path): GEN_OPTS['Directories']['backup_loc'] = path UI['auto_frame'] = frame = ttk.LabelFrame(window, ) UI['auto_enable'] = enable_check = ttk.Checkbutton( frame, text=_('Automatic Backup After Export'), variable=check_var, command=check_callback, ) frame['labelwidget'] = enable_check frame.grid(row=2, column=0, columnspan=3) dir_frame = ttk.Frame(frame, ) dir_frame.grid(row=0, column=0) ttk.Label( dir_frame, text='Directory', ).grid(row=0, column=0) UI['auto_dir'] = tk_tools.FileField( dir_frame, loc=back_dir, is_dir=True, callback=directory_callback, ) UI['auto_dir'].grid(row=1, column=0) count_frame = ttk.Frame(frame, ) count_frame.grid(row=0, column=1) ttk.Label( count_frame, text=_('Keep (Per Game):'), ).grid(row=0, column=0) count = tk_tools.ttk_Spinbox( count_frame, range=range(50), command=count_callback, ) count.grid(row=1, column=0) count.value = count_value
def cache_valid(self): """Check to see if the cache is valid.""" cache_time = GEN_OPTS.get_int('General', 'cache_time', 0) if cache_time == self.mod_time: LOGGER.info("Skipped copying cache!") return True LOGGER.info("Cache invalid - copying..") return False
def auto_backup(game: 'gameMan.Game', loader: loadScreen.LoadScreen): """Perform an automatic backup for the given game. We do this seperately since we don't need to read the property files. """ from BEE2_config import GEN_OPTS if not GEN_OPTS.get_bool('General', 'enable_auto_backup'): # Don't backup! loader.skip_stage(AUTO_BACKUP_STAGE) return folder = find_puzzles(game) if not folder: loader.skip_stage(AUTO_BACKUP_STAGE) return # Keep this many previous extra_back_count = GEN_OPTS.get_int('General', 'auto_backup_count', 0) to_backup = os.listdir(folder) backup_dir = GEN_OPTS.get_val('Directories', 'backup_loc', 'backups/') os.makedirs(backup_dir, exist_ok=True) # A version of the name stripped of special characters # Allowed: a-z, A-Z, 0-9, '_-.' safe_name = srctools.whitelist( game.name, valid_chars=BACKUP_CHARS, ) loader.set_length(AUTO_BACKUP_STAGE, len(to_backup)) if extra_back_count: back_files = [AUTO_BACKUP_FILE.format(game=safe_name, ind='')] + [ AUTO_BACKUP_FILE.format(game=safe_name, ind='_' + str(i + 1)) for i in range(extra_back_count) ] # Move each file over by 1 index, ignoring missing ones # We need to reverse to ensure we don't overwrite any zips for old_name, new_name in reversed( list(zip(back_files, back_files[1:]))): LOGGER.info( 'Moving: {old} -> {new}', old=old_name, new=new_name, ) old_name = os.path.join(backup_dir, old_name) new_name = os.path.join(backup_dir, new_name) try: os.remove(new_name) except FileNotFoundError: pass # We're overwriting this anyway try: os.rename(old_name, new_name) except FileNotFoundError: pass final_backup = os.path.join( backup_dir, AUTO_BACKUP_FILE.format(game=safe_name, ind=''), ) LOGGER.info('Writing backup to "{}"', final_backup) with open(final_backup, 'wb') as f: with ZipFile(f, mode='w', compression=ZIP_LZMA) as zip_file: for file in to_backup: zip_file.write( os.path.join(folder, file), file, ZIP_LZMA, ) loader.step(AUTO_BACKUP_STAGE)
def init_backup_settings(): """Initialise the auto-backup settings widget.""" from BEE2_config import GEN_OPTS check_var = tk.IntVar( value=GEN_OPTS.get_bool('General', 'enable_auto_backup') ) count_value = GEN_OPTS.get_int('General', 'auto_backup_count', 0) back_dir = GEN_OPTS.get_val('Directories', 'backup_loc', 'backups/') def check_callback(): GEN_OPTS['General']['enable_auto_backup'] = utils.bool_as_int( check_var.get() ) def count_callback(): GEN_OPTS['General']['auto_backup_count'] = str(count.value) def directory_callback(path): GEN_OPTS['Directories']['backup_loc'] = path UI['auto_frame'] = frame = ttk.LabelFrame( window, ) UI['auto_enable'] = enable_check = ttk.Checkbutton( frame, text='Automatic Backup After Export', variable=check_var, command=check_callback, ) frame['labelwidget'] = enable_check frame.grid(row=2, column=0, columnspan=3) dir_frame = ttk.Frame( frame, ) dir_frame.grid(row=0, column=0) ttk.Label( dir_frame, text='Directory', ).grid(row=0, column=0) UI['auto_dir'] = tk_tools.FileField( dir_frame, loc=back_dir, is_dir=True, callback=directory_callback, ) UI['auto_dir'].grid(row=1, column=0) count_frame = ttk.Frame( frame, ) count_frame.grid(row=0, column=1) ttk.Label( count_frame, text='Keep (Per Game):' ).grid(row=0, column=0) count = tk_tools.ttk_Spinbox( count_frame, range=range(50), command=count_callback, ) count.grid(row=1, column=0) count.value = count_value
def auto_backup(game: 'gameMan.Game', loader: LoadScreen): """Perform an automatic backup for the given game. We do this seperately since we don't need to read the property files. """ from BEE2_config import GEN_OPTS if not GEN_OPTS.get_bool('General', 'enable_auto_backup'): # Don't backup! loader.skip_stage(AUTO_BACKUP_STAGE) return folder = find_puzzles(game) if not folder: loader.skip_stage(AUTO_BACKUP_STAGE) return # Keep this many previous extra_back_count = GEN_OPTS.get_int('General', 'auto_backup_count', 0) to_backup = os.listdir(folder) backup_dir = GEN_OPTS.get_val('Directories', 'backup_loc', 'backups/') os.makedirs(backup_dir, exist_ok=True) # A version of the name stripped of special characters # Allowed: a-z, A-Z, 0-9, '_-.' safe_name = utils.whitelist( game.name, valid_chars=BACKUP_CHARS, ) loader.set_length(AUTO_BACKUP_STAGE, len(to_backup)) if extra_back_count: back_files = [ AUTO_BACKUP_FILE.format(game=safe_name, ind='') ] + [ AUTO_BACKUP_FILE.format(game=safe_name, ind='_'+str(i+1)) for i in range(extra_back_count) ] # Move each file over by 1 index, ignoring missing ones # We need to reverse to ensure we don't overwrite any zips for old_name, new_name in reversed( list(zip(back_files, back_files[1:])) ): LOGGER.info( 'Moving: {old} -> {new}', old=old_name, new=new_name, ) old_name = os.path.join(backup_dir, old_name) new_name = os.path.join(backup_dir, new_name) try: os.remove(new_name) except FileNotFoundError: pass # We're overwriting this anyway try: os.rename(old_name, new_name) except FileNotFoundError: pass final_backup = os.path.join( backup_dir, AUTO_BACKUP_FILE.format(game=safe_name, ind=''), ) LOGGER.info('Writing backup to "{}"', final_backup) with open(final_backup, 'wb') as f: with ZipFile(f, mode='w', compression=ZIP_LZMA) as zip_file: for file in to_backup: zip_file.write( os.path.join(folder, file), file, ZIP_LZMA, ) loader.step(AUTO_BACKUP_STAGE)