diff options
Diffstat (limited to 'libmat2/parser_factory.py')
| -rw-r--r-- | libmat2/parser_factory.py | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/libmat2/parser_factory.py b/libmat2/parser_factory.py new file mode 100644 index 0000000..dbe68b9 --- /dev/null +++ b/libmat2/parser_factory.py | |||
| @@ -0,0 +1,42 @@ | |||
| 1 | import os | ||
| 2 | import mimetypes | ||
| 3 | import importlib | ||
| 4 | import pkgutil | ||
| 5 | from typing import TypeVar | ||
| 6 | |||
| 7 | from . import abstract, unsupported_extensions | ||
| 8 | |||
| 9 | |||
| 10 | T = TypeVar('T', bound='abstract.AbstractParser') | ||
| 11 | |||
| 12 | # This loads every parser in a dynamic way | ||
| 13 | for module_loader, name, ispkg in pkgutil.walk_packages('.libmat2'): | ||
| 14 | if not name.startswith('libmat2.'): | ||
| 15 | continue | ||
| 16 | elif name == 'libmat2.abstract': | ||
| 17 | continue | ||
| 18 | importlib.import_module(name) | ||
| 19 | |||
| 20 | |||
| 21 | def _get_parsers() -> list: | ||
| 22 | """ Get all our parsers!""" | ||
| 23 | def __get_parsers(cls): | ||
| 24 | return cls.__subclasses__() + \ | ||
| 25 | [g for s in cls.__subclasses__() for g in __get_parsers(s)] | ||
| 26 | return __get_parsers(abstract.AbstractParser) | ||
| 27 | |||
| 28 | |||
| 29 | def get_parser(filename: str) -> (T, str): | ||
| 30 | mtype, _ = mimetypes.guess_type(filename) | ||
| 31 | |||
| 32 | _, extension = os.path.splitext(filename) | ||
| 33 | if extension in unsupported_extensions: | ||
| 34 | return None, mtype | ||
| 35 | |||
| 36 | for c in _get_parsers(): | ||
| 37 | if mtype in c.mimetypes: | ||
| 38 | try: | ||
| 39 | return c(filename), mtype | ||
| 40 | except ValueError: | ||
| 41 | return None, mtype | ||
| 42 | return None, mtype | ||
