Fix existing JSON array util `json_array_contains_value`, and add two
new utils: `json_array_contains_any` and `json_array_contains_all`.
These utils have been tested with arrays of strings and integers, on the
following database engine versions:
- PostgreSQL: 12, 13, 14, 15, 16, 17, 18
- MySQL: 8.0, 8.4, 9.0, 9.4
- MariaDB: 10.5, 10.6, 10.11, 11.4, 11.8, 12.0
The cache for fixture files was being set without a TTL, which meant
that updates to the fixture files were not reflected in the cache.
This change saves the MD5 hash of the fixture file in a different key,
and compares it to the current hash of the file before deciding whether
to update the cache.
Fixes#2347
Guarantee that cache is initialized during startup, and only once,
instead of every time a `MetadataHandler` object is instantiated.
Also, improve logic to determine `fixtures` paths.
The `emoji` library has been removed, in favor of using constants for
the few emojis used in the codebase. This reduces memory usage, and
avoids calling `emojize` for Python to discover where to replace emojis
in pre-defined strings.
This change replaces the `httpx` client with `aiohttp` for the
RetroAchievements API service.
The main reason for this change is that `httpx` has an unavoidable log
line with `INFO` level, which includes the request full URL, containing
the user's API key.
`httpx` has had an
[open discussion](https://github.com/encode/httpx/discussions/2765)
regarding this security issue for almost two years.
The change to `aiohttp` is painless, and would allow us to migrate more
of the codebase to it in the future, to avoid leaking sensitive
information in logs.
Similar to how `engineio` provides a JSON-compatible module, this change
adds a custom JSON encoder with support for additional types.
Changing SocketIO's JSON module fixes the encoding issue when the
scanning process tried to send a datetime, failing and the frontend not
displaying the scanned game (commonly, when it had sibling games)