Module importer
This is a silly but useful tool to import stuff automatically in renpy, mostly designed to be customizable in most of the cases and save you some time renaming and moving files/folder in your game, horiented for large game with a bunch of files…
this is mostly a CLI tool, but it can also be used as an external lib… most of the times
check each function docs and study their behavior as you want, it's not like I can't do much about it
just hope you like it and give me a star in github… and since you are there, follow me!
How to use (easy tutorial)
Setup
- download the tool and place in the folder relative to
./game(or basically in your renpy game's proyect) - ensure you have python between 3.13 and 3.14 (since one of our core functions only exits in 3.14 and low versions but it was marked for removal in 3.15, and its alternative sucks)
- install typing_extensions, since it one of our main dependencies
- once installed, you are ready to go the next section
Basic commands
if you follow the folder structure, you should only use
$ python importer.py --set-game ./game --enable-common
otherwise, you should check the commands section, or just use
$ python importer.py -h
to get more info about commands, since the commands only covers case-of-use, but it doesn't actually explains why the commands, we consider their names are very explicit
Details
Compilation (recommend for windows): auto-py-to-exe >= 2.45.1
Python:
Originally 3.13.2 (Microsoft store)
This version was created with 3.14.0t (yes, free threads)
Code structure:
Main imports
Metadata related
Enums
Language service
Secundary / optional imports
Constants
Functions
Utils
Path realted
Specifics 1
Writers
Specifics 2 (now it's personal)
Scanners
Imports
Entry point
Code: single file
Docummentation: pydoc3 >= 0.11.6
Depencencies
Third-party libs
| name | version | is optional? | why? |
|---|---|---|---|
| colorama | >= 0.4.6 | ✅ | just to get colors to the console |
| pillow | >= 12.0.0 | ✅ | to create side images |
| platformdirs | == 4.5.0 | ✅ | to get the equivalent to appdata folder in many OS as possible |
| pyminizip | >= 0.2.6 | ✅ | to create zip file using a single function |
| tqdm | >= 4.67.1 | ✅ | same as colorama, but for lists |
| typing_extensions | >= 4.15.0 | ❌ | typing.......... |
| Whoosh | >= 2.7.4 | ✅ | weight light search engine |
| pydoc3 | >= 0.11.6 | ✅ | to create this doc |
Python build-in (from 3.13.2 to 3.14.0t)
| name | version |
|---|---|
| sys | (build-in) |
| logging | (build-in) |
| warnings | (build-in) |
| plataform | (build-in) |
| os | (build-in) |
| enum | (build-in) |
| collections | (build-in) |
| locale | (build-in) |
| argparse | (build-in) |
| shutil | (build-in) |
| functools | (build-in) |
| pathlib | (build-in) |
| json | (build-in) |
| configparser | (build-in) |
Naming
Due to the design of the following code, the following variables are designated for naming and/or modifying the structure. This was designed to be "portable" and based on the "black box" concept (you have an input and an output, but you don't know what happens inside). Therefore, any function must follow the following "rules," and there are exceptions to these.
Note
Every function or class must specify the expected data type and the returned data type, always
GET Functions
These functions should be as small as possible. If two or more of these functions are related in their operation, then they should share as much size as possible. Generally, they should get:
get_{kind}_{what it does}_{where or how}Generally, a getter function should only have a minimum of two of these parts and no more. Exceptions to this rule are functions whose purpose is very simple or whose operation is literally defined by the function's name.
MKR Functions
These are functions whose purpose is to "create" something within the machine, whether it's manipulating files or directories. They generally have 2 or 3 words (maximum-minimum) following the structure below:
mkr_{what}_{type}
Functions ADD/DEL/RM/SAVE/LOAD
These are actually extra functions whose names cannot exceed two words and must be specific to their function. The documentation for these functions MUST be shorter and simpler, as they are extra.
IMPORT Functions
most of the time, these function are mean to be shortcuts for all other functions, calling of these is the equivalent to do a proccess, since behind, these function automatically fullfill all possible requirements for a procces to be made
SCAN Functions
basically, the only job of this kind of functions is to scan something, search for patterns, and return what they found, their structure consists of:
scan_{what or type}_{where or how}just like get functions, there might be exception to this rule
WRITE Functions
these function can't do much, other than recollect data and print/save into a file, most of the times their objective should gather the requiriments for other functions be done and check their viability before perform any procces
Other Functions
Most functions are already covered. You can add more if you wish, but you must update this header to keep the documentation current.
Folder structure
First of all, this tool was designed to be effort-less for beginers to use, to this might be something we would like game that use this tool to implement as their own folder structure
so, renpy basically have all their game in the folder with same name (./game), which we call game data, where all chapters (renpy files were the story
takes place) and assets are placed, we believe in a folder structure similar to some games, where:
every asset will go to an assets folder (DEFAULT_RESOURCE_PATH), where all of them are saved in different folders, such as
- audio (
DEFAULT_PATH_SOUND) - video (
DEFAULT_PATH_VIDEO) - images (
DEFAULT_PATH_IMAGE) - fonts
- etc
if you do something like
game/
| |
| | assets/
| | |
| | | audio/
| | | | folder A
| | | | folder B
| | | | folder C
| | | | my_song.mp3
| | | | my_song.wav
| | | video/
| | | | folder A
| | | | folder B
| | | | folder C
| | | | my_video.mp4
| | | | my_song.ogv
the tool will work automatically to import the files for you, you don't need to specify --set-audio or --set-video for the path, since (as mention before),
they are already declared (you can change them later if ya want, but that might require you to change the script)
but, there's a detail about background and sprites, due how they are organized and how different they are between games,
we separate them into their own commands (--set-sprite and --set-background to be precise), yet, the same can apply, given us
something like:
game/
| |
| | assets/
| | |
| | | images/
| | | | characters/
| | | | |
| | | | | character folder A
| | | | | character folder B
| | | | | character folder C
| | | | background/
| | | | |
| | | | | background folder A
| | | | | background folder B
| | | | | background folder C
ended up being something like this when using the whole folder structure
game/
| |
| | assets/
| | |
| | | audio/
| | | | folder A
| | | | folder B
| | | | folder C
| | | | my_song.mp3
| | | | my_song.wav
| | | video/
| | | | folder A
| | | | folder B
| | | | folder C
| | | | my_video.mp4
| | | | my_song.ogv
| | | images/
| | | | characters/
| | | | |
| | | | | character folder A /
| | | | | |
| | | | | | image A.png
| | | | | | image B.png
| | | | | character folder B
| | | | | character folder C
| | | | background/
| | | | |
| | | | | background folder A /
| | | | | |
| | | | | | image A.png
| | | | | | image B.png
| | | | | background folder B
| | | | | background folder C
| | |fonts /
| | | | font A.ttf
| | | | font B.ttf
| | | | font C.ttf
and so, basically, using a structure like ./game/assets, where ./game is our setted game data folder (using --set-game) will
make this whole procces more easy to use and for you even more organized if you are starting....
yet, if your proyect already have certain structure, you might consider modify DEFAULT_RESOURCE_PATH, DEFAULT_PATH_VIDEO,
DEFAULT_PATH_SOUND and DEFAULT_PATH_IMAGE to make the tool do something similar to the procces describe adove and make it more
automated, or just use the --set-[something] commands to indicate that manually, it's up to you
Commands
Note
better use -h or --help to get the full explanation of each command
$ python importer.py -h
Cases
- Case 1: I want to use custom folders due how my proyect is structured
$ python importer.py -s-ass ./game -s-sprite ./game/image/sprites -s-background ./game/backgrounds --enable-common
here we are using -s-sprite and -s-background to set manually their folders, the same could be using the audio or video variants of -s-[something] command
and don't forget about the --enable-common to create the common files
- Case 2: I want to create side images, but no common files
$ python importer.py -s-ass ./game -s-sprite ./game/image/sprites -s-background ./game/backgrounds --enable-sides
and note that if you use both, --enable-common and --enable-sides this will first create the sides images and then create common file
- Case 3: I want to rename some file and create common files after that
$ python importer.py -s-ass ./game -s-sprite ./game/image/sprites -s-background ./game/backgrounds --enable-common --enable-renamer
before even create the common file, the tool will enter into a simple interface asking you to provide the names, then select an option and confirm a new name for the file, once done, this will change ALL part where this image was used, this include audio, video, images, backgrounds, side variants and more!
Once done, it will create the common file, even if you don't enable --enable-common, this is because once the file is renamed, there's no way for renpy be sure
if this change was mode, so we really need that change be done, either if it's needed or not, so we make sure the changes are applied
Error codes
Basically, if the tool is executed as a CLI (Command Line Interface), these commands will be what it will return being:
- 0: Everything is good
- 1: missing required lib/dependency
- 2: incorrect python version
- 3: unkwon error
Changelog
17/02/2025
- added more formats
- most of the code is documented and the tool is mostly funcionable
- almost production version
10/03/2025
- added progress bars
- added new commands
- added new encryption functions
- added some eastern eggs
- fixed plataform dependencies and compatibility
- fixed minor bugs during compilation phase
- improve JSON import system and templates
- improve arguments parse function
- new search and import system
- code formatted under "black" formatting
- finish docummention
05/12/2025
- added multiplataform support
- added a better logging system
- added new functions and template system
- added more validations about paths during the whole creation
- added a better configuration file
- added some self-made alternatives to some third party dependencies
- added enums to represent constant data within the tool
- added even more docs and external links for more info
- changed the
frame()andhandler()function to represent what the actual flow is - changed the way the tool flow works
- changed the file structure
- changed the common.rpy workflow to make it more clear and stable
- improved language system (it still needs some minor improments, but it's the final version)
- improved importer and side generation system
- fixed some tricks to make
tqdmworks as expected - fixed minor bugs due how side images were originally planned
- fixed some arguments bugs
- deleted all eastern eggs (for now)
- finally the searcher feature works properly (yet with some bugs due how the path is now handle)
hope this maskes sence XD
Global variables
var BUILDIN_ANIMATION_KEYS : dict[TemplateKeys, list[str]]-
About
basically, this controlls when used some template based on their names (if includes some keywords or not)
here we use a
keyto represent a template withinTemplateKeys, and alist[str]to represent a collection of keywords thatis_animated_name()will make use to indicate if it's animated or not var BUILDIN_FILE_TEMPLATES : dict[TemplatePath, str]-
About
basically this defines how the file part of the template from
BUILDIN_TEMPLATESorFORMATS_IMPORTEDis using almost the same structure, but with differenceswhich basically are adding certain keyword/extension extras to the file.
TODO
make the function
get_name_template()or once finished the 1st assets import validate the file usinghandler()(?)check
BUILDIN_TEMPLATES, in their "keywords" section to know about how the format worksInformation Table
Keyword Meaning path the whole or simpliest path from a certain origin file the file that is being tested var BUILDIN_TEMPLATES : dict[TemplateKeys | str, str | list[str | bool | list[str]]]-
About
This is one of the core variables for this tool, because it basically defines how the template for each
TemplateKeysor new key should beKeywords
how it works is basically using the % operator to replace more easily certain keywords, when the tool reach
mkr_lines_list()function, based on whatwrite_names()and the modes based onTemplateKeys,ProccesKeywords,TemplatePathKeysandParseKeywordsare configured, alongside withFeaturesKeywordsandImportKeywordsconfigured, one or several templates will be used, we reserve the next ones seening in the information table, and also take a look at the examples, but take into account these are examples assuming certain configurationsthe real ones might be different from what is showed here, and each one of the next keyword must be used like the next example (and also this should the form that your custom templates might have):
{ "normal" : 'image %(name)s = "%(path)s"\n' }the example from adove is an extract from the default
BUILDIN_TEMPLATESreference template, ofc your might be differentand well… here is the information you might be looking for
Information Table
Keyword Meaning name represents the most simple part of the file which is being parsed by get_name_parsed()path this is the easiest and most simple part of the path, this starts from DEFAULT_RESOURCE_PATHorArgumentsGiven.game'till the path's end, mostly they are parsed as posix (/) and then normalized byget_path_parsed()(under normal circunstance, check the folder structure for more info)size_scale this represent the target's screen deimension, this should a Heigh__x__width ( DEFAULT_SIZE_SCREEN) or atuple[int, int], (anyway, they will parsed like the output says)size_side similar to the other, but this time represents the side's frame ( DEFAULT_SIZE_SIDE_VAR)abbr this the short form of name, but, this will be created using the folder's name or character.rpy (mostly depends on get_name_acron())file it's the same as path, but fixed with TemplatePath, which either case, might change depends on this last modekind this feature depends on a modded SDK (which support the encription system), basically this repreent a literal value from ImportKeywordstab this is basically a " " * DEFAULT_TABoperationA bit of side note, when one of the values is a
list, we don't know how to how to determine if it's an animated template, since a list might be also a non-animated template so, the first argument must always be True or False to indicate that, and if it is an animated template, it can useImageConfigValue.REPEATto enter into a loop to repeat certain statement, motly when dealing with multiple filesCaution
most of their behavior depends on multiple variable, the examples of below were made considering the most simpliest flags, being
ParseKeywords.FILE,ImportKeywords.IMAGESandTemplatePath.NORMALin a sprite folder with aDEFAULT_TABof 4Example Table
Keyword Input Output name hello_world.png hello_world path C:/Users/[USER]/Desktop/awesome-game/game/assets/images/Sprites/Xellar assets/images/Sprites/Xellar size_scale 1920x1080 or (1920, 1080) 1920, 1080 size_side 300x350 or (300, 350) 300, 350 file ArgumentsGiven.sprite/Xellar/xellar_normal.pngArgumentsGiven.sprite/Xellar/xellar_normal.pngtab 4 "----" var DEFAULT_EXTEND_IMAGE_NOT_SUPPORT : list[str]-
extension of file that are not actually supported (images this case), yet, this doesn't means renpy can't, check the renpy docs
var DEFAULT_EXTEND_IMAGE_SUPPORT : list[str]-
extension of file that are actually supported (images this case), yet, this doesn't means renpy can, check the renpy docs
var DEFAULT_EXTEND_SOUND_NOT_SUPPORT : list[str]-
extension of file that are not actually supported (sound this case), yet, this doesn't means renpy can't, check the renpy docs
var DEFAULT_EXTEND_SOUND_SUPPORT : list[str]-
extension of file that are actually supported (sounds this case), yet, this doesn't means renpy can, check the renpy docs
var DEFAULT_EXTEND_VIDEO_NOT_SUPPORT : list[str]-
extension of file that are not actually supported (videos this case), yet, this doesn't means renpy can't, check the renpy docs
var DEFAULT_EXTEND_VIDEO_SUPPORT : list[str]-
extension of file that are actually supported (videos this case), yet, this doesn't means renpy can, check the renpy docs
var DEFAULT_KIND_IMPORT : Literal['source', 'dev', 'zip']-
controll the template used
var DEFAULT_NAME_LIMIT : int-
controll the times limit for the tool find the character.rpy file to get the alias from some character
var DEFAULT_PATH_IMAGE : str-
default folder to search for images, check folder structure for more info
var DEFAULT_PATH_SIDE : str-
default folder to add side variants (once created), this will use of
DEFAULT_PATH_IMAGE/[etc]/[sprite/character]/DEFAULT_PATH_SIDE var DEFAULT_PATH_SOUND : str-
default folder to search for audio, check folder structure for more info
var DEFAULT_PATH_VIDEO : str-
default folder to search for videos, check folder structure for more info
var DEFAULT_RESOURCE_PATH : str-
default folder to search for assets, check folder structure for more info
var DEFAULT_SIZE_CORP_VAR : tuple[int, int, int, int]-
default dimensions to cut from an image
var DEFAULT_SIZE_SCREEN : str-
default target's screen dimension
var DEFAULT_SIZE_SIDE_VAR : str-
default target's frame used by side variants
var DEFAULT_TAB : int-
controll how the tool detect lines within the renpy files (hope you use tabs.... please… use TABs)
var FILE_NAME_REPLACE : dict[int, str]-
a list of symbols that we hate and they must be replaced at once!
var FILE_NAME_REPLACE_LONG : dict[str, str]-
a list of symbols to resume some names (when used) to not match with renpy keyword/reserved words
this material is old, but it cover the basics of why this variable
var FORMAT : str-
The format used by the logger
logger var FORMATS_IMPORTED : dict[TemplateKeys | str, str | list[str]]-
The actual variable that the tool will make use, not what
BUILDIN_TEMPLATES, that's just the default implementation in caseRequiredFiles.TEMPLATEScouldn't be foundsee
BUILDIN_TEMPLATESfor more info, since the structure it's pretty much the same var IGNORE_NOT_SUPPORTED : bool-
controll if ignore not supported files (basically supress some warnings)
var IMAGE_KEYWORDS : list[str]-
Basically this is used as reference by
scan_lines_chapters()to differenciate certain statements within the renpy language alonside withSOUND_KEYWORDS var KEYS_IMPORTED : dict[TemplateKeys, list[str]]-
The actual variable that the tool will make use, not what
BUILDIN_ANIMATION_KEYS, that's just the default implementation in caseRequiredFiles.ANIMATEDcouldn't be foundsee
BUILDIN_ANIMATION_KEYSfor more info, since the structure it's pretty much the same var RESERVED_GENERIC_CREA_EXTEN : tuple[str]-
a silly collection of extensions used by the tool
var RESERVED_GENERIC_CREA_NAMES : tuple[str, str, str]-
a silly collection of file names used by the tool
var RESERVED_GENERIC_FILE_EXTEN : list[str]-
a silly collection of reserved extension (mostly by renpy or by the tool)
var RESERVED_GENERIC_FILE_NAMES : tuple[str, str, str, str, str, str]-
a silly collection of reserved files that the tool will make use of
var RESERVED_GENERIC_FOLD_NAMES : tuple[str, str, str, str]-
a silly collection of reserved folder names
var ROOT_EXE_GAME : pathlib._local.Path-
the root folder (usually the same as where the tool is)
var ROOT_RES_SOFT : pathlib._local.Path-
the data folder (in windows, basically appdata/
__product__/__author__) var SKIP_EXTENSION : list[str]-
the same as
SKIP_GEN_NAMES, but it's limited to extensions names var SKIP_FILE_NAME : list[str]-
the same as
SKIP_GEN_NAMES, but it's limited to file names var SKIP_FOL_NAMES : list[str]-
the same as
SKIP_GEN_NAMES, but it's limited to folder names var SKIP_GEN_NAMES : list[str]-
a collection of names, this is totally independement from its type
var SKIP_SYMBOLS : list[str]-
a series of single-characters, mostly used when the name of something start, this will controll if this will be skiped
var SOUND_KEYWORDS : list[str]-
Basically this is used as reference by
scan_lines_chapters()to differenciate certain statements within the renpy language alonside withIMAGE_KEYWORDS var features_available : list[str]-
A silly collection of features that saves all available/ready to add features
var features_enabled : list[str]-
the same as
features_available, but when enabled var language : str-
the selected language, by default
os_languageis used, otherwise enligsh by default var languages : dict[str, dict[str, str]]-
The dictonary used by the language service, and this is a buildin variable that basically saves all of them
a file could be better, but might limit the tool
var logger : logging.Logger-
the logger, the files will be saved within the same level as where the tool is, this might be called importer.log
var os_language : str-
the detected os language (thanks to
getdefaultlocale) var parser : argparse.ArgumentParser-
mostly used when the tool is main
Functions
def add_feature(what: FeaturesKeywords,
is_internal: bool = True) ‑> bool-
Add a feature based on
FeaturesKeywordsand return if it was addedArgs
what:FeaturesKeywords- the feature to enable
is_internal:bool, optional- determine if use
features_availableorfeatures_enabledto add the feature. Defaults to True.
Returns
bool- was it added?
def add_jump(base: list) ‑> list[str]-
this parses
baseto alist[str]adding \n charactersArgs
base:list- base
Returns
list[str]- parsed base
def del_jump(base: list[str], allow_blank: bool = False) ‑> None-
Delete \n and \r spaces and tab if possible
Args
base:list[str]- a list of lines to delete those keysfrom
allow_blank:bool, optional- allow tabs don't be deleted. Defaults to False.
def frame(parser: argparse.ArgumentParser)-
Basically the entry point to start the tool using the default arguments
Args
parser:ArgumentParser- the parser object (if you have one created)
def get_list_file_extended(extension: str | list[str],
is_normal: bool = True,
*,
origin: pathlib._local.Path = WindowsPath('.'),
local: list[str] = []) ‑> list[str]-
similar to
get_list_system_file(), but this should those files that match their extension with what is being expectedArgs
extension:str | list[str]- collection of extensions
is_normal:bool, optional- return reserved resources or not, not both. Defaults to True.
origin:Path, optional- origin path. Defaults to Path(".").
local:list[str], optional- collection of names, in case you already have the files. Defaults to [].
Returns
list[str]- those names that matched
extensionlist
def get_list_file_named(names: str | Sequence[str] | dict[str | Sequence[str]],
is_normal: bool = True,
*,
origin: pathlib._local.Path = WindowsPath('.'),
local: list[str] = []) ‑> list[str]-
Similar to
get_list_system_file(), but for namesArgs
names:str | Sequence[str] | dict[str | Sequence[str]]- collection of names
is_normal:bool, optional- return reserved resources or not, not both. Defaults to True.
origin:Path, optional- origin path. Defaults to Path(".").
local:list[str], optional- collection of names, in case you already have the files. Defaults to [].
Returns
list[str]- those names that matched
namescollection
def get_list_files(names: list[str],
extesions: list[str],
is_normal: bool = True,
origin: pathlib._local.Path = WindowsPath('.'),
local: list[str] = []) ‑> list[str]-
This is just a shortcut that evaluate names and then extensions for a collection of files
Args
names:list[str]- collection of names
extesions:list[str]- collection of extensions
is_normal:bool, optional- return reserved resources or not, not both. Defaults to True.
origin:Path, optional- origin path. Defaults to Path(".").
local:list[str], optional- collection of names, in case you already have the files. Defaults to [].
Returns
list[str]- those names that matched the given criteria
def get_list_namesimple(origin: pathlib._local.Path = WindowsPath('.')) ‑> list[str]-
Get the simple part of origin and return it as
list[str]Args
origin:Path, optional- starter path. Defaults to Path(".").
Returns
list[str]- simple part
def get_list_subfolders(origin: pathlib._local.Path = WindowsPath('.'), exclude: Sequence[str] = []) ‑> list[str | pathlib._local.Path]-
This will recursible get folders and its subfolders within
originbased onget_list_system_file()Args
origin:Path, optional- starter path. Defaults to Path(".").
exclude:Sequence[str], optional- exclode some name. Defaults to [].
Returns
list[str | Path]- all folders/subfolders within
origin
def get_list_system_dirs(origin: pathlib._local.Path = WindowsPath('.'),
kind: Literal['dir', 'file', 'both'] = 'file',
**kwargs) ‑> list[str | list[str]]-
Based on
origin, this will get all files based onkindwithout any filter, whatever is inorigin, this will returnArgs
origin:Path, optional- the origin path. Defaults to Path(".").
kind:_literal_fields_files, optional- the resource type that will return. Defaults to "file".
Returns
list[str | list[str]]- a list of file/folders or both
def get_list_system_file(kind: Literal['dir', 'file', 'both'],
origin: pathlib._local.Path = WindowsPath('.'),
is_normal: bool = True) ‑> list[str | list[str]]-
similar to
get_list_system_dirs(), but applyingis_reserved()function to determine that, you can get if the function return reserved stuff or not based onis_normalparam, but this shouldn't return both, better useget_list_system_dirs()to get both of themArgs
kind:_literal_fields_files- resource type
origin:Path, optional- origin path. Defaults to Path(".").
is_normal:bool, optional- return reserved resources or not, not both. Defaults to True.
Returns
list[str | list[str]]- collection of files/folders/both
def get_message_translated(name: str, /, **kwargs: dict[str, str]) ‑> strdef get_name_acron(limit: int = 3, origin: pathlib._local.Path = WindowsPath('.')) ‑> str-
get the short or acronimun name for a character based either in their folder if the character.rpy couldn't be found… or the character.rpy file itself
Args
limit:int, optional- limit of try to get the name before parse the folder. Defaults to 3.
origin:Path, optional- starter path. Defaults to Path(".").
Returns
str- the shortest name possible (if declared) or the folder's name
def get_name_parsed(file: str) ‑> str-
Given a
file's name, this will parse it into something pretty simple, replacing and deleting numbers if neededExamples
input output Xellar normal speak.png xellar_normal_speak Xellar normal speak 1.png xellar_normal_speak_1_base Xellar!normal!speak.png xellar_normal_speak Args
file:str- file
Returns
str- file parsed
def get_name_template(file: str,
path: str,
mode: ParseKeywords,
limit: int = 3) ‑> tuple[str, str]-
Given the file and path, this will parse it base in the selected mode, this has a limit of character that you can customize with the
limitparameterthe return mostly depends on
BUILDIN_FILE_TEMPLATESvarArgs
file:str- file
path:str- path
mode:ParseKeywords- mode based in
ParseKeywords. limit:int, optional- limit of characters. Defaults to
DEFAULT_NAME_LIMIT.
Returns
tuple[str, str]- the file and path parsed by
ParseKeywords
def get_path_parsed(start: str | list[str], origin: pathlib._local.Path = WindowsPath('.')) ‑> str-
Based on a certain start keywords, this will cut
originand return its path if exits, otherwise, it'll returnoriginas posixExamples
here start is
["assets", "images"]when a good caseinput output C:/Users/[USER]/Desktop/awesome-game/game/assets/images/Sprites/Xellar assets/images/Sprites/Xellar here start is
["images"]when a good caseinput output C:/Users/[USER]/Desktop/awesome-game/game/assets/images/Sprites/Xellar images/Sprites/Xellar here start is
["assets", "images"]when a bad case- Example 1
input output C:/Users/[USER]/Desktop/awesome-game/game/images/Sprites/Xellar C:/Users/[USER]/Desktop/awesome-game/game/images/Sprites/Xellar - Example 2
input output C:/Users/[USER]/Desktop/awesome-game/game/assets/Xellar C:/Users/[USER]/Desktop/awesome-game/game/assets/Xellar Args
start:str | list[str]- collection of parts/folders to cut from
origin:Path, optional- starter path. Defaults to Path(".").
Returns
str- parsed
originORoriginas posix
def given_path(path: str) ‑> pathlib._local.Path-
just a silly function to check if the given path exits
Args
path:str- a path
Raises
ValueError- raised if the path doesn't exits
Returns
Path- the path as object
def handler(origin: ArgumentsGiven)-
Basically a handler that after
frame()was used, checks for the origin arguments and perform certain proccessArgs
origin:ArgumentsGiven- a bunch of arugments
def has_feature(what: FeaturesKeywords,
is_internal: bool = True) ‑> bool-
Check if the feature is enabled or can exits
Args
what:FeaturesKeywords- the feature
is_internal:bool, optional- determine if use
features_availableorfeatures_enabled. Defaults to True.
Returns
bool- has the feature?
def has_required_keys(base: list[str], reference: enum.StrEnum) ‑> bool-
Check if all
basekeys exits inreference, which is a enumArgs
base:list[str]- base
reference:StrEnum- reference enum
Returns
bool- ¿all
baseexits inreference
def import_audio(origin: pathlib._local.Path = WindowsPath('.'), single: bool = False) ‑> None-
Entry point to import stuff from
DEFAULT_PATH_SOUNDfolderArgs
origin:Path, optional- patyh starter. Defaults to Path(".").
single:bool, optional- limit
write_common_file()to only the origin. Defaults to False.
def import_backgrounds(origin: pathlib._local.Path = WindowsPath('.')) ‑> None-
Entry point to import stuff from
DEFAULT_PATH_IMAGEfolder, but for backgroundArgs
origin:Path, optional- patyh starter. Defaults to Path(".").
def import_sprites(origin: pathlib._local.Path = WindowsPath('.'), single: bool = False)-
Entry point to import stuff from
DEFAULT_PATH_IMAGEfolder, but for spritesArgs
origin:Path, optional- patyh starter. Defaults to Path(".").
single:bool, optional- limit
write_common_file()to only the origin. Defaults to False.
def import_video(origin: pathlib._local.Path = WindowsPath('.'), single: bool = False) ‑> None-
Entry point to import stuff from
DEFAULT_PATH_VIDEOfolderArgs
origin:Path, optional- patyh starter. Defaults to Path(".").
single:bool, optional- limit
write_common_file()to only the origin. Defaults to False.
def is_animated_name(name: str) ‑> TemplateKeys | None-
checks if the name is animated and return the key that corresponds to
TemplateKeys, none if failsArgs
name:str- name to evaluate
Returns
TemplateKeys | None- result
def is_reserved(name: str, kind: Literal['dir', 'file', 'both'] = 'file') ‑> bool-
check if the given name is reserved by the tool or not, based on
kind, will useRESERVED_GENERIC_FOLD_NAMESorRESERVED_GENERIC_FILE_NAMESand its skip variablesArgs
name:str- to match
kind:_literal_fields_files, optional- resource type. Defaults to "file".
Returns
bool- is reserved?
def mkr_dir(what: str,
root: pathlib._local.Path | str = WindowsPath('C:/Users/Z3R0_GT/Desktop/Repos/renpy-auto-importer')) ‑> pathlib._local.Path-
Basicallt this create the given
whatfolder and return the path to itNote
this will not evaluate if the given path really exits
Args
what:str- folder(s) to create
root:Path | str, optional- actual path. Defaults to
ROOT_EXE_GAME.
Returns
Path- root / what with the path already created
def mkr_lines_list(simple_path: str,
abbr: str,
files: list[str],
modes: list[str],
folder: pathlib._local.Path = WindowsPath('.')) ‑> list[str]-
This function works better when
write_common_file()call it, yet, you can still used, this requires the simple path fromorigin(which you can get usingget_path_parsed()), the abbreviation (usingget_name_acron()) and the list of files within the simple path, this must be name only the file's name, or folder(s) + file relative toorigin(or the same, simple_path)for more info about modes, check
write_common_file()where it's better explainedand folder which is used to validate simple_path
Args
simple_path:str- the simpliest representation of a path, being (for example) assets/image/Xellar
abbr:str- abbreviation of the folder
files:list[str]- a collection of files
modes:list[str]- modes to work with (based in different enums)
folder:Path, optional- the actual folder. Defaults to Path(".").
Raises
TypeError- raised if some template within
FORMATS_IMPORTEDis incorrect formatted or is an unsupported object type
Returns
list[str]- a collection of lines that represent the declaration of a common.rpy file
def mkr_str(base: list, sep: str = '') ‑> str-
this parses a
baseto a simplestrusing thesepArgs
base:list- base
sep:str, optional- separator. Defaults to "".
Returns
str- parsed base
def rm_defaults(origin: pathlib._local.Path = WindowsPath('.')) ‑> None-
Remove those files reserved by the tool (to avoid overwriting the same data or duplicates)
Args
origin:Path, optional- starter path. Defaults to Path(".").
def scan_file_compressed(kind: Literal['image', 'sound', 'video'] = 'image',
origin: pathlib._local.Path = WindowsPath('.')) ‑> bool-
Scan the actual
originand report those files that needs compressionArgs
kind:_literal_fields_exten, optional- resource type. Defaults to "image".
origin:Path, optional- starter path. Defaults to Path(".").
Returns
bool- does
originhave some file that needs compression?
def scan_folder_for(folder: str,
origin: pathlib._local.Path = WindowsPath('.'),
is_normal: bool = True) ‑> bool-
Scan for a certain folder starting from
origin, useis_normalto indicate if it's reservedArgs
folder:str- target folder
origin:Path, optional- starter path. Defaults to Path(".").
is_normal:bool, optional- return reserved resources or not, not both. Defaults to True.
Returns
bool- was founded?
def scan_lines_chapters(aliases: list[str], origin: pathlib._local.Path = WindowsPath('.')) ‑> dict[str, dict[str, dict[str, list[int]]]]-
This basically takes those chapter files and look for certain statements that used resources (like images, sound, video, etc…) and register their locations for later use, the origin should be data folder (or basically ./game) folder
the structure is basically
{ "file": { "resource type": { "statement": [0, 2, 3] } }#where each number is where the statement is being used }Args
aliases:list[str]- mostly belongs to character
origin:Path, optional- path starter. Defaults to Path(".").
Returns
dict[str, dict[str, dict[str, list[int]]]]- the representation of info
def scan_lines_common(origin: pathlib._local.Path = WindowsPath('.')) ‑> dict[pathlib._local.Path, list[str]]-
Basically this will search trought the whole
DEFAULT_RESOURCE_PATHfolder to look for commmon files, get their content and then save their definitions individually in the form of{ "path/to/common/file": [ "define xellar = ....", "define xellar_happy = ...." ] # and so for each thing }this for later use
Args
origin:Path, optional- path starter. Defaults to Path(".").
Returns
dict[Path, list[str]]- all files with their contents
def scan_subfolder_do(what: Callable[[pathlib._local.Path], list[T]],
*args,
exclude: Sequence[str] = [],
origin: pathlib._local.Path = WindowsPath('.'),
**kwargs) ‑> list[T]-
Scan between folders and do something while that, this will also send args and kwargs to the
whatfunction each timeArgs
what:Callable[[Path], list[T]]- function that will be called per folder, the first argument will always be the actual folder
exclude:Sequence[str], optional- names to be excluded. Defaults to [].
origin:Path, optional- starter path. Defaults to Path(".").
Returns
list[T]- depends on what returns, this will also apply it
def write_chipher_images(origin: pathlib._local.Path = WindowsPath('.'))-
Soon
TODO
this function doesn't exits.... based in 1.0.5.0 version
Args
origin:Path, optional- starter path. Defaults to Path(".").
def write_common_file(modes: list[str],
info: configparser.ConfigParser,
origin: pathlib._local.Path = WindowsPath('.'),
folders: list[str | pathlib._local.Path] = ['']) ‑> None-
this is one of the core functions of this tool, it basically takes a series of modes (mostly based from
TemplatePath,ImportKeywords,ParseKeywords,ProccesKeywordsand so on) based on theirorigin, this will apply differents procces for each individual case, but always running as a single functionthis function does actually write a common.rpy file, but it doesn't scan and evaluate files, that's
mkr_lines_list()'s jobHow It Works
first of all, we need the modes, for example
[ ParseKeywords.FILE, TemplateKeys.NORMAL, ImportKeywords.IMAGES, ]with these mode, we are telling the function to write in a file format (
ParseKeywords.FILE), enabling it to use a normal template (TemplateKeys.NORMAL), and the resources are images (ImportKeywords.IMAGES)Tip
alway remember to check what each one of these modes/keywords means, since in most cases what it says, it's what it does, except if it's explained the otherwise
then we have the
info, which is basically a config windows-like file, this makes use ofImageConfigHeadand herebyImageConfigValueas welloriginit's the same asfolders, butoriginis the starter path, thenfoldersare some folders where you want to repliacte the same procces usingmodes, these ones could be relative tooriginor absolute, in whichever case, it's already considered both cases as individualsNote
a side note,
modesbasically controlls how the function andmkr_lines_list()(also the other functions that relies onmodesand their enums) behave, withinoriginand others, there are some mechanism to assume information, such as determine the file oforiginin caseImportKeywordswasn't providedan so other part, but esscencialy, you must indicate one
ParseKeywordsandTemplateKeysat least to make this function do somethingArgs
modes:list[str]- modes to work with (based in different enums)
info:ConfigParser- config window-like file
origin:Path, optional- starter path. Defaults to Path(".").
folders:list[str | Path], optional- folders to replicate
modesbehavior. Defaults to [""].
def write_names(sprites: pathlib._local.Path = WindowsPath('.'),
game_data: pathlib._local.Path = WindowsPath('.')) ‑> tuple[SearchEngine, dict[str, tuple[str, str, str, int]], dict[str, dict[str, dict[str, list[int]]]]]-
this function basically gets all declarations used within the chapters files, basically its a helper to rename all declarations used for a certain file
Args
sprites:Path, optional- sprite folder. Defaults to Path(".").
game_data:Path, optional- game data folder. Defaults to Path(".").
Returns
tuple[SearchEngine, _to_change_statements, _statements_used]- information (maybe not the best return lol)
def write_side_image(size: tuple[int, int, int, int],
load: dict[TemplatePathKeys, str | list[str]],
file_generation_limit: int = 99) ‑> bool-
This will create a side folder based from
TemplatePathKeys.BASEinloadand skip if the name contains certain parts inTemplatePathKeys.NAMEArgs
size:tuple[int, int, int, int]- dimension in LX, LY, RX, RY
load:dict[TemplatePathKeys, str | list[str]]- basically someone didn't want to use arguments as a normal person, so
TemplatePathKeysexits file_generation_limit:int, optional- limit for files. Defaults to 99.
Returns
bool- did it worked?
Classes
class ArgumentsGiven (game,
audio,
video,
sprite,
background,
can_generate_side,
can_generate_common,
use_renamer,
use_cipher_zone,
can_generate_zip)-
A namedtuple that is used only when the tool is being used as
__main__, which basically represents certain options, in what paths we refer, such asArgumentsGiven.game,ArgumentsGiven.audio,ArgumentsGiven.video,ArgumentsGiven.sprite,ArgumentsGiven.backgroundrefers,we recomend your proyect be structurered just like folder structure suggest, otherwise, you might ended up using some commands or all the commands, but you can customize their behavior changing manually
DEFAULT_RESOURCE_PATH(which comes after [proyect]/game) and their respective field (DEFAULT_PATH_VIDEO,DEFAULT_PATH_SOUND,DEFAULT_PATH_IMAGE)Tip
an example of how the object is builded can be found in commands section, yet, it's important to check folder structure for more info about why this feature and how critical this one could be
Ancestors
- builtins.tuple
Instance variables
var audio-
The audio folder (mostly where [project]/game/audio in your renpy folder), this must be a valid folder/path to be used!
var background-
Just like
ArgumentsGiven.game, but for backgrounds' sprites, in most renpy proyects this is more custom that you might expect, check folder structure section for suggestions var can_generate_common-
Indicate if common files can be generated
var can_generate_side-
Indicate if side images can be generated
var can_generate_zip-
Indicate if zip/compression files can be generated
var game-
The data folder (mostly where [project]/game in your renpy folder), this must be a valid folder/path to be used!
var sprite-
Just like
ArgumentsGiven.game, but for characters' sprites, in most renpy proyects this is more custom that you might expect, check folder structure section for suggestions var use_cipher_zone-
Indicate if cipher system will be used, mostly this requires a custom SDK be made adn this will literally broke all your files if used
var use_renamer-
Indicate if the renamer process can/will be used
var video-
The video folder (this is depends if your game supports video or not, this might be in [proyect]/game/video, otherwise, always check folder structure section for more info), this must be a valid folder/path to be used!
class ColorPerLevel (*args, **kwds)-
A silly enum that saves certain colors for different porpuses
Ancestors
- enum.StrEnum
- builtins.str
- enum.ReprEnum
- enum.Enum
Class variables
var CRITIC-
Critical color, mostly related to delete files or certain process
var GENERIC-
Generic color
var INTERNAL-
like
ColorPerLevel.GENERIC, but for internal porpuses
class FeaturesKeywords (*args, **kwds)-
A silly enum that saves the feature that this tool have (mostly depends if ya have some of all dependencies)
Ancestors
- enum.StrEnum
- builtins.str
- enum.ReprEnum
- enum.Enum
Class variables
var IMAGE_CREATION-
Only exits if ya have PIL/Pillow installed
var PRETTY_CONSOLE-
Only exits if ya have tqdm installed
var RENAMING_PROCESS-
This feature might be easy to make as a buildin, but due how difficult it is, for it's left only if ya have whoosh installed
Note
this is temporary 'till we make the actual implementation, for now, it's limited just like
FeaturesKeywords.IMAGE_CREATIONorFeaturesKeywords.ZIP_COMPRESSION var SIDE_GENERATION-
This feature is mostly limited if
FeaturesKeywords.IMAGE_CREATIONwas enabled andArgumentsGiven.can_generate_sidewas used, see commands for more info var ZIP_COMPRESSION-
Only exits if ya have pyminizip installed
class ImageConfigHead (*args, **kwds)-
A silly enum that configure how the file
RequiredFiles.INFObehave and their headersAncestors
- enum.StrEnum
- builtins.str
- enum.ReprEnum
- enum.Enum
Class variables
var SCALE-
header for scale configurations
var SIDE-
header for side configurations
class ImageConfigValue (*args, **kwds)-
A silly enum that configure the name for each field within
ImageConfigHeadandRequiredFiles.INFOfileAncestors
- enum.StrEnum
- builtins.str
- enum.ReprEnum
- enum.Enum
Class variables
var DIMENSION-
mostly, this configure the target-screen dimension (1920x1080), this is moslty used by scale functions
var KEYS-
configure animation keys when scanning for files
var REPEAT-
configure if something must be repeated (this mostly is used by a different procces, like template)
var SIZE-
configure the size
var SQUARE-
configure the square/frame for side images (when created)
class ImportKeywords (*args, **kwds)-
A silly collection of file types that are supported to import by the tool, they are mostly used to no evaluate twice the file type
Ancestors
- enum.StrEnum
- builtins.str
- enum.ReprEnum
- enum.Enum
Class variables
var IMAGES-
indicate to use image not/support extensions
var SOUNDS-
indicate to use sound not/support extensions
var VIDEOS-
indicate to use video not/support extensions
class MessagesError (*args, **kwds)-
A silly collection of error messages, mostly used by the language service
Ancestors
- enum.StrEnum
- builtins.str
- enum.ReprEnum
- enum.Enum
Class variables
var ARGUMENT_NOT_FOUND-
The type of the None singleton.
var EXTENSION_ERROR-
The type of the None singleton.
var FEATURE_NOT_SUPPORTED-
The type of the None singleton.
var FEAUTRE_NOT_FOUND-
The type of the None singleton.
var FILE_NOT_FOUND-
The type of the None singleton.
var INCORRECT_ARGUMENTS-
The type of the None singleton.
var MODULE_NOT_FOUND-
The type of the None singleton.
var MODULE_NOT_FOUND_USING_DEFAULT-
The type of the None singleton.
var PATH_NOT_FOUND-
The type of the None singleton.
var USING_BUILT_IN-
The type of the None singleton.
class MessagesMeta (*args, **kwds)-
A silly collection of meta arguments, mostly used by the language service
Ancestors
- enum.StrEnum
- builtins.str
- enum.ReprEnum
- enum.Enum
Class variables
var DESCRIPTION-
The type of the None singleton.
var MESSAGE_FUNCTION_ENDED-
The type of the None singleton.
var MESSAGE_FUNCTION_INIT-
The type of the None singleton.
var MESSAGE_FUNCTION_PROGRESS-
The type of the None singleton.
var MESSAGE_INFO-
The type of the None singleton.
class ParseKeywords (*args, **kwds)-
A silly enum used mostly to refer the format the images will have once the common files are created
Ancestors
- enum.StrEnum
- builtins.str
- enum.ReprEnum
- enum.Enum
Class variables
var FILE-
indicate to use file-like format
var FOLDER-
indicate to use folder-like format
class ProccesKeywords (*args, **kwds)-
A silly enum that saves a flag-like system (not the best ofc) that determines how
write_common_file()and other functions behaveAncestors
- enum.StrEnum
- builtins.str
- enum.ReprEnum
- enum.Enum
Class variables
var ALL-
indicate to use everything
var ANIMATED-
indicate to use animated-like format, and this will actually check if the file is available for that porpuse, see
KEYS_IMPORTEDorBUILDIN_ANIMATION_KEYSfor more info var FLIP-
indicate to use flip-like format
var IGNORE-
indicate to ignore certain internal-level checks when used
var NOTHING-
indicate to ignore certain low-level checks when used
var SCALE-
indicate to use scale-like format
var SIDE-
indicate to use side-like format (this doesn't check if the file actually exits...........)
var SUBFOLDER-
indicate to also add subfolders to the procces
class RequiredFiles (*args, **kwds)-
A silly enum that save some required file names (mostly optional)
Ancestors
- enum.StrEnum
- builtins.str
- enum.ReprEnum
- enum.Enum
Class variables
var ANIMATED-
Here the keyword within the words are saved, mostly they are saved to differeciate single image with animated ones, see
BUILDIN_ANIMATION_KEYSfor a better how-to guide var INFO-
Here part of the tool's behavior starts, what is described in
ImageConfigHeadandImageConfigValueare saved and evaluated in runtime, for more info, check their respective section var TEMPLATES-
Here the textual templates are saved, you might use
TemplateKeysor custome ones, but using the tool with commands, only those that actually exits inTemplateKeysare supported, and the template is kinda limited, checkBUILDIN_TEMPLATESfor more info
class SearchEngine (sc: whoosh.fields.Schema)-
light weigth search based on whoosh
Methods
def get_index_size(self) ‑> int-
Get all docs indexed so far
Returns
repr (int): lenght of docs indexed
def index_documents(self, docs: Sequence)-
Index some documents to RAM
Args
docs:Sequence- docs
def query(self, q: str, fields: Sequence, highlight: bool = True) ‑> list[dict]-
Search trought all indexed docs
Args
q:str- name to search for
fields:Sequence- fields to search for
highlight:bool, optional- highlight where the match is. Defaults to True.
Returns
repr (List[Dict]): all coincidences
class TemplateKeys (*args, **kwds)-
A silly collection of formats that are currectly supported, mostly this is just a reference, the real ones might be present in
FORMATS_IMPORTED, but these ones can be used in the correct areas (likemkr_lines_list()to make exceptions to the rule, but that's not recommended anyway)Ancestors
- enum.StrEnum
- builtins.str
- enum.ReprEnum
- enum.Enum
Class variables
var ANIMATED_ANIMATED_BODY-
indicate to use the 'animated_animated_body' template
var ANIMATED_BLINK_NORMAL-
indicate to use the 'animated_blink_normal' template
var FLIPED-
indicate to use the 'fliped' template
var NORMAL-
indicate to use the 'normal' template
var SCALE-
indicate to use the 'scale' template
var SIDE-
indicate to use the 'side' template
var SOUND-
indicate to use the 'sound' template
var VIDEO-
indicate to use the 'video' template
var ZIPLOAD-
indicate to use the 'zipload' template
class TemplatePath (*args, **kwds)-
A silly enum that saves how the path is expressed and imported by
get_name_template()Ancestors
- enum.StrEnum
- builtins.str
- enum.ReprEnum
- enum.Enum
Class variables
var ENCRYPT-
indicate to use the encrypt import
var NORMAL-
indicate to use the normal import
var ZIP-
indicate to use the zip import
class TemplatePathKeys (*args, **kwds)-
A really… reallly… REALLY silly enum that doesn't really do much.... just is being used by
write_side_image()cuz someone didn't want to use functional arguments (?)Ancestors
- enum.StrEnum
- builtins.str
- enum.ReprEnum
- enum.Enum
Class variables
var BASE-
Base path (this should include everything, in windows C:/User/[name]/etc/etc/etc)
var NAME-
Base name, mostly what is at the end of
TemplatePathKeys.BASEpath