cardinal-pythonlib 2.0.4__tar.gz → 2.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/PKG-INFO +1 -1
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/bulk_email/main.py +1 -1
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/bulk_email/models.py +1 -1
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/django/fields/jsonclassfield.py +1 -1
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/django/function_cache.py +1 -1
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/django/middleware.py +5 -5
- {cardinal_pythonlib-2.0.4/cardinal_pythonlib/email → cardinal_pythonlib-2.1.0/cardinal_pythonlib/email_utils}/__init__.py +1 -1
- {cardinal_pythonlib-2.0.4/cardinal_pythonlib/email → cardinal_pythonlib-2.1.0/cardinal_pythonlib/email_utils}/mailboxpurge.py +1 -1
- {cardinal_pythonlib-2.0.4/cardinal_pythonlib/email → cardinal_pythonlib-2.1.0/cardinal_pythonlib/email_utils}/sendmail.py +1 -1
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/extract_text.py +110 -18
- {cardinal_pythonlib-2.0.4/cardinal_pythonlib/json → cardinal_pythonlib-2.1.0/cardinal_pythonlib/json_utils}/__init__.py +1 -1
- {cardinal_pythonlib-2.0.4/cardinal_pythonlib/json → cardinal_pythonlib-2.1.0/cardinal_pythonlib/json_utils}/serialize.py +2 -2
- {cardinal_pythonlib-2.0.4/cardinal_pythonlib/json → cardinal_pythonlib-2.1.0/cardinal_pythonlib/json_utils}/typing_helpers.py +1 -1
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/module_version.py +0 -3
- cardinal_pythonlib-2.0.4/cardinal_pythonlib/profile.py → cardinal_pythonlib-2.1.0/cardinal_pythonlib/profiling.py +1 -1
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/sizeformatter.py +1 -1
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/sqlalchemy/dialect.py +1 -1
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/sqlalchemy/schema.py +1 -0
- cardinal_pythonlib-2.1.0/cardinal_pythonlib/tests/__init__.py +27 -0
- cardinal_pythonlib-2.1.0/cardinal_pythonlib/tests/datetimefunc_tests.py +485 -0
- cardinal_pythonlib-2.1.0/cardinal_pythonlib/tests/dogpile_cache_tests.py +727 -0
- cardinal_pythonlib-2.1.0/cardinal_pythonlib/tests/extract_text_tests.py +588 -0
- cardinal_pythonlib-2.1.0/cardinal_pythonlib/tests/interval_tests.py +58 -0
- cardinal_pythonlib-2.1.0/cardinal_pythonlib/tests/lists_tests.py +45 -0
- cardinal_pythonlib-2.1.0/cardinal_pythonlib/tests/pdf_tests.py +215 -0
- cardinal_pythonlib-2.1.0/cardinal_pythonlib/tests/rate_limiting_tests.py +71 -0
- cardinal_pythonlib-2.1.0/cardinal_pythonlib/tests/rounding_tests.py +250 -0
- cardinal_pythonlib-2.1.0/cardinal_pythonlib/tests/rpm_tests.py +193 -0
- cardinal_pythonlib-2.1.0/cardinal_pythonlib/tests/sphinxtools_tests.py +81 -0
- cardinal_pythonlib-2.1.0/cardinal_pythonlib/tests/spreadsheets_tests.py +51 -0
- cardinal_pythonlib-2.1.0/cardinal_pythonlib/tests/subprocess_tests.py +52 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/tools/convert_mdb_to_mysql.py +2 -2
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/tools/explore_clang_format_config.py +5 -1
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/version_string.py +1 -1
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib.egg-info/PKG-INFO +1 -1
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib.egg-info/SOURCES.txt +20 -8
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib.egg-info/entry_points.txt +1 -1
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/setup.cfg +4 -1
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/setup.py +2 -2
- cardinal_pythonlib-2.0.4/cardinal_pythonlib/ensure_test_executed_correctly.py +0 -40
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/LICENSE +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/README.rst +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/__init__.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/argparse_func.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/athena_ohdsi.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/betweendict.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/buildfunc.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/bulk_email/__init__.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/bulk_email/constants.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/chebi.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/classes.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/cmdline.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/colander_utils.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/compression.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/configfiles.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/contexts.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/convert.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/crypto.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/datamapping.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/datetimefunc.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/dbfunc.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/debugging.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/deform_utils.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/dicts.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/django/__init__.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/django/admin.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/django/django_constants.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/django/fields/__init__.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/django/fields/helpers.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/django/fields/isodatetimetz.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/django/fields/restrictedcontentfile.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/django/files.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/django/forms.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/django/mail.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/django/reprfunc.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/django/request_cache.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/django/serve.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/django/tools/__init__.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/django/tools/generate_new_django_secret_key.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/docker.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/dogpile_cache.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/dsp.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/enumlike.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/excel.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/exceptions.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/file_io.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/fileops.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/formatting.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/getch.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/hash.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/httpconst.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/interval.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/iterhelp.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/lang.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/lists.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/logs.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/maths_numpy.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/maths_py.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/metaclasses.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/modules.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/network.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/nhs.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/openxml/__init__.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/openxml/find_bad_openxml.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/openxml/find_recovered_openxml.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/openxml/grep_in_openxml.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/openxml/pause_process_by_disk_space.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/parallel.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/pdf.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/platformfunc.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/plot.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/probability.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/process.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/progress.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/psychiatry/__init__.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/psychiatry/drugs.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/psychiatry/mk_r_druglists.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/psychiatry/rfunc.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/psychiatry/simhelpers.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/psychiatry/timeline.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/psychiatry/treatment_resistant_depression.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/pyramid/__init__.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/pyramid/compression.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/pyramid/constants.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/pyramid/requests.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/pyramid/responses.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/randomness.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/rate_limiting.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/regexfunc.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/register_db_with_odbc.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/reprfunc.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/rnc_text.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/rnc_web.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/rounding.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/rpm.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/run_all_tests.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/signalfunc.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/slurm.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/snomed.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/sort.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/source_reformatting.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/sphinxtools.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/spreadsheets.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/sql/__init__.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/sql/literals.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/sql/sql_grammar.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/sql/sql_grammar_factory.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/sql/sql_grammar_mssql.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/sql/sql_grammar_mysql.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/sql/validation.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/sqlalchemy/__init__.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/sqlalchemy/alembic_func.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/sqlalchemy/alembic_ops.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/sqlalchemy/arrow_types.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/sqlalchemy/core_query.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/sqlalchemy/dump.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/sqlalchemy/engine_func.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/sqlalchemy/insert_on_duplicate.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/sqlalchemy/list_types.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/sqlalchemy/logs.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/sqlalchemy/merge_db.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/sqlalchemy/orm_inspect.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/sqlalchemy/orm_query.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/sqlalchemy/orm_schema.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/sqlalchemy/semantic_version_coltype.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/sqlalchemy/session.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/sqlalchemy/sqla_version.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/sqlalchemy/sqlfunc.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/sqlalchemy/sqlserver.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/sqlalchemy/table_identity.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/stringfunc.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/subproc.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/sysops.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/tcpipconst.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/tee.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/text.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/timing.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/tools/__init__.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/tools/backup_mysql_database.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/tools/convert_athena_ohdsi_codes.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/tools/estimate_mysql_memory_usage.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/tools/list_all_file_extensions.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/tools/merge_csv.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/tools/pdf_to_booklet.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/tools/remove_duplicate_files.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/tsv.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/typetests.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/typing_helpers.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/ui.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/ui_commandline.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/uriconst.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/version.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/winservice.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/wsgi/__init__.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/wsgi/cache_mw.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/wsgi/constants.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/wsgi/errorreporter_mw.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/wsgi/headers_mw.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/wsgi/request_logging_mw.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/wsgi/reverse_proxied_mw.py +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib.egg-info/dependency_links.txt +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib.egg-info/requires.txt +0 -0
- {cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib.egg-info/top_level.txt +0 -0
{cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/bulk_email/models.py
RENAMED
|
@@ -63,7 +63,7 @@ from cardinal_pythonlib.bulk_email.constants import (
|
|
|
63
63
|
USERNAME_MAX_LENGTH,
|
|
64
64
|
)
|
|
65
65
|
from cardinal_pythonlib.colander_utils import EMAIL_ADDRESS_MAX_LEN
|
|
66
|
-
from cardinal_pythonlib.
|
|
66
|
+
from cardinal_pythonlib.email_utils.sendmail import (
|
|
67
67
|
ASCII,
|
|
68
68
|
CONTENT_TYPE_TEXT,
|
|
69
69
|
is_email_valid,
|
|
@@ -130,7 +130,7 @@ from django.core.exceptions import ValidationError
|
|
|
130
130
|
# noinspection PyUnresolvedReferences
|
|
131
131
|
from django.db.models import TextField
|
|
132
132
|
|
|
133
|
-
from cardinal_pythonlib.
|
|
133
|
+
from cardinal_pythonlib.json_utils.serialize import json_decode, json_encode
|
|
134
134
|
|
|
135
135
|
|
|
136
136
|
# =============================================================================
|
{cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/django/function_cache.py
RENAMED
|
@@ -36,7 +36,7 @@ from typing import Any, Callable, Dict, Tuple
|
|
|
36
36
|
from django.core.cache import cache # default cache
|
|
37
37
|
|
|
38
38
|
from cardinal_pythonlib.logs import get_brace_style_log_with_null_handler
|
|
39
|
-
from cardinal_pythonlib.
|
|
39
|
+
from cardinal_pythonlib.json_utils.serialize import json_encode
|
|
40
40
|
|
|
41
41
|
log = get_brace_style_log_with_null_handler(__name__)
|
|
42
42
|
|
{cardinal_pythonlib-2.0.4 → cardinal_pythonlib-2.1.0}/cardinal_pythonlib/django/middleware.py
RENAMED
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
|
|
29
29
|
import logging
|
|
30
30
|
import os
|
|
31
|
-
|
|
31
|
+
import re
|
|
32
32
|
import sys
|
|
33
33
|
from typing import Optional
|
|
34
34
|
|
|
@@ -107,9 +107,9 @@ https://onecreativeblog.com/post/59051248/django-login-required-middleware
|
|
|
107
107
|
Modified according to: https://djangosnippets.org/snippets/2845/
|
|
108
108
|
"""
|
|
109
109
|
|
|
110
|
-
# EXEMPT_URLS = [compile(settings.LOGIN_URL.lstrip('/'))]
|
|
110
|
+
# EXEMPT_URLS = [re.compile(settings.LOGIN_URL.lstrip('/'))]
|
|
111
111
|
# if hasattr(settings, 'LOGIN_EXEMPT_URLS'):
|
|
112
|
-
# EXEMPT_URLS += [compile(expr) for expr in settings.LOGIN_EXEMPT_URLS]
|
|
112
|
+
# EXEMPT_URLS += [re.compile(expr) for expr in settings.LOGIN_EXEMPT_URLS]
|
|
113
113
|
#
|
|
114
114
|
#
|
|
115
115
|
# class LoginRequiredMiddleware:
|
|
@@ -166,10 +166,10 @@ Modified according to: https://djangosnippets.org/snippets/2845/
|
|
|
166
166
|
# 3. RNC; composite of those patterns.
|
|
167
167
|
# -----------------------------------------------------------------------------
|
|
168
168
|
|
|
169
|
-
EXEMPT_URLS = [compile(settings.LOGIN_URL.lstrip("/"))]
|
|
169
|
+
EXEMPT_URLS = [re.compile(settings.LOGIN_URL.lstrip("/"))]
|
|
170
170
|
if hasattr(settings, "LOGIN_EXEMPT_URLS"):
|
|
171
171
|
EXEMPT_URLS += [
|
|
172
|
-
compile(expr.lstrip("/")) for expr in settings.LOGIN_EXEMPT_URLS
|
|
172
|
+
re.compile(expr.lstrip("/")) for expr in settings.LOGIN_EXEMPT_URLS
|
|
173
173
|
]
|
|
174
174
|
|
|
175
175
|
|
|
@@ -77,9 +77,14 @@ See also:
|
|
|
77
77
|
# =============================================================================
|
|
78
78
|
|
|
79
79
|
import argparse
|
|
80
|
+
import base64
|
|
81
|
+
from email import policy
|
|
82
|
+
from email.message import EmailMessage
|
|
83
|
+
from email.parser import BytesParser
|
|
80
84
|
from io import StringIO
|
|
81
85
|
import io
|
|
82
86
|
import logging
|
|
87
|
+
from mimetypes import guess_extension
|
|
83
88
|
import os
|
|
84
89
|
import re
|
|
85
90
|
import shutil
|
|
@@ -87,6 +92,7 @@ import subprocess
|
|
|
87
92
|
import sys
|
|
88
93
|
import textwrap
|
|
89
94
|
from typing import (
|
|
95
|
+
Any,
|
|
90
96
|
BinaryIO,
|
|
91
97
|
Dict,
|
|
92
98
|
Generator,
|
|
@@ -205,9 +211,9 @@ class TextProcessingConfig(object):
|
|
|
205
211
|
plain: bool = False,
|
|
206
212
|
semiplain: bool = False,
|
|
207
213
|
docx_in_order: bool = True,
|
|
208
|
-
horizontal_char="─",
|
|
209
|
-
vertical_char="│",
|
|
210
|
-
junction_char="┼",
|
|
214
|
+
horizontal_char: str = "─",
|
|
215
|
+
vertical_char: str = "│",
|
|
216
|
+
junction_char: str = "┼",
|
|
211
217
|
plain_table_start: str = None,
|
|
212
218
|
plain_table_end: str = None,
|
|
213
219
|
plain_table_col_boundary: str = None,
|
|
@@ -352,7 +358,7 @@ def get_filelikeobject(filename: str = None, blob: bytes = None) -> BinaryIO:
|
|
|
352
358
|
Returns:
|
|
353
359
|
a :class:`BinaryIO` object
|
|
354
360
|
"""
|
|
355
|
-
if not filename and
|
|
361
|
+
if not filename and blob is None:
|
|
356
362
|
raise ValueError("no filename and no blob")
|
|
357
363
|
if filename and blob:
|
|
358
364
|
raise ValueError("specify either filename or blob")
|
|
@@ -367,11 +373,11 @@ def get_file_contents(filename: str = None, blob: bytes = None) -> bytes:
|
|
|
367
373
|
"""
|
|
368
374
|
Returns the binary contents of a file, or of a BLOB.
|
|
369
375
|
"""
|
|
370
|
-
if
|
|
376
|
+
if filename is None and blob is None:
|
|
371
377
|
raise ValueError("no filename and no blob")
|
|
372
378
|
if filename and blob:
|
|
373
379
|
raise ValueError("specify either filename or blob")
|
|
374
|
-
if blob:
|
|
380
|
+
if blob is not None:
|
|
375
381
|
return blob
|
|
376
382
|
with open(filename, "rb") as f:
|
|
377
383
|
return f.read()
|
|
@@ -445,7 +451,7 @@ def get_file_contents_text(
|
|
|
445
451
|
)
|
|
446
452
|
|
|
447
453
|
|
|
448
|
-
def get_cmd_output(*args, encoding: str = SYS_ENCODING) -> str:
|
|
454
|
+
def get_cmd_output(*args: Any, encoding: str = SYS_ENCODING) -> str:
|
|
449
455
|
"""
|
|
450
456
|
Returns text output of a command.
|
|
451
457
|
"""
|
|
@@ -456,7 +462,7 @@ def get_cmd_output(*args, encoding: str = SYS_ENCODING) -> str:
|
|
|
456
462
|
|
|
457
463
|
|
|
458
464
|
def get_cmd_output_from_stdin(
|
|
459
|
-
stdint_content_binary: bytes, *args, encoding: str = SYS_ENCODING
|
|
465
|
+
stdint_content_binary: bytes, *args: Any, encoding: str = SYS_ENCODING
|
|
460
466
|
) -> str:
|
|
461
467
|
"""
|
|
462
468
|
Returns text output of a command, passing binary data in via stdin.
|
|
@@ -549,17 +555,17 @@ def availability_pdf() -> bool:
|
|
|
549
555
|
# -----------------------------------------------------------------------------
|
|
550
556
|
# In a D.I.Y. fashion
|
|
551
557
|
# -----------------------------------------------------------------------------
|
|
552
|
-
# DOCX specification:
|
|
558
|
+
# DOCX specification: https://ecma-international.org/publications-and-standards/standards/ecma-376/ # noqa: E501
|
|
553
559
|
|
|
554
560
|
DOCX_HEADER_FILE_REGEX = re.compile("word/header[0-9]*.xml")
|
|
555
|
-
|
|
561
|
+
DOCX_DOCUMENT_FILE_REGEX = re.compile("word/document[0-9]*.xml")
|
|
556
562
|
DOCX_FOOTER_FILE_REGEX = re.compile("word/footer[0-9]*.xml")
|
|
557
563
|
DOCX_SCHEMA_URL = (
|
|
558
564
|
"http://schemas.openxmlformats.org/wordprocessingml/2006/main"
|
|
559
565
|
)
|
|
560
566
|
|
|
561
567
|
|
|
562
|
-
def docx_qn(tagroot):
|
|
568
|
+
def docx_qn(tagroot: str) -> str:
|
|
563
569
|
return f"{{{DOCX_SCHEMA_URL}}}{tagroot}"
|
|
564
570
|
|
|
565
571
|
|
|
@@ -595,7 +601,9 @@ def gen_xml_files_from_docx(fp: BinaryIO) -> Iterator[str]:
|
|
|
595
601
|
for filename in filelist:
|
|
596
602
|
if DOCX_HEADER_FILE_REGEX.match(filename):
|
|
597
603
|
yield z.read(filename).decode("utf8")
|
|
598
|
-
|
|
604
|
+
for filename in filelist:
|
|
605
|
+
if DOCX_DOCUMENT_FILE_REGEX.match(filename):
|
|
606
|
+
yield z.read(filename).decode("utf8")
|
|
599
607
|
for filename in filelist:
|
|
600
608
|
if DOCX_FOOTER_FILE_REGEX.match(filename):
|
|
601
609
|
yield z.read(filename).decode("utf8")
|
|
@@ -624,7 +632,7 @@ def docx_gen_wordwrapped_fragments(
|
|
|
624
632
|
"""
|
|
625
633
|
to_wrap = [] # type: List[DocxFragment]
|
|
626
634
|
|
|
627
|
-
def yield_wrapped():
|
|
635
|
+
def yield_wrapped() -> Generator[str, None, None]:
|
|
628
636
|
"""
|
|
629
637
|
Yield the word-wrapped stuff to date.
|
|
630
638
|
"""
|
|
@@ -1132,9 +1140,24 @@ def convert_html_to_text(
|
|
|
1132
1140
|
"""
|
|
1133
1141
|
Converts HTML to text.
|
|
1134
1142
|
"""
|
|
1143
|
+
|
|
1144
|
+
# https://bugs.launchpad.net/beautifulsoup/+bug/2110492
|
|
1145
|
+
# beautifulsoup4==4.13.4 returns "b''" for an empty bytes array
|
|
1146
|
+
# So we just workaround this here:
|
|
1147
|
+
if bytes is not None and len(blob) == 0:
|
|
1148
|
+
return ""
|
|
1149
|
+
|
|
1135
1150
|
with get_filelikeobject(filename, blob) as fp:
|
|
1136
|
-
soup = bs4.BeautifulSoup(fp)
|
|
1137
|
-
|
|
1151
|
+
soup = bs4.BeautifulSoup(fp, "html.parser")
|
|
1152
|
+
|
|
1153
|
+
# In the real world we can end up with UTF-16 characters embedded as
|
|
1154
|
+
# numbered entities in Windows-1252 encoded HTML such as
|
|
1155
|
+
# �� "Slightly smiling face". Replacing these here
|
|
1156
|
+
# avoids "UnicodeEncodeError: 'utf-8' codec can't encode characters in
|
|
1157
|
+
# position ... surrogates not allowed".
|
|
1158
|
+
text = soup.get_text().encode(errors="replace").decode()
|
|
1159
|
+
|
|
1160
|
+
return text
|
|
1138
1161
|
|
|
1139
1162
|
|
|
1140
1163
|
# =============================================================================
|
|
@@ -1152,7 +1175,7 @@ def convert_xml_to_text(
|
|
|
1152
1175
|
Converts XML to text.
|
|
1153
1176
|
"""
|
|
1154
1177
|
with get_filelikeobject(filename, blob) as fp:
|
|
1155
|
-
soup = bs4.
|
|
1178
|
+
soup = bs4.BeautifulSoup(fp, features="xml")
|
|
1156
1179
|
return soup.get_text()
|
|
1157
1180
|
|
|
1158
1181
|
|
|
@@ -1229,6 +1252,74 @@ def availability_doc() -> bool:
|
|
|
1229
1252
|
return bool(antiword)
|
|
1230
1253
|
|
|
1231
1254
|
|
|
1255
|
+
# =============================================================================
|
|
1256
|
+
# EML
|
|
1257
|
+
# =============================================================================
|
|
1258
|
+
|
|
1259
|
+
|
|
1260
|
+
def convert_eml_to_text(
|
|
1261
|
+
filename: str = None,
|
|
1262
|
+
blob: bytes = None,
|
|
1263
|
+
config: TextProcessingConfig = _DEFAULT_CONFIG,
|
|
1264
|
+
) -> str:
|
|
1265
|
+
email_content_list: list[str] = []
|
|
1266
|
+
|
|
1267
|
+
with get_filelikeobject(filename, blob) as fp:
|
|
1268
|
+
parser = BytesParser(policy=policy.default) # type: ignore[arg-type]
|
|
1269
|
+
message = parser.parse(fp)
|
|
1270
|
+
|
|
1271
|
+
for email_content in _gen_email_content(message, config):
|
|
1272
|
+
if email_content is not None:
|
|
1273
|
+
email_content_list.append(email_content)
|
|
1274
|
+
|
|
1275
|
+
text = "\n".join(email_content_list)
|
|
1276
|
+
|
|
1277
|
+
return text
|
|
1278
|
+
|
|
1279
|
+
|
|
1280
|
+
def _gen_email_content(
|
|
1281
|
+
message: EmailMessage, config: TextProcessingConfig
|
|
1282
|
+
) -> Generator[Optional[str], None, None]:
|
|
1283
|
+
body = message.get_body(
|
|
1284
|
+
preferencelist=(
|
|
1285
|
+
"html",
|
|
1286
|
+
"plain",
|
|
1287
|
+
)
|
|
1288
|
+
) # type: ignore[attr-defined]
|
|
1289
|
+
if body is not None:
|
|
1290
|
+
yield _get_email_content(body, config)
|
|
1291
|
+
|
|
1292
|
+
for part in message.iter_attachments(): # type: ignore[attr-defined]
|
|
1293
|
+
yield _get_email_content(part, config)
|
|
1294
|
+
|
|
1295
|
+
|
|
1296
|
+
def _get_email_content(
|
|
1297
|
+
message: EmailMessage,
|
|
1298
|
+
config: TextProcessingConfig,
|
|
1299
|
+
) -> Optional[str]:
|
|
1300
|
+
content_type = message.get_content_type()
|
|
1301
|
+
ext = guess_extension(content_type)
|
|
1302
|
+
|
|
1303
|
+
if ext is not None and ext in ext_map:
|
|
1304
|
+
content = message.get_content()
|
|
1305
|
+
if isinstance(content, str):
|
|
1306
|
+
charset = "utf-8"
|
|
1307
|
+
content_type_header = message.get("Content-Type")
|
|
1308
|
+
if content_type_header:
|
|
1309
|
+
charset = content_type_header.params.get("charset", "utf-8")
|
|
1310
|
+
blob = content.encode(charset, "replace")
|
|
1311
|
+
elif isinstance(content, EmailMessage):
|
|
1312
|
+
blob = content.as_bytes()
|
|
1313
|
+
if message.get("Content-Transfer-Encoding") == "base64":
|
|
1314
|
+
blob = base64.b64decode(blob)
|
|
1315
|
+
else:
|
|
1316
|
+
blob = content
|
|
1317
|
+
|
|
1318
|
+
return document_to_text(blob=blob, extension=ext, config=config)
|
|
1319
|
+
|
|
1320
|
+
return None
|
|
1321
|
+
|
|
1322
|
+
|
|
1232
1323
|
# =============================================================================
|
|
1233
1324
|
# Anything
|
|
1234
1325
|
# =============================================================================
|
|
@@ -1267,7 +1358,7 @@ def availability_anything() -> bool:
|
|
|
1267
1358
|
# Decider
|
|
1268
1359
|
# =============================================================================
|
|
1269
1360
|
|
|
1270
|
-
ext_map = {
|
|
1361
|
+
ext_map: dict[str, dict[str, Any]] = {
|
|
1271
1362
|
# Converter functions must be of the form: func(filename, blob, config).
|
|
1272
1363
|
# Availability must be either a boolean literal or a function that takes no
|
|
1273
1364
|
# params.
|
|
@@ -1276,6 +1367,7 @@ ext_map = {
|
|
|
1276
1367
|
".docm": {CONVERTER: convert_docx_to_text, AVAILABILITY: True},
|
|
1277
1368
|
".docx": {CONVERTER: convert_docx_to_text, AVAILABILITY: True},
|
|
1278
1369
|
".dot": {CONVERTER: convert_doc_to_text, AVAILABILITY: availability_doc},
|
|
1370
|
+
".eml": {CONVERTER: convert_eml_to_text, AVAILABILITY: True},
|
|
1279
1371
|
".htm": {CONVERTER: convert_html_to_text, AVAILABILITY: True},
|
|
1280
1372
|
".html": {CONVERTER: convert_html_to_text, AVAILABILITY: True},
|
|
1281
1373
|
".log": {CONVERTER: get_file_contents_text, AVAILABILITY: True},
|
|
@@ -1333,7 +1425,7 @@ def document_to_text(
|
|
|
1333
1425
|
Raises an exception for malformed arguments, missing files, bad
|
|
1334
1426
|
filetypes, etc.
|
|
1335
1427
|
"""
|
|
1336
|
-
if not filename and
|
|
1428
|
+
if not filename and blob is None:
|
|
1337
1429
|
raise ValueError("document_to_text: no filename and no blob")
|
|
1338
1430
|
if filename and blob:
|
|
1339
1431
|
raise ValueError("document_to_text: specify either filename or blob")
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
|
-
# cardinal_pythonlib/
|
|
2
|
+
# cardinal_pythonlib/json_utils/serialize.py
|
|
3
3
|
|
|
4
4
|
"""
|
|
5
5
|
===============================================================================
|
|
@@ -807,7 +807,7 @@ def dict_to_pendulumdate(
|
|
|
807
807
|
# noinspection PyTypeChecker
|
|
808
808
|
dt = pendulum.parse(d["iso"]) # type: pendulum.DateTime
|
|
809
809
|
# noinspection PyTypeChecker
|
|
810
|
-
return dt.date()
|
|
810
|
+
return dt.date()
|
|
811
811
|
|
|
812
812
|
|
|
813
813
|
register_class_for_json(
|
|
@@ -39,9 +39,6 @@ from importlib.metadata import version # structure for Python 3.8 or higher
|
|
|
39
39
|
|
|
40
40
|
from semantic_version import Version
|
|
41
41
|
|
|
42
|
-
# noinspection PyUnresolvedReferences
|
|
43
|
-
import cardinal_pythonlib.ensure_test_executed_correctly # noqa: F401
|
|
44
|
-
|
|
45
42
|
|
|
46
43
|
# =============================================================================
|
|
47
44
|
# Report Python module versions
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# cardinal_pythonlib/tests/__init__.py
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
===============================================================================
|
|
5
|
+
|
|
6
|
+
Original code copyright (C) 2009-2022 Rudolf Cardinal (rudolf@pobox.com).
|
|
7
|
+
|
|
8
|
+
This file is part of cardinal_pythonlib.
|
|
9
|
+
|
|
10
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
11
|
+
you may not use this file except in compliance with the License.
|
|
12
|
+
You may obtain a copy of the License at
|
|
13
|
+
|
|
14
|
+
https://www.apache.org/licenses/LICENSE-2.0
|
|
15
|
+
|
|
16
|
+
Unless required by applicable law or agreed to in writing, software
|
|
17
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
18
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
19
|
+
See the License for the specific language governing permissions and
|
|
20
|
+
limitations under the License.
|
|
21
|
+
|
|
22
|
+
===============================================================================
|
|
23
|
+
|
|
24
|
+
The mere existence of this file makes Python treat the directory as a
|
|
25
|
+
package.
|
|
26
|
+
|
|
27
|
+
"""
|