* Migrate build system to uv
Closes#3787, and is a step towards #3081 and #4022
This change breaks our PyOxidizer bundling process. While we probably
could update it to work with the new venvs & lockfile, my intention
is to use this as a base to try out a uv-based packager/installer.
Some notes about the changes:
- Use uv for python download + venv installation
- Drop python/requirements* in favour of pyproject files / uv.lock
- Bumped to latest Python 3.9 version. The move to 3.13 should be
a fairly trivial change when we're ready.
- Dropped the old write_wheel.py in favour of uv/hatchling. This has
the unfortunate side-effect of dropping leading zeros in our wheels,
which we could try hack around in the future.
- Switch to Qt 6.7 for the dev repo, as it's the first PyQt version
with a Linux/ARM WebEngine wheel.
- Unified our macOS deployment target with minimum required for ARM.
- Dropped unused fluent python files
- Dropped unused python license generation
- Dropped helpers to run under Qt 5, as our wheels were already
requiring Qt 6 to install.
* Build action to create universal uv binary
* Drop some PyOxidizer-related files
* Use Windows ARM64 cargo/node binaries during build
We can't provide ARM64 wheels to users yet due to #4079, but we can
at least speed up the build.
The rustls -> native-tls change on Windows is because ring requires
clang to compile for ARM64, and I figured it's best to keep our Windows
deps consistent. We already built the wheels with native-tls.
* Make libankihelper a universal library
We were shipping a single arch library in a purelib, leading to
breakages when running on a different platform.
* Use Python wheel for mpv/lame on Windows/Mac
This is convenient, but suboptimal on a Mac at the moment. The first
run of mpv will take a number of seconds for security checks to run,
and our mpv code ends up timing out, repeating the process each time.
Our installer stub will need to invoke mpv once first to get it validated.
We could address this by distributing the audio with the installer/stub,
or perhaps by putting the binaries in a .pkg file that's notarized+stapled
and then included in the wheel.
* Add some helper scripts to build a fully-locked wheel
* Initial macOS launcher prototype
* Add a hidden env var to preload our libs and audio helpers on macOS
* qt/bundle -> qt/launcher
- remove more of the old bundling code
- handle app icon
* Fat binary, notarization & dmg
* Publish wheels on testpypi for testing
* Use our Python pin for the launcher too
* Python cleanups
* Extend launcher to other platforms + more
- Switch to Qt 6.8 for repo default, as 6.7 depends on an older
libwebp/tiff which is unavailable on newer installs
- Drop tools/mac-x86, as we no longer need to test against Qt 5
- Add flags to cross compile wheels on Mac and Linux
- Bump glibc target to 2_36, building on Debian Stable
- Increase mpv timeout on macOS to allow for initial gatekeeper checks
- Ship both arm64 and amd64 uv on Linux, with a bash stub to pick
the appropriate arch.
* Fix pylint on Linux
* Fix failure to run from /usr/local/bin
* Remove remaining pyoxidizer refs, and clean up duplicate release folder
* Rust dep updates
- Rust 1.87 for now (1.88 due out in around a week)
- Nom looks involved, so I left it for now
- prost-reflect depends on a new prost version that got yanked
* Python 3.13 + dep updates
Updated protoc binaries + add helper in order to try fix build breakage.
Ended up being due to an AI-generated update to pip-system-certs that
was not reviewed carefully enough:
https://gitlab.com/alelec/pip-system-certs/-/issues/36
The updated mypy/black needed some tweaks to our files.
* Windows compilation fixes
* Automatically run Anki after installing on Windows
* Touch pyproject.toml upon install, so we check for updates
* Update Python deps
- urllib3 for CVE
- pip-system-certs got fixed
- markdown/pytest also updated
* add fill tool
* add fill tool logic
* open colour picker on fill tool activation
* refactor/add fill attr to io clozes
* fill masks in editor
* fill text and inactive masks in reviewer
* fix lint
* remove debug option
(originally merged into a PR branch)
* Make URL schemes dialog more ergonomic
* add name to contributors list
* Title Case
* Tweak build instructions so Cursor picks them up
* Use a warning icon for the URL scheme pop-up
* Default to cancelling
* CHANGE collection size too large error to add MB values and info about compressed vs. uncompressed
* Round f64 to 2 decimals
* Remove line breaks from ftl/core
* Remove string 'uncompressed' from code
* Add string 'uncompressed' to ftl/core
* Remove if statement change introduced to test changes locally
* Run ./check
* ADD name of the button after button number (1 → again...)
* ADD info string to explain what 'correct' means
* Run ./check and make it happy
* Apply suggestion from @dae to make text shorter
* Update TrueRetention.svelte adding description
* Update statistics.ftl to add additional info
* Swap TR with DR
* Change string to 'Is expected to'
* Add help modal to TR table
* Add tooltip slot to Graph.svelte (thanks @Luc-Mcgrady)
* Fix lint warning and failing test
* Remove unused code
* removedd on:mount to make eslint happy
* ADD back on:mount
* ADD back code needed for on:mount
* REMOVE openHelpModal() as I couldn't figure out how to make the title clickable
* attempt to ADD clickable title (BROKEN\!)
* Update ts/lib/components/TitledContainer.svelte
Co-authored-by: Luc Mcgrady <lucmcgrady@gmail.com>
* Update ts/routes/graphs/Graph.svelte
Co-authored-by: Luc Mcgrady <lucmcgrady@gmail.com>
* Update ts/routes/graphs/TrueRetention.svelte
Co-authored-by: Luc Mcgrady <lucmcgrady@gmail.com>
* ADD exported onTitleClick as @Luc-Mcgrady suggested
* REMOVE vite.config.ts file
---------
Co-authored-by: Luc Mcgrady <lucmcgrady@gmail.com>
* Display median interval in Stats instead of mean
Median is better suited than mean for reporting skewed data.
* Display median ease in Stats instead of mean
* Update difficulty.ts
* Update ease.ts
* Update statistics.ftl
* Format eases.rs
* Remove unused import
* Change Median back to Average in UI
* Revert "Change Median back to Average in UI"
This reverts commit e0c1e3f8e4.
* Preserve the old translations for now (dae)
* Show "and others" at the end of the contributor list in the about dialog
* Make about addendum translatable
* Fix CONTRIBUTORS
* Fix CONTRIBUTORS
* Update ftl/qt/about.ftl (dae)
* Feat/grade now
* pass ci
* fix from_queue
* Refactor card answering to support from_queue flag
- Add `from_queue` field to `CardAnswer` struct and proto message
- Modify `answer_card_inner` to handle queue updates based on `from_queue`
- Remove `grade_card` method and consolidate card answering logic
- Update related test cases to set `from_queue` flag
* fix current_changes() called when no op set
* Optimize queue updates for batch card processing
- Refactor `grade_now` to collect processed card IDs first
- Add new `update_queues_for_processed_cards` method for efficient batch queue updates
- Improve queue management by removing entries and updating counts in a single pass
- Remove individual queue update method in favor of batch processing
* pass ci
* keep the same style
* remove ineffective code
* remove unused imports
* cap csv import preview table at 1000 columns
* add fluent message
* show warning when preview table columns have been truncated
* simplify fluent message ($count will almost always be a big num)
* _tr -> tr
I think this one really calls for a poll. Dae, I highly suggest you to ask multiple users whether "Optimize current" and "Optimize all" are clear enough or need "preset". I'm pretty sure most people will find it confusing without "preset".
* Add percentage to FSRS spinner
This commit add a percentage option in SpinBox and SpinBoxFloatRow, set to False
by default.
If it's true, a percent symbol is added at the end of the line before
the increase/decrease button.
While the value is represented as a percentage without decimal places,
the internal representation is not changed. Which mean that a
multiplier must used to compute the string value, indicate to the
input field the min, max and step, and when updating the result.
* Remove unsightly percentage sign, and update historical retention too
https://github.com/ankitects/anki/pull/3679#issuecomment-2579636981
---------
Co-authored-by: Damien Elmes <gpg@ankiweb.net>
* Tweak how the True Retention stats table displays numbers
- Always show fractional parts of numbers even if they are 0 (91.0% not 91%).
- Show "N/A" for percentages instead of 0% when there are 0 total reviews.
* Localise percentages correctly
* Make the True Retention table pretty
* Hide absolute pass/fail table for 'all'
* Run './ninja format'
* Manually run prettier on Svelte 5 components
* Refactor to not use {#snippet}
* Fix lint to pass check:eslint
* Fix lint to pass check:svelte
* Rename t9n -> tr to follow code style
* Replace hard-coded string with a translation string
* Use assertUnreachable(...) for exhaustively matching enum
* Improve i18n and multi-platform display of FSRS Simulator
* Tweak the graph bounds to avoid overlapping of the y-axis tick values and the y-axis title
* Update CONTRIBUTORS
* I18n for 4 more strings
* Reduce TitledContainer wrapper of fsrs simulator graph to maximize content display area
* Clean unused variables
* Update ftl/core/deck-config.ftl
* Update ftl/core/deck-config.ftl
* Add gradient color for forgetting curve
* Add desiredRetention prop for CardInfo
* update CONTRIBUTORS
* Formatting
* Tweak range of gradient
* Tweak: salmon -> tomato
* Get desired retention of the card from backend
* Add a reference line for desired retention
* Fix: Corrected the steel blue's height & Hide desired retention line when yMin is higher than desiredRetentionY
* Add y axis title
* Show desired retention in the tooltip
* I18n: improve translation and vertical text display
* Revert rotatation&writing-mode of vertical title
* Tweak font-size of y axis title
* Fix: delete old desired retention line when changing duration
* Update ftl/core/card-stats.ftl
---------
Co-authored-by: Damien Elmes <dae@users.noreply.github.com>
* Separate failed message from optimal
* No reviews only
* Fix: Can't block optimize if not optimal
* Wording change
* Update ftl/core/deck-config.ftl
* Simplify code (dae)
* Feat/Easy Days
* format
* add easy_days_percentages to deck_config
* configure Easy Days via table
* remove unused code
* add translatable strings & add default of easy days
* don't check easy_days_percentages when deserialize
* pass test::all_reserved_fields_are_removed
* consider next_day_at when interval_to_weekday
* remove y-axis-title created in last simulation
* EstimatedTotalKnowledge should be integer
* Reorder deck option sections (dae)
- Move FSRS to bottom left, to move it closer to the top, and so
the left and right columns appear roughly balanced when FSRS is
enabled.
- Move Easy Days above Advanced
* Don't crash if wrong number of days (dae)
* Use lower field number (dae)
Repeated fields are more compactly stored in the first 15 fields.
* Add "open image" option to editor
* Update qt/aqt/editor.py
Co-authored-by: Ben Nguyen <105088397+bpnguyen107@users.noreply.github.com>
* Update editor.py
* Remove unused import
* Fix "show in folder"
* Fix 'show in folder' on macOS
* Revert "Fix "show in folder""
This reverts commit cf2b33ee9422bcaf8d9e20bd4cce74e5061c13cf.
* Reimplement show_in_folder for Windows (dae)
- Avoid reusing call(), as the startupinfo we were passing in was
breaking the explorer invocation
- Attempt to bring explorer to the front after the window has been show,
as it otherwise appears under Anki (at least when running from source)
---------
Co-authored-by: Ben Nguyen <105088397+bpnguyen107@users.noreply.github.com>
Co-authored-by: Damien Elmes <gpg@ankiweb.net>
* graduate card when user press hard and has 0 learning steps
* fix error: useless conversion to the same type
* do the same thing to again
* fix expected `Option<u32>`, found integer
* ./ninja format
* Update to FSRS-rs v1.2.0
* if else -> match
* Weight length check has been moved into FSRS (dae)
* Don't mention the number of FSRS parameters (dae)
It has changed, and may change again.
* Empty cards is undoable
If there was a reason for this operation not to be undoable, I can't easily guess it. My main hyposhesis was that the number of deleted card may be too big. But I realized that deleting a deck is undoable and may delete as many note.
As you may know, I realized that only the undoable operations triggered notification in AnkiDroid that we may have to update the UI. And while I just wanted to trigger more notifications, some reviewers thought it would be nicer if the operation were returning a OpChanges. So here it's done. If you would please consider merging it.
I decided to introduce a new string because the closest strings I could find currently are "Empty cards..." and the trailing commas don't seem nice in "undo". And the title, which we may not be able to reuse in all language
* Don't count cards that have already been removed (dae)
* right click and copy on image works
* renamed helper fn
* separated functionality of copy and copy image
* Update CONTRIBUTORS
* snake case
* Update CONTRIBUTORS