Commit Graph

823 Commits

Author SHA1 Message Date
Damien Elmes
3d0ddc8539 make flag changes in the reviewer undoable
This splits update_card() into separate undoable/non-undoable ops
like the change to notes in b4396b94abdeba3347d30025c5c0240d991006c9

It means that actions get a blanket 'Update Card' description - in the
future we'll probably want to either add specific actions to the backend,
or allow an enum or string to be passed in to describe the op.

Other changes:
- card.flush() can no longer be used to add new cards. Card creation
is only supposed to be done in response to changes in a note's fields,
and this functionality was only exposed because the card generation
hadn't been migrated to the backend at that point. As far as I'm aware,
only Arthur's "copy notes" add-on used this functionality, and that should
be an easy fix - when the new note is added, the associated cards will
be generated, and they can then be retrieved with note.cards()
- tidy ups/PEP8
2021-03-10 11:53:27 +10:00
Damien Elmes
f1a1b0891e make mark toggling undoable
- note.flush() behaves like before, as otherwise actions or add-ons
that perform bulk flushing would end up creating an undo entry for
each note
- added col.update_note() to opt in to the new behaviour
- tidy up the names of some related routines
2021-03-10 11:53:27 +10:00
Damien Elmes
bec77fd420 undo support for bulk tag add/remove 2021-03-10 11:47:53 +10:00
Damien Elmes
49a1970399 note deletion undo; refactoring
- transact() now automatically clears card queues unless an op
opts-out (and currently only AnswerCard does). This means there's no
risk of forgetting to clear the queues in an operation, or when undoing/
redoing
- CollectionOp->UndoableOp
- clear queues when redoing "answer card", instead of clearing redo
when clearing queues
2021-03-10 11:47:53 +10:00
Damien Elmes
9445e2ee22 drop some unused properties 2021-03-10 11:47:53 +10:00
Damien Elmes
605ad1c9ee remove unnecessary setMod() calls 2021-03-10 11:47:53 +10:00
Damien Elmes
57d7e3e2ab commit immediately when there's no active checkpoint
Reviews and operations on the backend that support undoing can now be
committed immediately, so they will not be lost in the event of a crash.

This required tweaks to a few places:

- don't set collection mtime on save() unless changes were made in
Python, as otherwise we end up accidentally clearing the backend undo
queue
- autosave() is now run on every reset()
- garbage collection now runs in a timer, instead of relying on
autosave() to be run periodically
2021-03-10 11:47:53 +10:00
Damien Elmes
40aff4447a undo support for note adding 2021-03-10 11:47:53 +10:00
Damien Elmes
b466f0ce90 rework undo
- use dataclasses for the review/checkpoint undo cases, instead of the
nasty ad-hoc list structure
- expose backend review undo to Python, and hook it into GUI
- redo is not currently exposed on the GUI, and the backend can only
cope with reviews done by the new scheduler at the moment
- the initial undo prototype code was bumping mtime/usn on undo, but
that was not ideal, as it was breaking the queue handling which expected
the mtime to match. The original rationale for bumping mtime/usn was
to avoid problems with syncing, but various operations like removing
a revlog can't be synced anyway - so we just need to ensure we clear the
undo queue prior to syncing
2021-03-10 11:47:53 +10:00
Damien Elmes
c9eeb91e0a initial work on undoing reviews+burying siblings
- fetch sfld and csum when fetching notes, to make it cheaper
to write them back out unmodified
- make `fields` private, and access it via accessors, so we can
still catch when fields have been mutated without calling
prepare_for_update()
- fix python importing code passing a string in as the checksum
2021-03-10 11:47:53 +10:00
Damien Elmes
b81e2c0265 Ensure we purge caches when rolling back
Fixes #1056
2021-03-08 10:39:18 +10:00
Damien Elmes
5f9792392a don't cap child counts to parents when reviewing in v2
https://forums.ankiweb.net/t/anki-2-1-41-beta/7305/59

When originally implemented in 21023ed3e5,
a given deck's limit was bound by its parents. This lead to a deck list
that seemed more logical in the parent limit < child limit case, as
child counts couldn't exceed a parent's, but it obscured the fact that
child decks could still be clicked on to show cards. And in the parent
limit > child limit case, the count shown for the child on the deck list
did not reflect how many cards were actually available and would be
delivered.

This change updates the reviewer to ignore parent limits when getting
review counts for the deck, which makes the behaviour consistent with
the deck list, which was recently changed to ignore parent limits.

