catch invalid temp folder and other tweaks

- tweak sync code so that a failure in loading the collection
  won't leave the app with an unopen collection
- don't show corrupt collection message when the error is not
  a db error
- catch the temp folder issue when loading the collection. i suspect
  this was the issue that was causing some people to end up with
  an open anki instance with no collection loaded
This commit is contained in:
Damien Elmes 2013-10-22 15:30:46 +09:00
parent 553a908839
commit 82a54c780f
5 changed files with 35 additions and 8 deletions

View File

@ -2,12 +2,16 @@
# Copyright: Damien Elmes <anki@ichi2.net> # Copyright: Damien Elmes <anki@ichi2.net>
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import os, time import os
import time
try: try:
from pysqlite2 import dbapi2 as sqlite from pysqlite2 import dbapi2 as sqlite
except ImportError: except ImportError:
from sqlite3 import dbapi2 as sqlite from sqlite3 import dbapi2 as sqlite
Error = sqlite.Error
class DB(object): class DB(object):
def __init__(self, path, text=None, timeout=0): def __init__(self, path, text=None, timeout=0):
encpath = path encpath = path

View File

@ -45,7 +45,10 @@ class MediaManager(object):
except OSError: except OSError:
# cwd doesn't exist # cwd doesn't exist
self._oldcwd = None self._oldcwd = None
try:
os.chdir(self._dir) os.chdir(self._dir)
except OSError:
raise Exception("invalidTempFolder")
# change database # change database
self.connect() self.connect()

View File

@ -1,10 +1,11 @@
# Copyright: Damien Elmes <anki@ichi2.net> # Copyright: Damien Elmes <anki@ichi2.net>
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
from aqt.qt import *
import sys import sys
import cgi import cgi
from anki.lang import _
from aqt.qt import *
from aqt.utils import showText, showWarning from aqt.utils import showText, showWarning
class ErrorHandler(QObject): class ErrorHandler(QObject):
@ -43,6 +44,12 @@ class ErrorHandler(QObject):
self.timer.setSingleShot(True) self.timer.setSingleShot(True)
self.timer.start() self.timer.start()
def tempFolderMsg(self):
return _("""\
The permissions on your system's temporary folder are incorrect, and Anki is \
not able to correct them automatically. Please search for 'temp folder' in the \
Anki manual for more information.""")
def onTimeout(self): def onTimeout(self):
error = cgi.escape(self.pool) error = cgi.escape(self.pool)
self.pool = "" self.pool = ""
@ -56,6 +63,8 @@ class ErrorHandler(QObject):
if "no default output" in error: if "no default output" in error:
return showWarning(_("Please connect a microphone, and ensure " return showWarning(_("Please connect a microphone, and ensure "
"other programs are not using the audio device.")) "other programs are not using the audio device."))
if "invalidTempFolder" in error:
return showWarning(self.tempFolderMsg())
stdText = _("""\ stdText = _("""\
An error occurred. It may have been caused by a harmless bug, <br> An error occurred. It may have been caused by a harmless bug, <br>
or your deck may have a problem. or your deck may have a problem.

View File

@ -24,7 +24,7 @@ import aqt.stats
from aqt.utils import restoreGeom, showInfo, showWarning,\ from aqt.utils import restoreGeom, showInfo, showWarning,\
restoreState, getOnlyText, askUser, applyStyles, showText, tooltip, \ restoreState, getOnlyText, askUser, applyStyles, showText, tooltip, \
openHelp, openLink, checkInvalidFilename openHelp, openLink, checkInvalidFilename
import anki.db
class AnkiQt(QMainWindow): class AnkiQt(QMainWindow):
def __init__(self, app, profileManager, args): def __init__(self, app, profileManager, args):
@ -270,13 +270,22 @@ To import into a password protected profile, please open the profile before atte
self.hideSchemaMsg = True self.hideSchemaMsg = True
try: try:
self.col = Collection(self.pm.collectionPath()) self.col = Collection(self.pm.collectionPath())
except: except anki.db.Error:
# move back to profile manager # move back to profile manager
showWarning("""\ showWarning("""\
Your collection is corrupt. Please see the manual for \ Your collection is corrupt. Please see the manual for \
how to restore from a backup.""") how to restore from a backup.""")
self.unloadProfile() self.unloadProfile()
raise raise
except Exception, e:
# the custom exception handler won't catch this if we immediately
# unload, so we have to manually handle it
if "invalidTempFolder" in repr(str(e)):
showWarning(self.errorHandler.tempFolderMsg())
self.unloadProfile()
return
self.unloadProfile()
raise
self.hideSchemaMsg = False self.hideSchemaMsg = False
self.progress.setupDB(self.col.db) self.progress.setupDB(self.col.db)
self.maybeEnableUndo() self.maybeEnableUndo()

View File

@ -275,6 +275,10 @@ class SyncThread(QThread):
self.media = media self.media = media
def run(self): def run(self):
# init this first so an early crash doesn't cause an error
# in the main thread
self.syncMsg = ""
self.uname = ""
try: try:
self.col = Collection(self.path) self.col = Collection(self.path)
except: except:
@ -282,8 +286,6 @@ class SyncThread(QThread):
return return
self.server = RemoteServer(self.hkey) self.server = RemoteServer(self.hkey)
self.client = Syncer(self.col, self.server) self.client = Syncer(self.col, self.server)
self.syncMsg = ""
self.uname = ""
self.sentTotal = 0 self.sentTotal = 0
self.recvTotal = 0 self.recvTotal = 0
# throttle updates; qt doesn't handle lots of posted events well # throttle updates; qt doesn't handle lots of posted events well