mirror of
https://github.com/ankitects/anki.git
synced 2025-09-19 14:32:22 -04:00
Merge branch 'sobjornstad-master'
This commit is contained in:
commit
ec5d4b2203
12 changed files with 82 additions and 16 deletions
|
@ -261,6 +261,7 @@ class AnkiPackageExporter(AnkiExporter):
|
||||||
p = path.replace(".apkg", ".media.db2")
|
p = path.replace(".apkg", ".media.db2")
|
||||||
if os.path.exists(p):
|
if os.path.exists(p):
|
||||||
os.unlink(p)
|
os.unlink(p)
|
||||||
|
os.chdir(self.mediaDir)
|
||||||
shutil.rmtree(path.replace(".apkg", ".media"))
|
shutil.rmtree(path.replace(".apkg", ".media"))
|
||||||
return media
|
return media
|
||||||
|
|
||||||
|
|
|
@ -190,6 +190,11 @@ class Anki2Importer(Importer):
|
||||||
dstScm = self.dst.models.scmhash(dstModel)
|
dstScm = self.dst.models.scmhash(dstModel)
|
||||||
if srcScm == dstScm:
|
if srcScm == dstScm:
|
||||||
# they do; we can reuse this mid
|
# they do; we can reuse this mid
|
||||||
|
model = srcModel.copy()
|
||||||
|
model['id'] = mid
|
||||||
|
model['mod'] = intTime()
|
||||||
|
model['usn'] = self.col.usn()
|
||||||
|
self.dst.models.update(model)
|
||||||
break
|
break
|
||||||
# as they don't match, try next id
|
# as they don't match, try next id
|
||||||
mid += 1
|
mid += 1
|
||||||
|
|
|
@ -156,7 +156,6 @@ class NoteImporter(Importer):
|
||||||
updateLog.append(updateLogTxt % fld0)
|
updateLog.append(updateLogTxt % fld0)
|
||||||
dupeCount += 1
|
dupeCount += 1
|
||||||
found = True
|
found = True
|
||||||
break
|
|
||||||
elif self.importMode == 1:
|
elif self.importMode == 1:
|
||||||
dupeCount += 1
|
dupeCount += 1
|
||||||
elif self.importMode == 2:
|
elif self.importMode == 2:
|
||||||
|
|
|
@ -353,7 +353,11 @@ group by day order by day""" % (self._limit(), lim),
|
||||||
tot, period, unit))
|
tot, period, unit))
|
||||||
if total and tot:
|
if total and tot:
|
||||||
perMin = total / float(tot)
|
perMin = total / float(tot)
|
||||||
perMin = ngettext("%d card/minute", "%d cards/minute", perMin) % round(perMin)
|
perMin = round(perMin, 1)
|
||||||
|
perMin = ngettext("%d card/minute", "%.01f cards/minute", perMin) % perMin
|
||||||
|
# don't round down to zero
|
||||||
|
if float(perMin.split(' ')[0]) < 0.1:
|
||||||
|
perMin = ''.join(["<", _("%.01f cards/minute")]) % 0.1
|
||||||
self._line(
|
self._line(
|
||||||
i, _("Average answer time"),
|
i, _("Average answer time"),
|
||||||
_("%(a)0.1fs (%(b)s)") % dict(a=(tot*60)/total, b=perMin))
|
_("%(a)0.1fs (%(b)s)") % dict(a=(tot*60)/total, b=perMin))
|
||||||
|
|
|
@ -292,9 +292,10 @@ def tmpdir():
|
||||||
shutil.rmtree(_tmpdir)
|
shutil.rmtree(_tmpdir)
|
||||||
import atexit
|
import atexit
|
||||||
atexit.register(cleanup)
|
atexit.register(cleanup)
|
||||||
_tmpdir = unicode(os.path.join(tempfile.gettempdir(), "anki_temp"), sys.getfilesystemencoding())
|
_tmpdir = unicode(os.path.join(tempfile.gettempdir(), "anki_temp"), \
|
||||||
if not os.path.exists(_tmpdir):
|
sys.getfilesystemencoding())
|
||||||
os.mkdir(_tmpdir)
|
if not os.path.exists(_tmpdir):
|
||||||
|
os.mkdir(_tmpdir)
|
||||||
return _tmpdir
|
return _tmpdir
|
||||||
|
|
||||||
def tmpfile(prefix="", suffix=""):
|
def tmpfile(prefix="", suffix=""):
|
||||||
|
|
|
@ -790,8 +790,9 @@ by clicking on one on the left."""))
|
||||||
txt = "-"+txt
|
txt = "-"+txt
|
||||||
if self.mw.app.keyboardModifiers() & Qt.ControlModifier:
|
if self.mw.app.keyboardModifiers() & Qt.ControlModifier:
|
||||||
cur = unicode(self.form.searchEdit.lineEdit().text())
|
cur = unicode(self.form.searchEdit.lineEdit().text())
|
||||||
if cur:
|
if cur and cur != \
|
||||||
txt = cur + " " + txt
|
_("<type here to search; hit enter to show current deck>"):
|
||||||
|
txt = cur + " " + txt
|
||||||
elif self.mw.app.keyboardModifiers() & Qt.ShiftModifier:
|
elif self.mw.app.keyboardModifiers() & Qt.ShiftModifier:
|
||||||
cur = unicode(self.form.searchEdit.lineEdit().text())
|
cur = unicode(self.form.searchEdit.lineEdit().text())
|
||||||
if cur:
|
if cur:
|
||||||
|
|
|
@ -142,15 +142,44 @@ a flash drive.""" % self.base)
|
||||||
self.name = name
|
self.name = name
|
||||||
newFolder = self.profileFolder(create=False)
|
newFolder = self.profileFolder(create=False)
|
||||||
if os.path.exists(newFolder):
|
if os.path.exists(newFolder):
|
||||||
showWarning(_("Folder already exists."))
|
if (oldFolder != newFolder) and (
|
||||||
self.name = oldName
|
oldFolder.lower() == newFolder.lower()):
|
||||||
return
|
# OS is telling us the folder exists because it does not take
|
||||||
|
# case into account; use a temporary folder location
|
||||||
|
midFolder = ''.join([oldFolder, '-temp'])
|
||||||
|
if not os.path.exists(midFolder):
|
||||||
|
os.rename(oldFolder, midFolder)
|
||||||
|
oldFolder = midFolder
|
||||||
|
else:
|
||||||
|
showWarning(_("Please remove the folder %s and try again.")
|
||||||
|
% midFolder)
|
||||||
|
self.name = oldName
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
showWarning(_("Folder already exists."))
|
||||||
|
self.name = oldName
|
||||||
|
return
|
||||||
|
|
||||||
# update name
|
# update name
|
||||||
self.db.execute("update profiles set name = ? where name = ?",
|
self.db.execute("update profiles set name = ? where name = ?",
|
||||||
name.encode("utf8"), oldName.encode("utf-8"))
|
name.encode("utf8"), oldName.encode("utf-8"))
|
||||||
# rename folder
|
# rename folder
|
||||||
os.rename(oldFolder, newFolder)
|
try:
|
||||||
self.db.commit()
|
os.rename(oldFolder, newFolder)
|
||||||
|
except WindowsError as e:
|
||||||
|
self.db.rollback()
|
||||||
|
if "Access is denied" in e:
|
||||||
|
showWarning(_("""\
|
||||||
|
Anki could not rename your profile because it could not rename the profile \
|
||||||
|
folder on disk. Please ensure you have permission to write to Documents/Anki \
|
||||||
|
and no other programs are accessing your profile folders, then try again."""))
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
except:
|
||||||
|
self.db.rollback()
|
||||||
|
raise
|
||||||
|
else:
|
||||||
|
self.db.commit()
|
||||||
|
|
||||||
# Folder handling
|
# Folder handling
|
||||||
######################################################################
|
######################################################################
|
||||||
|
@ -189,7 +218,12 @@ a flash drive.""" % self.base)
|
||||||
elif isMac:
|
elif isMac:
|
||||||
return os.path.expanduser("~/Documents/Anki")
|
return os.path.expanduser("~/Documents/Anki")
|
||||||
else:
|
else:
|
||||||
return os.path.expanduser("~/Anki")
|
# use Documents/Anki on new installs, ~/Anki on existing ones
|
||||||
|
p = os.path.expanduser("~/Anki")
|
||||||
|
if os.path.exists(p):
|
||||||
|
return p
|
||||||
|
else:
|
||||||
|
return os.path.expanduser("~/Documents/Anki")
|
||||||
|
|
||||||
def _loadMeta(self):
|
def _loadMeta(self):
|
||||||
path = os.path.join(self.base, "prefs.db")
|
path = os.path.join(self.base, "prefs.db")
|
||||||
|
|
|
@ -127,7 +127,7 @@ class Reviewer(object):
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
_revHtml = """
|
_revHtml = """
|
||||||
<img src="qrc:/icons/rating.png" class=marked>
|
<img src="qrc:/icons/rating.png" id=star class=marked>
|
||||||
<div id=qa></div>
|
<div id=qa></div>
|
||||||
<script>
|
<script>
|
||||||
var ankiPlatform = "desktop";
|
var ankiPlatform = "desktop";
|
||||||
|
|
|
@ -217,10 +217,10 @@ enter your details below.""") %
|
||||||
vbox.addWidget(bb)
|
vbox.addWidget(bb)
|
||||||
d.setLayout(vbox)
|
d.setLayout(vbox)
|
||||||
d.show()
|
d.show()
|
||||||
d.exec_()
|
accepted = d.exec_()
|
||||||
u = user.text()
|
u = user.text()
|
||||||
p = passwd.text()
|
p = passwd.text()
|
||||||
if not u or not p:
|
if not accepted or not u or not p:
|
||||||
return
|
return
|
||||||
return (u, p)
|
return (u, p)
|
||||||
|
|
||||||
|
|
BIN
tests/support/diffmodeltemplates-1.apkg
Normal file
BIN
tests/support/diffmodeltemplates-1.apkg
Normal file
Binary file not shown.
BIN
tests/support/diffmodeltemplates-2.apkg
Normal file
BIN
tests/support/diffmodeltemplates-2.apkg
Normal file
Binary file not shown.
|
@ -204,6 +204,27 @@ def test_anki2_diffmodels():
|
||||||
assert after == before + 1
|
assert after == before + 1
|
||||||
assert dst.cardCount() == 3
|
assert dst.cardCount() == 3
|
||||||
|
|
||||||
|
def test_anki2_diffmodel_templates():
|
||||||
|
# different from the above as this one tests only the template text being
|
||||||
|
# changed, not the number of cards/fields
|
||||||
|
dst = getEmptyCol()
|
||||||
|
# import the first version of the model
|
||||||
|
tmp = getUpgradeDeckPath("diffmodeltemplates-1.apkg")
|
||||||
|
imp = AnkiPackageImporter(dst, tmp)
|
||||||
|
imp.dupeOnSchemaChange = True
|
||||||
|
imp.run()
|
||||||
|
# then the version with updated template
|
||||||
|
tmp = getUpgradeDeckPath("diffmodeltemplates-2.apkg")
|
||||||
|
imp = AnkiPackageImporter(dst, tmp)
|
||||||
|
imp.dupeOnSchemaChange = True
|
||||||
|
imp.run()
|
||||||
|
# collection should contain the note we imported
|
||||||
|
assert(dst.noteCount() == 1)
|
||||||
|
# the front template should contain the text added in the 2nd package
|
||||||
|
tcid = dst.findCards("")[0] # only 1 note in collection
|
||||||
|
tnote = dst.getCard(tcid).note()
|
||||||
|
assert("Changed Front Template" in dst.findTemplates(tnote)[0]['qfmt'])
|
||||||
|
|
||||||
def test_anki2_updates():
|
def test_anki2_updates():
|
||||||
# create a new empty deck
|
# create a new empty deck
|
||||||
dst = getEmptyCol()
|
dst = getEmptyCol()
|
||||||
|
|
Loading…
Reference in a new issue