Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Send updates when NoteID is populated #106

Merged
merged 9 commits into from
Apr 14, 2023

Conversation

benjamin-weller
Copy link
Contributor

@benjamin-weller benjamin-weller commented Mar 2, 2023

Jason can you please take a look at generally what I'm thinking about doing and give me a LGTM or not. I just don't want to get going on these changes and be barking up the wrong tree.

Continuation of PR 92.

@benjamin-weller benjamin-weller mentioned this pull request Mar 2, 2023
@jasonwilliams
Copy link
Owner

Hey @benjamin-weller sorry for being slow to look at this. I've been away i will try and take a look this week

@benjamin-weller
Copy link
Contributor Author

SG, no worries. I'm relatively green WRT to JavaScript async + await, so I think that's likely where I could have missed something.

Additionally how would you suggest I write unit tests for these changes?

@benjamin-weller benjamin-weller changed the title Send updates when NoteID is populated, and Insert NoteID into markdown when creating a card Send updates when NoteID is populated Mar 15, 2023
async createAndUpdateCards() {
// Push the updated cards (based on noteID)
const updateCards = this.cards.filter((v) => v.noteId);
this._pushUpdatedCardsToAnki(updateCards);
Copy link
Owner

@jasonwilliams jasonwilliams Mar 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could probably use reduce so you only cycle through the cards once

    this.cards.reduce((acc, v) => {v.noteId ? acc[update].push(v) : acc[new].push(v) }, {})

Or something like that

Copy link
Contributor Author

@benjamin-weller benjamin-weller Mar 25, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll going to use forEach here because that's what makes sense in my brain.

async pushNewCardsToAnki() {
// Calls anki to update the fields of all the passed cards.
private async _pushUpdatedCardsToAnki(cards: Card[]) {
cards?.map((card) => this.ankiService?.updateFields(card));
Copy link
Owner

@jasonwilliams jasonwilliams Mar 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is async but there's no await being used.
You're also not returning any value so map is redundant here, you may instead just want to use forEach.

Do you want to wait for this function to finish? If so you could return the promises into a Promise.all() and await that

Suggested change
cards?.map((card) => this.ankiService?.updateFields(card));
const cardsPromise = cards?.map((card) => this.ankiService?.updateFields(card));
await Promise.all(cardsPromise);

The ? on cards would be redundant as it should always be an array coming into this function.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going to drop the async on this function as I don't care exactly when this finishes.
I'll also switch to forEach.
I'll remove the optional chaining you mentioned.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we do need to care when operations like this finish though. Due to the progress bar that’s shown in VSCode, it needs to know when to stop showing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've taken your advice and ensured I'm awaiting the async _pushUpdatedCardsToAnki function now.

@jasonwilliams
Copy link
Owner

Yeah so far looks good.
Just so I understand, we don't have the code that handles adding the noteID into the markdown just yet right?

So far I see support for parsing the note and updating/instead of pushing if there is a noteid (this PR)

For tests:
I would say do the best you can, but don't worry too much about it. Im happy to help out on tests, I may try and migrate to vitest soon anyway so if you're not up to it I can change and add later.

@benjamin-weller
Copy link
Contributor Author

Just so I understand, we don't have the code that handles adding the noteID into the markdown just yet right?

Yes I have some "working" code for this on my computer. I want to roll this change out first because I perceive that change to be higher risk/would clog up the review for this change.

WRT tests, I manually tested. Idk how exactly I would mock updating a card in Anki here? Unless you have a good idea now on how to do that I'm leaning towards not implementing them for this feature. That won't be the case for the next one (updating the markdown) as that's higher risk imo.

Proof of manual testing (works on my machine):

Deck Prior to run:
image

Content of MD file:

# Deck Name Is Definately Not Scratch

## NEW NAME IS DEFINATELY NOT YOLO

<!-- notecardId: 1679716453114 -->

New back side of card

Ran: Send To Own Deck

Deck post run:
image

I want to point out that my changes allow you to update a notecard regardless of which deck it exists in. This may feel like a bug at first, but it's what I want, my use case; I may relocate an entire subsection of markdown document, but that doesn't mean when I re-push to Anki that I want to re-create new cards, I just want to know that the particular cards is up to date.

@jasonwilliams
Copy link
Owner

jasonwilliams commented Mar 25, 2023

I want to point out that my changes allow you to update a notecard regardless of which deck it exists in. This may feel like a bug at first, but it's what I want, my use case; I may relocate an entire subsection of markdown document, but that doesn't mean when I re-push to Anki that I want to re-create new cards, I just want to know that the particular cards is up to date.

sure this sounds fair, but it may conflict with the “Send dir to Anki” command. Which sends cards to Anki based on their directory location. If I have noteids on the cards and move them which operation wins out?

We may want to think about and how we respond to it

@mkraenz
Copy link
Contributor

mkraenz commented Mar 25, 2023

Hi, awesome job! Updates are the one feature I've been missing, so very happy this is getting tackled. Thank you so much!

In eager awaiting of this, I've written a script to update an existing markdown file (without note ids) with the note ids from Anki, in a similar format as #106 (comment) does (though I'm using <!-- noteId: 1636220174001 --> for now).

You can find it in this gist https://gist.github.com/mkraenz/a7e0473ca80c07522ff75dc2fd9e52ba

Maybe it becomes a reference for you or somebody else. In particular, the sanitization of the card front is not trivial.
Note that I do assume a nicely linted markdown file.

The summary at the end looks like this for 526 cards with backticks, question marks, parentheses in the card front all being gracefully handled. Only one of the cards cannot be resolved to its note id.

@@@@@@@@@@@@@@@@@@@@@@@ DONE @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
OVERWRITTEN FILE ON DISK:  /home/mirco/Desktop/anki.test.md.withNoteids.md 

Total number of cards processed:  526
Number of successfully written note ids for cards:  525
Number of missing node ids for cards:  1
MISSING NOTE_IDS FOR CARDS:
 linux `$RANDOM`

PS: Sorry for randomly dropping this into this PR.

@benjamin-weller
Copy link
Contributor Author

benjamin-weller commented Mar 30, 2023

I want to point out that my changes allow you to update a notecard regardless of which deck it exists in. This may feel like a bug at first, but it's what I want, my use case; I may relocate an entire subsection of markdown document, but that doesn't mean when I re-push to Anki that I want to re-create new cards, I just want to know that the particular cards is up to date.

sure this sounds fair, but it may conflict with the “Send dir to Anki” command. Which sends cards to Anki based on their directory location. If I have noteids on the cards and move them which operation wins out?

We may want to think about and how we respond to it

I'm not certain exactly which one wins out tbh. I'm willing to feature flag this (only have cards be updated if the user opts in), this ensures that they explicitly agree that things might not be 100% compatible. Is that fair for you?

@benjamin-weller
Copy link
Contributor Author

Hi, awesome job! Updates are the one feature I've been missing, so very happy this is getting tackled. Thank you so much!

In eager awaiting of this, I've written a script to update an existing markdown file (without note ids) with the note ids from Anki, in a similar format as #106 (comment) does (though I'm using <!-- noteId: 1636220174001 --> for now).

You can find it in this gist https://gist.github.com/mkraenz/a7e0473ca80c07522ff75dc2fd9e52ba

Maybe it becomes a reference for you or somebody else. In particular, the sanitization of the card front is not trivial. Note that I do assume a nicely linted markdown file.

The summary at the end looks like this for 526 cards with backticks, question marks, parentheses in the card front all being gracefully handled. Only one of the cards cannot be resolved to its note id.

@mkraenz It's great to hear that hopefully this feature will have users!

Yes the card sanitation is currently the most tricky part, I assume that the text of the header is equivalent to the text of the front of the card (I ask the HTML for the inner content but even then there can be stuff like <strong> tags which interfere with string matching). I'll take a closer look at your implementation, I'm really hoping that I can find a NPM package that will just simply reverse engineer a given HTML string to markdown.

@jasonwilliams
Copy link
Owner

I'm not certain exactly which one wins out tbh. I'm willing to feature flag this (only have cards be updated if the user opts in), this ensures that they explicitly agree that things might not be 100% compatible. Is that fair for you?

Ok lets feature flag it for now.
I also think at some point in the future we could have a command that re-moves cards based on their new position in the directory (assuming you're using the send to dir feature). This would mitigate the issue we face of moving cards then re-updating to somewhere else.

@benjamin-weller
Copy link
Contributor Author

Is there anything else I need to do such that these changes are ready to merge?

Copy link
Owner

@jasonwilliams jasonwilliams left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I’ve been slow on this, LGTM

@jasonwilliams jasonwilliams merged commit 6824b5b into jasonwilliams:main Apr 14, 2023
@jasonwilliams
Copy link
Owner

@benjamin-weller how has this been for you? Have you been testing it?
I guess we need a commit which adds the noteID back into the markdown

@benjamin-weller
Copy link
Contributor Author

Hey, I've created a new PR, let's talk there.

@Spirarel
Copy link

Spirarel commented May 9, 2023

I'm not certain exactly which one wins out tbh. I'm willing to feature flag this (only have cards be updated if the user opts in), this ensures that they explicitly agree that things might not be 100% compatible. Is that fair for you?

Ok lets feature flag it for now. I also think at some point in the future we could have a command that re-moves cards based on their new position in the directory (assuming you're using the send to dir feature). This would mitigate the issue we face of moving cards then re-updating to somewhere else.

Are you guys approaching a release soon or do we need to install from main?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants