Merge pull request #443 from Arthur-Milchior/exportFromBrowserInAnki

Export from browser in anki
This commit is contained in:
Damien Elmes 2020-02-12 08:05:26 +10:00 committed by GitHub
commit 60becbf480
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 59 additions and 11 deletions

View file

@ -470,6 +470,9 @@ class DeckManager:
dids.append(id) dids.append(id)
return self.col.db.list("select id from cards where did in " + ids2str(dids)) return self.col.db.list("select id from cards where did in " + ids2str(dids))
def for_card_ids(self, cids: List[int]) -> List[int]:
return self.col.db.list(f"select did from cards where id in {ids2str(cids)}")
def _recoverOrphans(self) -> None: def _recoverOrphans(self) -> None:
dids = list(self.decks.keys()) dids = list(self.decks.keys())
mod = self.col.db.mod mod = self.col.db.mod

View file

@ -8,7 +8,7 @@ import shutil
import unicodedata import unicodedata
import zipfile import zipfile
from io import BufferedWriter from io import BufferedWriter
from typing import Any, Dict, List, Tuple, Union from typing import Any, Dict, List, Optional, Tuple, Union
from zipfile import ZipFile from zipfile import ZipFile
from anki import hooks from anki import hooks
@ -21,9 +21,17 @@ from anki.utils import ids2str, namedtmp, splitFields, stripHTML
class Exporter: class Exporter:
includeHTML: Union[bool, None] = None includeHTML: Union[bool, None] = None
def __init__(self, col: _Collection, did: None = None) -> None: did: Optional[int]
def __init__(
self,
col: _Collection,
did: Optional[int] = None,
cids: Optional[List[int]] = None,
) -> None:
self.col = col self.col = col
self.did = did self.did = did
self.cids = cids
def doExport(self, path) -> None: def doExport(self, path) -> None:
raise Exception("not implemented") raise Exception("not implemented")
@ -65,7 +73,9 @@ class Exporter:
return s return s
def cardIds(self) -> Any: def cardIds(self) -> Any:
if not self.did: if self.cids is not None:
cids = self.cids
elif not self.did:
cids = self.col.db.list("select id from cards") cids = self.col.db.list("select id from cards")
else: else:
cids = self.col.decks.cids(self.did, children=True) cids = self.col.decks.cids(self.did, children=True)
@ -160,10 +170,12 @@ class AnkiExporter(Exporter):
Exporter.__init__(self, col) Exporter.__init__(self, col)
def deckIds(self) -> List[int]: def deckIds(self) -> List[int]:
if not self.did: if self.cids:
return [] return self.col.decks.for_card_ids(self.cids)
else: elif self.did:
return [self.did] + [x[1] for x in self.src.decks.children(self.did)] return [self.did] + [x[1] for x in self.src.decks.children(self.did)]
else:
return []
def exportInto(self, path: str) -> None: def exportInto(self, path: str) -> None:
# sched info+v2 scheduler not compatible w/ older clients # sched info+v2 scheduler not compatible w/ older clients

View file

@ -23,6 +23,7 @@ from anki.notes import Note
from anki.utils import fmtTimeSpan, htmlToTextLine, ids2str, intTime, isMac, isWin from anki.utils import fmtTimeSpan, htmlToTextLine, ids2str, intTime, isMac, isWin
from aqt import AnkiQt, gui_hooks from aqt import AnkiQt, gui_hooks
from aqt.editor import Editor from aqt.editor import Editor
from aqt.exporting import ExportDialog
from aqt.qt import * from aqt.qt import *
from aqt.sound import av_player, play_clicked_audio from aqt.sound import av_player, play_clicked_audio
from aqt.theme import theme_manager from aqt.theme import theme_manager
@ -614,6 +615,7 @@ class Browser(QMainWindow):
f.actionOrange_Flag.triggered.connect(lambda: self.onSetFlag(2)) f.actionOrange_Flag.triggered.connect(lambda: self.onSetFlag(2))
f.actionGreen_Flag.triggered.connect(lambda: self.onSetFlag(3)) f.actionGreen_Flag.triggered.connect(lambda: self.onSetFlag(3))
f.actionBlue_Flag.triggered.connect(lambda: self.onSetFlag(4)) f.actionBlue_Flag.triggered.connect(lambda: self.onSetFlag(4))
f.actionExport.triggered.connect(lambda: self._exporting())
# jumps # jumps
f.actionPreviousCard.triggered.connect(self.onPreviousCard) f.actionPreviousCard.triggered.connect(self.onPreviousCard)
f.actionNextCard.triggered.connect(self.onNextCard) f.actionNextCard.triggered.connect(self.onNextCard)
@ -1898,6 +1900,14 @@ update cards set usn=?, mod=?, did=? where id in """
self.model.reset() self.model.reset()
self.mw.requireReset() self.mw.requireReset()
# Exporting
######################################################################
def _exporting(self):
cids = self.selectedNotesAsCards()
if cids:
ExportDialog(self.mw, cids=cids)
# Flags & Marking # Flags & Marking
###################################################################### ######################################################################

View file

@ -4,6 +4,7 @@
import os import os
import re import re
import time import time
from typing import List, Optional
import aqt import aqt
from anki import hooks from anki import hooks
@ -14,21 +15,22 @@ from aqt.utils import checkInvalidFilename, getSaveFile, showInfo, showWarning,
class ExportDialog(QDialog): class ExportDialog(QDialog):
def __init__(self, mw, did=None): def __init__(self, mw, did: Optional[int] = None, cids: Optional[List[int]] = None):
QDialog.__init__(self, mw, Qt.Window) QDialog.__init__(self, mw, Qt.Window)
self.mw = mw self.mw = mw
self.col = mw.col self.col = mw.col
self.frm = aqt.forms.exporting.Ui_ExportDialog() self.frm = aqt.forms.exporting.Ui_ExportDialog()
self.frm.setupUi(self) self.frm.setupUi(self)
self.exporter = None self.exporter = None
self.cids = cids
self.setup(did) self.setup(did)
self.exec_() self.exec_()
def setup(self, did): def setup(self, did: Optional[int]):
self.exporters = exporters() self.exporters = exporters()
# if a deck specified, start with .apkg type selected # if a deck specified, start with .apkg type selected
idx = 0 idx = 0
if did: if did or self.cids:
for c, (k, e) in enumerate(self.exporters): for c, (k, e) in enumerate(self.exporters):
if e.ext == ".apkg": if e.ext == ".apkg":
idx = c idx = c
@ -38,7 +40,10 @@ class ExportDialog(QDialog):
self.frm.format.activated.connect(self.exporterChanged) self.frm.format.activated.connect(self.exporterChanged)
self.exporterChanged(idx) self.exporterChanged(idx)
# deck list # deck list
if self.cids is None:
self.decks = [_("All Decks")] + sorted(self.col.decks.allNames()) self.decks = [_("All Decks")] + sorted(self.col.decks.allNames())
else:
self.decks = [_("Browser Selection")]
self.frm.deck.addItems(self.decks) self.frm.deck.addItems(self.decks)
# save button # save button
b = QPushButton(_("Export...")) b = QPushButton(_("Export..."))
@ -77,9 +82,18 @@ class ExportDialog(QDialog):
self.exporter.includeMedia = self.frm.includeMedia.isChecked() self.exporter.includeMedia = self.frm.includeMedia.isChecked()
self.exporter.includeTags = self.frm.includeTags.isChecked() self.exporter.includeTags = self.frm.includeTags.isChecked()
self.exporter.includeHTML = self.frm.includeHTML.isChecked() self.exporter.includeHTML = self.frm.includeHTML.isChecked()
if not self.frm.deck.currentIndex(): idx = self.frm.deck.currentIndex()
if self.cids is not None:
# Browser Selection
self.exporter.cids = self.cids
self.exporter.did = None self.exporter.did = None
elif idx == 0:
# All decks
self.exporter.did = None
self.exporter.cids = None
else: else:
# Deck idx-1 in the list of decks
self.exporter.cids = None
name = self.decks[self.frm.deck.currentIndex()] name = self.decks[self.frm.deck.currentIndex()]
self.exporter.did = self.col.decks.id(name) self.exporter.did = self.col.decks.id(name)
if self.isVerbatim: if self.isVerbatim:

View file

@ -295,6 +295,7 @@
<addaction name="menuFlag"/> <addaction name="menuFlag"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="action_Info"/> <addaction name="action_Info"/>
<addaction name="actionExport"/>
</widget> </widget>
<widget class="QMenu" name="menu_Notes"> <widget class="QMenu" name="menu_Notes">
<property name="title"> <property name="title">
@ -599,6 +600,14 @@
<string notr="true">Ctrl+K</string> <string notr="true">Ctrl+K</string>
</property> </property>
</action> </action>
<action name="actionExport">
<property name="text">
<string>&amp;Export Notes</string>
</property>
<property name="shortcut">
<string>Ctrl+Shift+E</string>
</property>
</action>
</widget> </widget>
<resources> <resources>
<include location="icons.qrc"/> <include location="icons.qrc"/>