diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 88cff1adb..f41d0d36f 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -18,7 +18,7 @@ support site, it would be great if you could add your name below as well. ******************** -- Sample Name +Erez Volk ******************** diff --git a/pylib/anki/importing/noteimp.py b/pylib/anki/importing/noteimp.py index 8b190a61b..eb11504cc 100644 --- a/pylib/anki/importing/noteimp.py +++ b/pylib/anki/importing/noteimp.py @@ -64,11 +64,13 @@ class NoteImporter(Importer): allowHTML = False importMode = 0 mapping: Optional[List[str]] + tagModified: Optional[str] def __init__(self, col: _Collection, file: str) -> None: Importer.__init__(self, col, file) self.model = col.models.current() self.mapping = None + self.tagModified = None self._tagsMapped = False def run(self) -> None: @@ -271,6 +273,13 @@ content in the text file to the correct fields.""" self.col.tags.register(n.tags) tags = self.col.tags.join(n.tags) return [intTime(), self.col.usn(), n.fieldsStr, tags, id, n.fieldsStr, tags] + elif self.tagModified: + tags = self.col.db.scalar("select tags from notes where id = ?", id) + tagList = self.col.tags.split(tags) + self.tagModified.split() + tagList = self.col.tags.canonify(tagList) + self.col.tags.register(tagList) + tags = self.col.tags.join(tagList) + return [intTime(), self.col.usn(), n.fieldsStr, tags, id, n.fieldsStr] else: return [intTime(), self.col.usn(), n.fieldsStr, id, n.fieldsStr] @@ -283,6 +292,13 @@ update notes set mod = ?, usn = ?, flds = ?, tags = ? where id = ? and (flds != ? or tags != ?)""", rows, ) + elif self.tagModified: + self.col.db.executemany( + """ +update notes set mod = ?, usn = ?, flds = ?, tags = ? +where id = ? and flds != ?""", + rows, + ) else: self.col.db.executemany( """ diff --git a/pylib/tests/test_importing.py b/pylib/tests/test_importing.py index 78c1edb2e..ae7406fc1 100644 --- a/pylib/tests/test_importing.py +++ b/pylib/tests/test_importing.py @@ -1,6 +1,7 @@ # coding: utf-8 import os +from tempfile import NamedTemporaryFile from anki.importing import ( Anki2Importer, @@ -194,6 +195,100 @@ def test_csv2(): deck.close() +def test_tsv_tag_modified(): + deck = getEmptyCol() + mm = deck.models + m = mm.current() + f = mm.newField("Top") + mm.addField(m, f) + mm.save(m) + n = deck.newNote() + n["Front"] = "1" + n["Back"] = "2" + n["Top"] = "3" + n.addTag("four") + deck.addNote(n) + + with NamedTemporaryFile(mode="w") as tf: + tf.write("1\tb\tc\n") + tf.flush() + i = TextImporter(deck, tf.name) + i.initMapping() + i.tagModified = "boom" + i.run() + + n.load() + assert n["Front"] == "1" + assert n["Back"] == "b" + assert n["Top"] == "c" + assert "four" in n.tags + assert "boom" in n.tags + assert len(n.tags) == 2 + assert i.updateCount == 1 + + deck.close() + + +def test_tsv_tag_multiple_tags(): + deck = getEmptyCol() + mm = deck.models + m = mm.current() + f = mm.newField("Top") + mm.addField(m, f) + mm.save(m) + n = deck.newNote() + n["Front"] = "1" + n["Back"] = "2" + n["Top"] = "3" + n.addTag("four") + n.addTag("five") + deck.addNote(n) + + with NamedTemporaryFile(mode="w") as tf: + tf.write("1\tb\tc\n") + tf.flush() + i = TextImporter(deck, tf.name) + i.initMapping() + i.tagModified = "five six" + i.run() + + n.load() + assert n["Front"] == "1" + assert n["Back"] == "b" + assert n["Top"] == "c" + assert list(sorted(n.tags)) == list(sorted(["four", "five", "six"])) + + deck.close() + + +def test_csv_tag_only_if_modified(): + deck = getEmptyCol() + mm = deck.models + m = mm.current() + f = mm.newField("Left") + mm.addField(m, f) + mm.save(m) + n = deck.newNote() + n["Front"] = "1" + n["Back"] = "2" + n["Left"] = "3" + deck.addNote(n) + + with NamedTemporaryFile(mode="w") as tf: + tf.write("1,2,3\n") + tf.flush() + i = TextImporter(deck, tf.name) + i.initMapping() + i.tagModified = "right" + i.run() + + n.load() + assert n.tags == [] + assert i.updateCount == 0 + + deck.close() + + def test_supermemo_xml_01_unicode(): deck = getEmptyCol() file = str(os.path.join(testDir, "support/supermemo1.xml")) diff --git a/qt/aqt/importing.py b/qt/aqt/importing.py index 756b0db91..65e649c7f 100644 --- a/qt/aqt/importing.py +++ b/qt/aqt/importing.py @@ -91,6 +91,7 @@ class ImportDialog(QDialog): self.frm.autoDetect.clicked.connect(self.onDelimiter) self.updateDelimiterButtonText() self.frm.allowHTML.setChecked(self.mw.pm.profile.get("allowHTML", True)) + self.frm.importMode.currentIndexChanged.connect(self.importModeChanged) self.frm.importMode.setCurrentIndex(self.mw.pm.profile.get("importMode", 1)) # import button b = QPushButton(_("Import")) @@ -179,6 +180,9 @@ you can enter it here. Use \\t to represent tab.""" self.mw.pm.profile["importMode"] = self.importer.importMode self.importer.allowHTML = self.frm.allowHTML.isChecked() self.mw.pm.profile["allowHTML"] = self.importer.allowHTML + if self.frm.tagModifiedCheck.isChecked(): + self.importer.tagModified = self.frm.tagModifiedTag.toPlainText() + self.mw.pm.profile["tagModified"] = self.importer.tagModified did = self.deck.selectedId() if did != self.importer.model["did"]: self.importer.model["did"] = did @@ -283,6 +287,14 @@ you can enter it here. Use \\t to represent tab.""" def helpRequested(self): openHelp("importing") + def importModeChanged(self, newImportMode): + if newImportMode == 0: + allowTagModified = True + else: + allowTagModified = False + self.frm.tagModifiedCheck.setEnabled(allowTagModified) + self.frm.tagModifiedTag.setEnabled(allowTagModified) + def showUnicodeWarning(): """Shorthand to show a standard warning.""" diff --git a/qt/designer/importing.ui b/qt/designer/importing.ui index ce14706bc..07dd178be 100644 --- a/qt/designer/importing.ui +++ b/qt/designer/importing.ui @@ -77,6 +77,20 @@ + + + + + + Tag modified notes: + + + + + + + +