Commit Graph

51 Commits

Author SHA1 Message Date
RumovZ
cdfb84f19a
Implement TTS using windows crate (#2371)
* Implement TTS using windows crate

* Use API calls instead of SSML

* Properly stop player in case of TTS error

* Add context to WindowsErrors

* Validate available voices

* Remove TTS text from synthesize error

* Limit maximum buffer size

* Make validation optional and list it in tts filter

* We no longer need the winrt module (dae)

* Use a separate request object so the meaning of the bool is clear (dae)

* Slightly shorten runtime error message (dae)

The default message appears to clip slightly.

* Alternate buffer implementation (dae)

* Use array instead of vec

* Drop the max buffer size to 128k (dae)
2023-02-17 12:26:07 +10:00
Damien Elmes
b4290fbe44 Bump werkzeug version
Fixes CVE-2023-23934
2023-02-16 17:41:25 +10:00
Damien Elmes
cf45cbf429
Rework syncing code, and replace local sync server (#2329)
This PR replaces the existing Python-driven sync server with a new one in Rust.
The new server supports both collection and media syncing, and is compatible
with both the new protocol mentioned below, and older clients. A setting has
been added to the preferences screen to point Anki to a local server, and a
similar setting is likely to come to AnkiMobile soon.

Documentation is available here: <https://docs.ankiweb.net/sync-server.html>

In addition to the new server and refactoring, this PR also makes changes to the
sync protocol. The existing sync protocol places payloads and metadata inside a
multipart POST body, which causes a few headaches:

- Legacy clients build the request in a non-deterministic order, meaning the
entire request needs to be scanned to extract the metadata.
- Reqwest's multipart API directly writes the multipart body, without exposing
the resulting stream to us, making it harder to track the progress of the
transfer. We've been relying on a patched version of reqwest for timeouts,
which is a pain to keep up to date.

To address these issues, the metadata is now sent in a HTTP header, with the
data payload sent directly in the body. Instead of the slower gzip, we now
use zstd. The old timeout handling code has been replaced with a new implementation
that wraps the request and response body streams to track progress, allowing us
to drop the git dependencies for reqwest, hyper-timeout and tokio-io-timeout.

The main other change to the protocol is that one-way syncs no longer need to
downgrade the collection to schema 11 prior to sending.
2023-01-18 12:43:46 +10:00
Damien Elmes
cef672a6a1 Update Windows/Linux to Qt 6.4.2
Closes #2275
2023-01-09 16:22:47 +10:00
Aristotelis
2270ff425a
Add dev tools for live-reloading Anki's web views (#2151)
* Add dev tools for live-reloading the web stack while running Anki

* Handle CDP connection errors more graciously

* Include sass in web stack watchers

* Refactor monitored folder and event definition

* Switch to more specific build target

Thanks to @hikaru-y

* Add PyChromeDevTools to dev requirements

* Update rebuild-web for ninja

* Satisfy mypy

* Remove ts-watch

Superseded by web-watch (the version here was also still based around bazel)

* Simplify calls to other build tools

Given that `./ninja qt/aqt` has to be run from the project root anyways, it doesn't make sense to use calls relative to `rebuild-web` in an ill-guided effort to lower dependencies on hard-coded paths.

* Remove remaining script-relative tool path
2023-01-03 11:55:58 +10:00
Damien Elmes
e0c4ba4b60 Revert to Qt 6.3.1 on macOS
Due to flicker reported on #2263. 6.3.1 was used in the 2.1.54 and is
the more conservative choice; we can trial 6.3.2 after release.
2022-12-14 15:25:10 +10:00
Damien Elmes
f9f8769ea8 Update certifi to fix security alert 2022-12-11 11:42:08 +10:00
Damien Elmes
9dc6e41153 Switch back to winrt to see if it fixes slow TTS
https://forums.ankiweb.net/t/slow-tts-and-duplicated-voices/25157/7

winrt blocks an upgrade from Python 3.9, so this will be a temporary
solution at best.
2022-12-06 20:30:54 +10:00
Damien Elmes
a70f8d4dd5 Fix TTS handling on Windows
Also update to winsdk, which unblocks Python updates on Windows
2022-11-29 13:04:51 +10:00
Damien Elmes
5e0a761b87
Move away from Bazel (#2202)
(for upgrading users, please see the notes at the bottom)

Bazel brought a lot of nice things to the table, such as rebuilds based on
content changes instead of modification times, caching of build products,
detection of incorrect build rules via a sandbox, and so on. Rewriting the build
in Bazel was also an opportunity to improve on the Makefile-based build we had
prior, which was pretty poor: most dependencies were external or not pinned, and
the build graph was poorly defined and mostly serialized. It was not uncommon
for fresh checkouts to fail due to floating dependencies, or for things to break
when trying to switch to an older commit.

For day-to-day development, I think Bazel served us reasonably well - we could
generally switch between branches while being confident that builds would be
correct and reasonably fast, and not require full rebuilds (except on Windows,
where the lack of a sandbox and the TS rules would cause build breakages when TS
files were renamed/removed).

Bazel achieves that reliability by defining rules for each programming language
that define how source files should be turned into outputs. For the rules to
work with Bazel's sandboxing approach, they often have to reimplement or
partially bypass the standard tools that each programming language provides. The
Rust rules call Rust's compiler directly for example, instead of using Cargo,
and the Python rules extract each PyPi package into a separate folder that gets
added to sys.path.

These separate language rules allow proper declaration of inputs and outputs,
and offer some advantages such as caching of build products and fine-grained
dependency installation. But they also bring some downsides:

- The rules don't always support use-cases/platforms that the standard language
tools do, meaning they need to be patched to be used. I've had to contribute a
number of patches to the Rust, Python and JS rules to unblock various issues.
- The dependencies we use with each language sometimes make assumptions that do
not hold in Bazel, meaning they either need to be pinned or patched, or the
language rules need to be adjusted to accommodate them.

I was hopeful that after the initial setup work, things would be relatively
smooth-sailing. Unfortunately, that has not proved to be the case. Things
frequently broke when dependencies or the language rules were updated, and I
began to get frustrated at the amount of Anki development time I was instead
spending on build system upkeep. It's now about 2 years since switching to
Bazel, and I think it's time to cut losses, and switch to something else that's
a better fit.

The new build system is based on a small build tool called Ninja, and some
custom Rust code in build/. This means that to build Anki, Bazel is no longer
required, but Ninja and Rust need to be installed on your system. Python and
Node toolchains are automatically downloaded like in Bazel.

This new build system should result in faster builds in some cases:

- Because we're using cargo to build now, Rust builds are able to take advantage
of pipelining and incremental debug builds, which we didn't have with Bazel.
It's also easier to override the default linker on Linux/macOS, which can
further improve speeds.
- External Rust crates are now built with opt=1, which improves performance
of debug builds.
- Esbuild is now used to transpile TypeScript, instead of invoking the TypeScript
compiler. This results in faster builds, by deferring typechecking to test/check
time, and by allowing more work to happen in parallel.

As an example of the differences, when testing with the mold linker on Linux,
adding a new message to tags.proto (which triggers a recompile of the bulk of
the Rust and TypeScript code) results in a compile that goes from about 22s on
Bazel to about 7s in the new system. With the standard linker, it's about 9s.

Some other changes of note:

- Our Rust workspace now uses cargo-hakari to ensure all packages agree on
available features, preventing unnecessary rebuilds.
- pylib/anki is now a PEP420 implicit namespace, avoiding the need to merge
source files and generated files into a single folder for running. By telling
VSCode about the extra search path, code completion now works with generated
files without needing to symlink them into the source folder.
- qt/aqt can't use PEP420 as it's difficult to get rid of aqt/__init__.py.
Instead, the generated files are now placed in a separate _aqt package that's
added to the path.
- ts/lib is now exposed as @tslib, so the source code and generated code can be
provided under the same namespace without a merging step.
- MyPy and PyLint are now invoked once for the entire codebase.
- dprint will be used to format TypeScript/json files in the future instead of
the slower prettier (currently turned off to avoid causing conflicts). It can
automatically defer to prettier when formatting Svelte files.
- svelte-check is now used for typechecking our Svelte code, which revealed a
few typing issues that went undetected with the old system.
- The Jest unit tests now work on Windows as well.

If you're upgrading from Bazel, updated usage instructions are in docs/development.md and docs/build.md. A summary of the changes:

- please remove node_modules and .bazel
- install rustup (https://rustup.rs/)
- install rsync if not already installed  (on windows, use pacman - see docs/windows.md)
- install Ninja (unzip from https://github.com/ninja-build/ninja/releases/tag/v1.11.1 and
  place on your path, or from your distro/homebrew if it's 1.10+)
- update .vscode/settings.json from .vscode.dist
2022-11-27 15:24:20 +10:00
Stefan Kangas
5551a37f03
Fix typos (#2210) 2022-11-24 20:18:57 +10:00
Damien Elmes
276c42e250 Update to Qt 6.4.0 2022-10-10 12:29:02 +10:00
Damien Elmes
9abc73360e Update Python deps
Addresses a protobuf CVE. Required some other patches due to changes
in latest mypy and pylint.
2022-09-24 09:46:43 +10:00
Damien Elmes
88b3a8bd12 Update to Qt 6.3.2 2022-09-21 12:21:11 +10:00
Damien Elmes
4a884d379f Fix build failing on macOS
I suspect the PyQt maintainer uploaded a new wheel and yanked the old
one, which made pip fall back on a source install which failed. If that's
the case, he really should have used a new version number, as this makes
building/bisecting older releases more cumbersome.
2022-08-25 18:04:37 +10:00
Damien Elmes
c229fbe52f Update to Qt 6.3.1 2022-06-18 09:02:07 +10:00
Damien Elmes
07d96c4bf2 Update waitress for data race fix 2022-06-03 13:02:27 +10:00
Damien Elmes
c4dbaa7970 Support updating single Python dependency 2022-06-03 12:57:31 +10:00
Damien Elmes
0b03919f45 Upgrade to Qt 6.3
Fixes #1753
Fixes #1770
2022-04-20 19:12:10 +10:00
Damien Elmes
d2caab6d5a Update Python deps for Waitress fix
b28c9e8bda

Closes #1731
2022-03-23 22:22:23 +10:00
Damien Elmes
1165939271 Update Python deps, including stable Black
Black 22.1 made some changes that required some minor reformatting.
2022-02-25 15:26:16 +10:00
Damien Elmes
79df188e2a update bundled Python for Linux builds
removes dependency on libcrypt:
https://forums.ankiweb.net/t/issue-building-2-1-50beta3/17630/8
2022-02-18 15:52:41 +10:00
Damien Elmes
91e8f73b69 Fully revert "update to (Py)Qt 6.2.3"
This reverts commit 2c4db58013.

Reverting just the WebEngine component introduced a new bug:
f61c64dd34 (commitcomment-66745823)
2022-02-16 10:13:09 +10:00
Damien Elmes
f61c64dd34 roll back qtwebengine to 6.2.2 to fix broken copy&paste on Windows
https://forums.ankiweb.net/t/anki-2-1-50-beta-3/17501/2
https://forums.ankiweb.net/t/is-this-a-bug-anki-2-1-50-beta3/17528
2022-02-11 23:27:16 +10:00
Damien Elmes
95dbf30fb9 updates to the build process and binary bundles
All platforms:

- rename scripts/ to tools/: Bazelisk expects to find its wrapper script
(used by the Mac changes below) in tools/. Rather than have a separate
scripts/ and tools/, it's simpler to just move everything into tools/.
- wheel outputs and binary bundles now go into .bazel/out/dist. While
not technically Bazel build products, doing it this way ensures they get
cleaned up when 'bazel clean' is run, and it keeps them out of the source
folder.
- update to the latest Bazel

Windows changes:

- bazel.bat has been removed, and tools\setup-env.bat has been added.
Other scripts like .\run.bat will automatically call it to set up the
environment.
- because Bazel is now on the path, you can 'bazel test ...' from any
folder, instead of having to do \anki\bazel.
- the bat files can handle being called from any working directory,
so things like running "\anki\tools\python" from c:\ will work.
- build installer as part of bundling process

Mac changes:

- `arch -arch x86_64 bazel ...` will now automatically use a different
build root, so that it is cheap to switch back and forth between archs
on a new Mac.
- tools/run-qt* will now automatically use Rosetta
- disable jemalloc in Mac x86 build for now, as it won't build under
Rosetta (perhaps due to its build scripts using $host_cpu instead of
$target_cpu)
- create app bundle as part of bundling process

Linux changes:

- remove arm64 orjson workaround in Linux bundle, as without a
readily-available, relatively distro-agonstic PyQt/Qt build
we can use, the arm64 Linux bundle is of very limited usefulness.
- update Docker files for release build
- include fcitx5 in both the qt5 and qt6 bundles
- create tarballs as part of the bundling process
2022-02-10 19:23:07 +10:00
Damien Elmes
2c4db58013 update to (Py)Qt 6.2.3 2022-02-03 18:06:58 +10:00
Damien Elmes
732c33c2b3 update to latest rules_python 2022-01-15 16:16:33 +10:00
Damien Elmes
1315a3a3bb update mypy and mypy-protobuf
- The way mypy gathers site packages has changed slightly, so we had to
update extendsitepkgs.py to work with it.
- Not sure if there's a way to avoid the ignore in
operations/__init__.py. mypy is still ensuring a provided argument has
a .changes attribute, so thankfully we don't seem to have lost much here.
2022-01-15 16:04:04 +10:00
Damien Elmes
d651c85dc8 update most Python deps
mypy and mypy-protobuf have been excluded, as they have changes that
break our build
2022-01-15 15:17:03 +10:00
Damien Elmes
8d90b6b061 run buildifier/buildozer to tidy up BUILD files 2021-12-14 09:18:24 +10:00
Damien Elmes
ed5273fae7 unpin regex & update Python deps
regex was failing to build correctly on the latest Xcode/macOS 12, and
black have dropped it as a dependency due to the build difficulties it
creates.
2021-12-08 15:11:47 +10:00
Damien Elmes
2687e11b86 update to PyQt6.2.2 2021-12-03 19:42:43 +10:00
Damien Elmes
06fb8badfb update Python deps + fix update script
Script should now work properly for PyQt as well.
2021-12-03 19:39:39 +10:00
Damien Elmes
07f3f34bf5 update Python deps; pin jsonschema
jsonschema 4.2 introduced a change that broke our current workaround
for in-memory support.

https://github.com/Julian/jsonschema/pull/873
https://github.com/indygreg/PyOxidizer/issues/457
2021-11-06 08:28:42 +10:00
Damien Elmes
f6a4e74f68 fix Python update script 2021-11-05 15:02:48 +10:00
Damien Elmes
f8ae64043d set local=False for python/protoc/clang
Suspect this will fix these repos being unnecessarily restarted on
changes to the workspace.
2021-11-01 11:38:20 +10:00
Damien Elmes
20873107ac remove PyQt 6.2.0 workarounds
Fixed in the 6.2.1 release, and attempting to sign again on ARM
breaks the build.
2021-10-29 13:48:39 +10:00
Damien Elmes
293bc83fe4 update to PyQt 6.2.1 2021-10-29 08:40:22 +10:00
Damien Elmes
922b3b7dbd arch is not in POSIX
ee644e08a3 (commitcomment-58626200)
2021-10-26 08:06:12 +10:00
Damien Elmes
ae59f68729 update hashes for new darwin-arm64 pyqt6 wheels
https://www.riverbankcomputing.com/pipermail/pyqt/2021-October/044317.html

Should fix Mac CI.
2021-10-25 13:12:30 +10:00
Damien Elmes
e2139f9460 fail build if pyqt install fails 2021-10-25 09:42:21 +10:00
Damien Elmes
d19b943e1a update to latest pyqt5.15
Our tooling now handles the extra wheels correctly
2021-10-25 09:42:14 +10:00
Damien Elmes
8cd905a35f remove a few unnecessary PyQt workarounds
https://www.riverbankcomputing.com/pipermail/pyqt/2021-October/044314.html
2021-10-24 14:24:35 +10:00
Damien Elmes
ee644e08a3 fixes and documentation for Linux ARM64
+ add qt6 dep to wheel install docs
+ remove x86_64 constraint on orjson
2021-10-23 15:22:24 +10:00
Damien Elmes
a14eb6a1e8 improve PyQt install
- use a single script for all PyQt versions
- add hashes
- add a new ./run-qt5.14 script for testing with PyQt5.14
2021-10-23 10:56:17 +10:00
Damien Elmes
70292f07a6 add hashes to most Python deps
pyqt still to do
2021-10-23 08:54:34 +10:00
Damien Elmes
081ec4ef40 update Python deps, and fix update script 2021-10-23 08:43:19 +10:00
Damien Elmes
048a9a2b60 vendor stringcase
It's a tiny library that has not been updated in years, and it was
leading to a warning on startup:

 DeprecationWarning: invalid escape sequence \W
  return re.sub("\W+", "", string)
2021-10-22 08:56:44 +10:00
Damien Elmes
a1b2bfb355 remove duplicate line and unnecessary py.typed insertion in install_pyqt6 2021-10-21 14:11:09 +10:00
Damien Elmes
cbc358ff0b add aliases to run vendored python and node from command line
You can then do './scripts/python -m venv /path/to/venv' to create
a virtual env based on the bundled Python, which can be handy if
you don't happen to have the appropriate version of Python installed
separately.
2021-10-18 19:50:41 +10:00