diff --git a/anki/exporting.py b/anki/exporting.py index dd1444ebf..93a7018b8 100644 --- a/anki/exporting.py +++ b/anki/exporting.py @@ -261,6 +261,7 @@ class AnkiPackageExporter(AnkiExporter): p = path.replace(".apkg", ".media.db2") if os.path.exists(p): os.unlink(p) + os.chdir(self.mediaDir) shutil.rmtree(path.replace(".apkg", ".media")) return media diff --git a/anki/importing/anki2.py b/anki/importing/anki2.py index ffb97c815..01e3bb751 100644 --- a/anki/importing/anki2.py +++ b/anki/importing/anki2.py @@ -190,6 +190,11 @@ class Anki2Importer(Importer): dstScm = self.dst.models.scmhash(dstModel) if srcScm == dstScm: # 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 # as they don't match, try next id mid += 1 diff --git a/anki/importing/noteimp.py b/anki/importing/noteimp.py index e9e435d67..d53f8a9ac 100644 --- a/anki/importing/noteimp.py +++ b/anki/importing/noteimp.py @@ -156,7 +156,6 @@ class NoteImporter(Importer): updateLog.append(updateLogTxt % fld0) dupeCount += 1 found = True - break elif self.importMode == 1: dupeCount += 1 elif self.importMode == 2: diff --git a/anki/stats.py b/anki/stats.py index 681157785..391fa67a2 100644 --- a/anki/stats.py +++ b/anki/stats.py @@ -353,7 +353,11 @@ group by day order by day""" % (self._limit(), lim), tot, period, unit)) if total and 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( i, _("Average answer time"), _("%(a)0.1fs (%(b)s)") % dict(a=(tot*60)/total, b=perMin)) diff --git a/anki/utils.py b/anki/utils.py index 6fab82fa1..5452d051b 100644 --- a/anki/utils.py +++ b/anki/utils.py @@ -292,9 +292,10 @@ def tmpdir(): shutil.rmtree(_tmpdir) import atexit atexit.register(cleanup) - _tmpdir = unicode(os.path.join(tempfile.gettempdir(), "anki_temp"), sys.getfilesystemencoding()) - if not os.path.exists(_tmpdir): - os.mkdir(_tmpdir) + _tmpdir = unicode(os.path.join(tempfile.gettempdir(), "anki_temp"), \ + sys.getfilesystemencoding()) + if not os.path.exists(_tmpdir): + os.mkdir(_tmpdir) return _tmpdir def tmpfile(prefix="", suffix=""): diff --git a/aqt/browser.py b/aqt/browser.py index 941dc2176..8c7d526e0 100644 --- a/aqt/browser.py +++ b/aqt/browser.py @@ -790,8 +790,9 @@ by clicking on one on the left.""")) txt = "-"+txt if self.mw.app.keyboardModifiers() & Qt.ControlModifier: cur = unicode(self.form.searchEdit.lineEdit().text()) - if cur: - txt = cur + " " + txt + if cur and cur != \ + _(""): + txt = cur + " " + txt elif self.mw.app.keyboardModifiers() & Qt.ShiftModifier: cur = unicode(self.form.searchEdit.lineEdit().text()) if cur: diff --git a/aqt/profiles.py b/aqt/profiles.py index a7472947c..cc99fd26e 100644 --- a/aqt/profiles.py +++ b/aqt/profiles.py @@ -142,15 +142,44 @@ a flash drive.""" % self.base) self.name = name newFolder = self.profileFolder(create=False) if os.path.exists(newFolder): - showWarning(_("Folder already exists.")) - self.name = oldName - return + if (oldFolder != newFolder) and ( + oldFolder.lower() == newFolder.lower()): + # 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 self.db.execute("update profiles set name = ? where name = ?", name.encode("utf8"), oldName.encode("utf-8")) # rename folder - os.rename(oldFolder, newFolder) - self.db.commit() + try: + 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 ###################################################################### @@ -189,7 +218,12 @@ a flash drive.""" % self.base) elif isMac: return os.path.expanduser("~/Documents/Anki") 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): path = os.path.join(self.base, "prefs.db") diff --git a/aqt/reviewer.py b/aqt/reviewer.py index 40a5dcdc9..9bdfc749b 100644 --- a/aqt/reviewer.py +++ b/aqt/reviewer.py @@ -127,7 +127,7 @@ class Reviewer(object): ########################################################################## _revHtml = """ - +