-
Notifications
You must be signed in to change notification settings - Fork 12
/
AnkiPluginConnector.py
134 lines (105 loc) · 4.19 KB
/
AnkiPluginConnector.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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# Using AnkiConnect project as a sub-module import and use AnkiBridge
import sys
# sys.path.insert(0, "org_to_anki/anki-connect/AnkiConnect.py")
import os
# TODO => need to embbeded the AnkiConnectCode
# dirname = os.path.dirname(__file__)
# ankiConnectPath = os.path.join(dirname, "../anki-connect/AnkiConnect.py")
# sys.path.append(ankiConnectPath)
from .. import config
from .AnkiBridge import AnkiBridge
from .AnkiNoteBuilder import AnkiNoteBuilder
# Anki imports
try:
import anki
import aqt
from aqt.utils import showInfo
except:
pass
class AnkiPluginConnector:
def __init__(self, defaultDeck=config.defaultDeck):
self.AnkiBridge = AnkiBridge()
self.defaultDeck = defaultDeck
self.AnkiNoteBuilder = AnkiNoteBuilder(self.defaultDeck)
def uploadNewDeck(self, deck): # AnkiDeck
### Upload deck to Anki in embedded mode ###
self._checkForDefaultDeck()
self._buildNewDecksAsRequired(deck.getDeckNames())
# Build new questions
notes = self.buildIndividualAnkiNotes(deck.getQuestions())
media = self.prepareMedia(deck.getMedia())
# Add notes => TODO => needs to handle exception better
numberOfDuplicateNotes = 0
for note in notes:
try:
self.AnkiBridge.addNote(note)
except Exception as e:
if str(e) == "cannot create note because it is a duplicate":
numberOfDuplicateNotes += 1
else:
raise e
# Add Media => TODO => not tested
for i in media:
self.AnkiBridge.storeMediaFile(i.get("fileName"), i.get("data"))
def prepareMedia(self, ankiMedia): # ([])
formattedMedia = []
if len(ankiMedia) == 0:
return formattedMedia
else:
for i in ankiMedia:
formattedMedia.append({"fileName": i.fileName, "data": base64.b64encode(i.data).decode("utf-8")})
return formattedMedia
def _buildNewDecksAsRequired(self, deckNames): # ([str])
# Check decks exist for notes
newDeckPaths = []
for i in deckNames:
fullDeckPath = self._getFullDeckPath(i)
if fullDeckPath not in self.currentDecks and fullDeckPath not in newDeckPaths:
newDeckPaths.append(fullDeckPath)
# Create decks
for deck in newDeckPaths:
self.AnkiBridge.createDeck(deck)
def _getFullDeckPath(self, deckName): # (str)
return str(self.defaultDeck + "::" + deckName)
def _checkForDefaultDeck(self):
self.currentDecks = self.AnkiBridge.deckNames()
if self.defaultDeck not in self.currentDecks:
self.AnkiBridge.createDeck(self.defaultDeck)
# TODO => refactor
def buildAnkiNotes(self, ankiQuestions): # [AnkiQuestion]
notes = []
for i in ankiQuestions:
notes.append(self.AnkiNoteBuilder.buildNote(i))
finalNotes = {}
finalNotes["notes"] = notes
return finalNotes
def buildIndividualAnkiNotes(self, ankiQuestions):
allNotes = []
for i in ankiQuestions:
allNotes.append(self.AnkiNoteBuilder.buildNote(i))
return allNotes
### These methods are still in beta and are subject to change ###
# Get deck Notes
def getDeckNotes(self, deckName):
# TODO => revisit return type
return self.AnkiBridge.getDeckNotes(deckName)
# Add new notes
def addNote(self, note):
# TODO need to verify this note is logically correct
if isinstance(note, list) == False:
note = [note]
builtNotes = self.buildIndividualAnkiNotes(note)
for note in builtNotes:
self.AnkiBridge.addNote(note)
# Delete notes
def deleteNotes(self, noteIds):
# TODO ensure that noteID is an array
self.AnkiBridge.deleteNotes(noteIds)
# Update Note fields
def updateNoteFields(self, note):
# TODO ensure note is logically correct
self.AnkiBridge.updateNoteFields(note)
def getConfig(self):
return aqt.mw.addonManager.getConfig(__name__)
def writeConfig(self, config):
aqt.mw.addonManager.writeConfig(__name__, config)