Neither solution is ideal - this was a tradeoff v2 made in order to keep
fetching of review cards from multiple decks reasonably performant. The
experimental scheduling work moves back to respecting limits on
individual children, so this should hopefully improve in the future.

Also removed _revForDeck(), which was unused.
2021-03-02 10:23:06 +10:00
Damien Elmes
de7baa80bd switch to 4 buttons when previewing in test scheduler
- Currently we just use 1.5x and 2x the normal preview delay; we could
change this in the future.
- Don't try to capture the current state; just use a flag to denote
exit status.
- Show (end) when exiting
2021-03-01 23:47:00 +10:00
Damien Elmes
4387e3ed86 fix reps updating in v2, but do it in answerCard instead of getCard 2021-03-01 21:48:02 +10:00
Damien Elmes
8f0c8b6f8a use different approach to running tests twice
The symlink approach was breaking on Windows
2021-03-01 12:47:39 +10:00
Damien Elmes
2c6b6734b5 experimental queue building
Still a work in progress, and hidden behind a feature flag.
2021-03-01 12:18:21 +10:00
RumovZ
92cbf168f6 Catch DeckIsFilteredError directly on frontend 2021-02-26 11:32:40 +01:00
RumovZ
ef925a88d6 Add filtered deck error localisation on backend 2021-02-26 11:32:26 +01:00
Damien Elmes
f165576992 implement leech handling
Also change the default for new users to "tag only"
2021-02-23 17:35:20 +10:00
Damien Elmes
69448365c4 move test code behind env var 2021-02-22 21:32:18 +10:00
Damien Elmes
97300a16bf implement fuzzing
Notes:

- The fuzz seed is now derived from the card id and # of reps, so
if a card is undone and done again, the same fuzz will be used.
- The intervals shown on the answer buttons now include the fuzz, instead
of hiding it from the user. This will prevent questions about due dates
being different to what was shown on the buttons, but will create
questions about due dates being different for cards with the same
interval, and some people may find it distracting for learning cards.
The new approach is easier to reason about, but time will tell
whether it's a net gain or not.
- The env var we were using to shift the clock away from rollover for
unit tests has been repurposed to also disable fuzzing, which simplifies
the tests.
- Cards in filtered decks without scheduling now have the preview delay
fuzzed.
- Sub-day learning cards are mostly fuzzed like before, but will apply
the up-to-5-minutes of fuzz regardless of the time of day.
- The answer buttons now round minute values, as the fuzz on short
intervals is distracting.
2021-02-22 21:31:53 +10:00
Damien Elmes
08c5fe474a make checkRevIvl() assert so pytest can print values; fix missed check 2021-02-22 21:31:53 +10:00
Damien Elmes
f82cf0cd4b drop some unused code 2021-02-22 21:31:53 +10:00
Damien Elmes
3af5221895 plug new answering code in
This is not the way the code is intended to be used, but making it
conform to the existing API allows us to exercise the existing unit
tests and provides partial backwards compatibility.

- Leech handling is currently broken
- Fix answered_at in wrong units, and not being used
2021-02-22 21:31:53 +10:00
Damien Elmes
f811beae5e remove burySiblings()'s dependency on newConf()/revConf() 2021-02-22 21:31:53 +10:00
Damien Elmes
7dc05253c1 fix a few more instances where v2 tests were referencing 'left today' 2021-02-22 21:31:53 +10:00
Damien Elmes
72389595fa tidy up top of file 2021-02-22 21:31:53 +10:00
Damien Elmes
63df7ee7a9 move re-queuing out of _answerCard() 2021-02-22 21:31:53 +10:00
Damien Elmes
a112a4403a duplicate schedv2.py in scheduler.py 2021-02-22 11:40:19 +10:00
Damien Elmes
c659898ee1 separate queue building and card answering 2021-02-22 11:33:28 +10:00
Damien Elmes
b8ad694006 move more routines down 2021-02-22 11:14:41 +10:00
Damien Elmes
4c5d4befbf move routines not related to building/answering to bottom of file 2021-02-22 11:07:56 +10:00
Damien Elmes
e7bcc22d6f move legacy aliases to bottom of schedv2.py 2021-02-22 10:57:08 +10:00
Damien Elmes
f50cd43e75 fix incorrect nested review counts in v2 scheduler
https://forums.ankiweb.net/t/problem-with-anki-subdecks/7689
2021-02-21 22:48:14 +10:00
Damien Elmes
53d9433d94 Revert "use v2 scheduler+new timezone handling by default for new users"
This reverts commit 8372931b9b.

