Stvad / CrowdAnki

Plugin for Anki SRS designed to facilitate cooperation on creation of notes and decks.
MIT License
520 stars 44 forks source link

Cancel on Change note type doesn't cancel #143

Open boydkelly opened 2 years ago

boydkelly commented 2 years ago

Hi, I'm having an issue that probably involves also brainbrew and/or assetmanager. I have been trying to set up a second deck (lets call it Examples) to import from crowdanki. Crowdanki + brainbrew for Deck A is working just fine. Then I set up the Examples deck (ie export via crowdanki, run brainbrew init and re-import via crowdanki). Now when I go back to Import from Crowdanki and select my A deck.json, Crowdanki tells me that it is currently using the note type from the Examples Deck (see screenshot). I know this is very wrong and won't work, so I click 'Cancel'. Crowdanki imports the deck anyways with the wrong note type, and the only way I can correct this is to restore a backup.

What does appear to me to be clearly a crowdanki issue is clicking cancel and then the import proceeds.

However the fact that the wrong note type is recognized seems a mystery to me. And I totally realize that I have no error message or more information. I am wondering whether Assetmanager or Brainbrew is causing this issue. But since you guys are the experts you might have some idea or opionion on where the problem might be coming from. What could cause crowdanki to not recognize the note type for a particular deck? Thanks!

Screenshot from 2021-10-10 00-11-50

aplaice commented 2 years ago

What does appear to me to be clearly a crowdanki issue is clicking cancel and then the import proceeds.

Yes, this is an ugly, if known, behaviour of CrowdAnki. (See #21 and here in the source code.) Sorry!

However the fact that the wrong note type is recognized seems a mystery to me.

What are the crowdanki_uuids of the different note types (in A and in examples)? (This should be in the BrainBrew recipes yaml files, listed as the model_id.*) (Are they the same?) You might be hit by the fixed-in-master (#136) but not-in-release bug where different note types had the same crowdanki_uuid.

* Alternatively, you could check by using this debug console snippet (you can access the debug console with Ctrl+Shift+; and execute the snippet with Ctrl+Return):

```python repeated = {} for model in filter(lambda model: 'crowdanki_uuid' in model, self.col.models.all()): cu = model["crowdanki_uuid"] if cu in repeated: repeated[cu] = True else: repeated[cu] = False if any(repeated.values()): print("WARNING! There are repeated Note Model uuids!") else: print("There are no repeated Note Model uuids! Everything is OK!") ```

Otherwise, I'm also mystified.

ohare93 commented 2 years ago

Ah this old issue. Wasn't this cancel issue fixed?

Can you link us to your repo (or the PR) to see the differences between these two decks in the Brain Brew yaml? :pray: How did you go about creating the second deck in the first place? If you exported it via CrowdAnki and put that into your repo via a Brain Brew init then there should be no issue. If you just copy/pasted your orginal deck objects in your Brain Brew repo, then perhaps your deck uuid is indeed the same :sweat_smile:

boydkelly commented 2 years ago

hmmm.... Looks like I do indeed have repeaated Note Model uuids. And yes since the note types can be complicated I do clone them. And my deck has been around for a few years now as well. A lot of water has flowed under the bridge.

So what is the best way to remediate this? Can I just manually go and edit/differentiate the crowdanki_uuid? Thanks!

repeated = {} ... for model in filter(lambda model: 'crowdanki_uuid' in model, ... self.col.models.all()): ... cu = model["crowdanki_uuid"] ... if cu in repeated: ... repeated[cu] = True ... else: ... repeated[cu] = False ... ... if any(repeated.values()): ... print("WARNING! There are repeated Note Model uuids!") ... else: ... print("There are no repeated Note Model uuids! Everything is OK!") WARNING! There are repeated Note Model uuids!

ohare93 commented 2 years ago

Make a deck in Anki, export it with CrowdAnki, copy the Uuid of the deck, and copy paste it into your new one you created in Brain Brew? Could be that simple :sweat_smile:

Would probably be good to allow CrowdAnki to continue processing if the Deck Uuid is blank, and it would assume this is a new deck.

aplaice commented 2 years ago

So what is the best way to remediate this? Can I just manually go and edit/differentiate the crowdanki_uuid?

You can indeed just edit the note model crowdanki_uuid (the model_id) in your BrainBrew deck files. Unfortunately, when you import the edited deck, you'll (I think) end up with the relevant note models duplicated. (You'll have the "original" versions with the wrong crowdanki_uuids and the "new" versions, with correct, unique crowdanki_uuids, named "orginal-note-model-type-xxxxx".) This isn't a serious issue — you can delete the original ones and rename the new ones — but is slightly messy.

I'd recommend running the following console script which will disambiguate the non-unique crowdanki_uuids. It'll also print out the new crowdanki_uuid for each note model whose uuid has been changed, in case you have unimported changes in the BrainBrew files (you can then manually edit the relevant model_ids to be the new crowdanki_uuid). If you don't have unimported changes in BrainBrew then you can just export from Anki with CrowdAnki and transform with BrainBrew like normal (without editing anything manually).

from uuid import uuid1

uuids = []

for model in filter(lambda model: 'crowdanki_uuid' in model,
                    sorted(self.col.models.all(), key=lambda m: m["id"])):
    # we're sorting in the hope that note models with higher ids 
    # (which mostly corresponds to creation date) were created later, 
    # so we change the uuid of the copies, not the original
    cu = model["crowdanki_uuid"]
    if cu in uuids:
        new_uuid = str(uuid1())
        print("Replacing UUID for note model " + model["name"] + " with " + new_uuid + " !")
        model["crowdanki_uuid"] = new_uuid
        self.col.models.save(model)
    else:
        uuids.append(cu)

I hope this helps! Sorry for the problem!


Wasn't this cancel issue fixed?

Unfortunately not. :( From what I recall, it's annoying since the dialogue pops up in the middle of the import, so it's not even clear what's the right thing to do. Do we cancel the entire import (and undo any changes that have already been made) or just not modify the notes with the "problematic" note model (but what do we do with new notes with the problematic note model (just not import them?); also the user is then left in a confusing partially-imported/partially-not state)?

boydkelly commented 2 years ago

I hope this helps! Sorry for the problem!

Yes it did. I did have to do a brainbrew init on the crowdanki export. But everything seems to be ok now. Thanks very much for the help here! Awesome project. Crowdanki and brainbrew are the two best Anki plugins!!!

ohare93 commented 2 years ago

Thanks again @aplaice, you are the king maintainer of CrowdAnki :clap: