-
Notifications
You must be signed in to change notification settings - Fork 0
/
aokana.py
77 lines (62 loc) · 3.4 KB
/
aokana.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
from anki.utils import os, json
from aqt.utils import showInfo
from aqt import qt
from .sync.syncer import Syncer
from .sync.confirmer import ChangeConfirmer
from .widgets.syncdialog import SyncDialog
from .arguments.syncarguments import SyncArgumentsFetcher
from .exceptions import SyncArgumentsException
class Aokana():
def __init__(self, api):
self.api = api
self.config = api.getConfig()
self.syncDialog = self.getSyncDialog()
self.syncArgumentsFetcher = SyncArgumentsFetcher(self.config, self.api.getNotes, self.syncDialog)
self.syncer = Syncer(self.onSyncUpdate, self.api.saveMedia)
self.changeConfirmer = ChangeConfirmer(self.api.saveCollection)
self.progress = self.api.getProgress()
def load(self):
self.api.addToolsMenuSeparator()
self.addAction('Sync 蒼彼方', self.openSyncDialog, "Ctrl+k")
def addAction(self, title, callback, shortcut):
action = qt.QAction(title, self.api.window)
action.triggered.connect(lambda: callback())
action.setShortcut(shortcut)
self.api.addToolsMenuAction(action)
def getSyncDialog(self):
dialog = SyncDialog(self.api.window)
dialog.syncClicked.connect(self.onSyncClicked)
dialog.confirmClicked.connect(self.onSyncConfirmed)
return dialog
def onSyncUpdate(self, message, expression, index, max):
print(message)
self.progress.update('Processed %s... (%d/%d)' % (expression, index, max), index, max=max)
def onSyncConfirmed(self, changeOperations, sourceDialog):
changes, failures = self.changeConfirmer.confirm(changeOperations)
showInfo('Processed %d note(s) with %d update(s) and %d failure(s).' % (len(changeOperations), changes, failures), sourceDialog)
def shouldStopBeforeConfirmation(self, currentNote, changeOperations):
count = len(changeOperations)
return currentNote != None and (count == 0 or (count == 1 and not changeOperations[0].hasAnyChanges()))
def syncEntries(self, currentNote, extendedQuery, skipTagged, resolveManually):
try:
args = self.syncArgumentsFetcher.fetch(extendedQuery, skipTagged, resolveManually)
self.progress.start(parent=self.syncDialog)
self.progress._showWin() # workaround for progress dialog showing after manual conflict resolver dialog
changeOperations = self.syncer.sync(args, lambda: self.progress.want_cancel())
self.progress.finish()
if self.shouldStopBeforeConfirmation(currentNote, changeOperations):
expression = currentNote[self.config['noteMappings'][self.api.getNoteType(currentNote)]['expressionField']]
showInfo('No changes available for %s' % expression, self.api.window)
else:
self.syncDialog.showConfirmDialog(changeOperations)
except SyncArgumentsException as e:
showInfo(e.getMessage(), self.syncDialog)
def onSyncClicked(self):
dialog = self.syncDialog
self.syncEntries(None, dialog.extendedQuery(), dialog.skipTagged(), dialog.resolveManually())
def openSyncDialog(self):
note = self.api.getCurrentReviewerNote()
if note != None and any(self.api.isNoteOfType(note, noteType) for noteType in self.config['noteMappings']):
self.syncEntries(note, 'nid:%d' % note.id, False, True)
return
self.syncDialog.exec_()