I fear this will be too disruptive - let's give AnkiDroid a bit more
time to catch up. Reverting this will mean new users are presented with
an upgrade notice on first startup, which looks a bit silly, but it's
probably the lesser of two evils.
2021-02-21 19:03:46 +10:00
Damien Elmes
8372931b9b use v2 scheduler+new timezone handling by default for new users
- In corner cases, enabling the new timezone handling later can cause
reviews to shift forward or back a day, so it's best to have it on
by default.
- https://github.com/ankidroid/Anki-Android/issues/5805 has not landed
in a stable release yet, but will hopefully not be too far off by the
time 2.1.41 is released.
- Existing users will be unaffected, as the upgrade prompt in the previous
commit asks them if they use AnkiDroid.
- Users starting on AnkiDroid will be unaffected, as their collections
will still be on V1.
- The error message AnkiWeb gives when syncing an older AnkiDroid
with the new timezone enabled has been updated to direct users to the
preferences screen.
2021-02-21 17:18:08 +10:00
Damien Elmes
5ae66af5d2 rework v2 scheduler upgrade; drop downgrade
- Rework V2 upgrade so that it no longer resets cards in learning,
or empties filtered decks.
- V1 users will receive a message at the top of the deck list
encouraging them to upgrade, and they can upgrade directly from that
screen.
- The setting in the preferences screen has been removed, so users
will need to use an older Anki version if they wish to switch back to
V1.
- Prevent V2 exports with scheduling from being importable into a V1
collection - the code was previously allowing this when it shouldn't
have been.
- New collections still default to v1 at the moment.

Also add helper to get map of decks and deck configs, as there were
a few places in the codebase where that was required.
2021-02-21 15:50:41 +10:00
Damien Elmes
54fa322f3d add some flush() calls and fix a card type in test_schedv2
Will help test when code is moved to backend
2021-02-20 14:00:26 +10:00
Damien Elmes
713bf254c8 stop checking "steps left today" in test_schedv2 2021-02-20 13:59:07 +10:00
Damien Elmes
2a7945f4be fix __repr__ in collection 2021-02-20 13:57:53 +10:00
Damien Elmes
b13d28cc5b tidy up doc string 2021-02-19 10:04:57 +10:00
abdo
010ebef12e Add docstrings to find_cards() and find_notes() 2021-02-17 17:30:38 +03:00
Henrik Giesel
87febe489e Allow for passing in custom note type and template 2021-02-12 02:12:03 +01:00
Henrik Giesel
270cef63f4 Allow for passing in custom note types for rendering ephemeral cards 2021-02-12 01:53:03 +01:00
Damien Elmes
35840221bb tweak search wording and tidy up API
- SearchTerm -> SearchNode
- Operator -> Joiner; share between messages
- build_search_string() supports specifying AND/OR as a convenience
- group_searches() makes it easier to negate
2021-02-11 19:57:19 +10:00
Damien Elmes
59ccfe5918 more search bikeshedding
While implementing the overdue search, I realised it would be nice to
be able to construct a search string with OR and NOT searches without
having to construct each part individually with build_search_string().

Changes:

- Extends SearchTerm to support a text search, which will be parsed
by the backend. This allows us to do things like wrap text in a group
or NOT node.
- Because SearchTerm->Node conversion can now fail with a parsing error,
it's switched over to TryFrom
- Switch concatenate_searches and replace_search_term to use SearchTerms,
so that they too don't require separate string building steps.
- Remove the unused normalize_search()
- Remove negate_search, as this is now an operation on a Node, and
users can wrap their search in SearchTerm(negated=...)
- Remove the match_any and negate args from build_search_string

Having done all this work, I've just realised that perhaps the original
JSON idea was more feasible than I first thought - if we wrote it out
to a string and re-parsed it, we would be able to leverage the existing
checks that occur at parsing stage.
2021-02-11 17:11:17 +10:00
Damien Elmes
5ab115c145 convert some pylib strings to f-strings with flynt
excluded some changes where readability got noticeably worse
2021-02-11 09:51:09 +10:00
Damien Elmes
bb29ce88f3 minor code cleanups with pyupgrade
- pyupgrade --py38-plus --keep-runtime-typing --keep-percent-format
- third-party mpv and winpaths excluded
2021-02-11 09:43:40 +10:00
Damien Elmes
9ce4b21935 add markdown flag for deck description
Needed so we can display consistently, and gradually transition over
2021-02-09 18:47:19 +10:00
Damien Elmes
a8ddb65e1c add ability to force interval reset
- use trailing ! to force a reset
- use - instead of ..
- tweak i18n messages and error handling
2021-02-08 22:33:27 +10:00