Revert "don't rely on cwd in media.py"

This reverts commit 975ca90225.

reverting for now as it breaks showing of images during review
This commit is contained in:
Damien Elmes 2017-04-11 12:50:33 +10:00
parent 783767be0d
commit aa89d06304
2 changed files with 46 additions and 38 deletions

View file

@ -35,6 +35,15 @@ class MediaManager:
self._dir = re.sub("(?i)\.(anki2)$", ".media", self.col.path) self._dir = re.sub("(?i)\.(anki2)$", ".media", self.col.path)
if not os.path.exists(self._dir): if not os.path.exists(self._dir):
os.makedirs(self._dir) os.makedirs(self._dir)
try:
self._oldcwd = os.getcwd()
except OSError:
# cwd doesn't exist
self._oldcwd = None
try:
os.chdir(self._dir)
except OSError:
raise Exception("invalidTempFolder")
# change database # change database
self.connect() self.connect()
@ -43,6 +52,7 @@ class MediaManager:
return return
path = self.dir()+".db2" path = self.dir()+".db2"
create = not os.path.exists(path) create = not os.path.exists(path)
os.chdir(self._dir)
self.db = DB(path) self.db = DB(path)
if create: if create:
self._initDB() self._initDB()
@ -84,16 +94,23 @@ create table meta (dirMod int, lastUsn int); insert into meta values (0, 0);
# anew # anew
self.col.log("failed to import old media db:"+traceback.format_exc()) self.col.log("failed to import old media db:"+traceback.format_exc())
self.db.execute("detach old") self.db.execute("detach old")
npath = os.path.join(self.dir(), "collection.media.db.old") npath = "../collection.media.db.old"
if os.path.exists(npath): if os.path.exists(npath):
os.unlink(npath) os.unlink(npath)
os.rename(os.path.join(self.dir(), "collection.media.db"), npath) os.rename("../collection.media.db", npath)
def close(self): def close(self):
if self.col.server: if self.col.server:
return return
self.db.close() self.db.close()
self.db = None self.db = None
# change cwd back to old location
if self._oldcwd:
try:
os.chdir(self._oldcwd)
except:
# may have been deleted
pass
def dir(self): def dir(self):
return self._dir return self._dir
@ -243,26 +260,24 @@ create table meta (dirMod int, lastUsn int); insert into meta values (0, 0);
files = local files = local
renamedFiles = False renamedFiles = False
for file in files: for file in files:
path = os.path.join(self.dir(), file)
if not local: if not local:
if not os.path.isfile(path): if not os.path.isfile(file):
# ignore directories # ignore directories
continue continue
if file.startswith("_"): if file.startswith("_"):
# leading _ says to ignore file # leading _ says to ignore file
continue continue
nfcFile = unicodedata.normalize("NFC", file) nfcFile = unicodedata.normalize("NFC", file)
nfcPath = os.path.join(self.dir(), nfcFile)
# we enforce NFC fs encoding on non-macs; on macs we'll have gotten # we enforce NFC fs encoding on non-macs; on macs we'll have gotten
# NFD so we use the above variable for comparing references # NFD so we use the above variable for comparing references
if not isMac and not local: if not isMac and not local:
if file != nfcFile: if file != nfcFile:
# delete if we already have the NFC form, otherwise rename # delete if we already have the NFC form, otherwise rename
if os.path.exists(nfcPath): if os.path.exists(nfcFile):
os.unlink(path) os.unlink(file)
renamedFiles = True renamedFiles = True
else: else:
os.rename(path, nfcPath) os.rename(file, nfcFile)
renamedFiles = True renamedFiles = True
file = nfcFile file = nfcFile
# compare # compare
@ -332,9 +347,8 @@ create table meta (dirMod int, lastUsn int); insert into meta values (0, 0);
(added, removed) = self._changes() (added, removed) = self._changes()
media = [] media = []
for f in added: for f in added:
path = os.path.join(self.dir(), f) mt = self._mtime(f)
mt = self._mtime(path) media.append((f, self._checksum(f), mt, 1))
media.append((f, self._checksum(path), mt, 1))
for f in removed: for f in removed:
media.append((f, None, 0, 1)) media.append((f, None, 0, 1))
# update media db # update media db
@ -352,9 +366,8 @@ create table meta (dirMod int, lastUsn int); insert into meta values (0, 0);
removed = [] removed = []
# loop through on-disk files # loop through on-disk files
for f in os.listdir(self.dir()): for f in os.listdir(self.dir()):
path = os.path.join(self.dir(), f)
# ignore folders and thumbs.db # ignore folders and thumbs.db
if os.path.isdir(path): if os.path.isdir(f):
continue continue
if f.lower() == "thumbs.db": if f.lower() == "thumbs.db":
continue continue
@ -362,9 +375,9 @@ create table meta (dirMod int, lastUsn int); insert into meta values (0, 0);
if self.hasIllegal(f): if self.hasIllegal(f):
continue continue
# empty files are invalid; clean them up and continue # empty files are invalid; clean them up and continue
sz = os.path.getsize(path) sz = os.path.getsize(f)
if not sz: if not sz:
os.unlink(path) os.unlink(f)
continue continue
if sz > 100*1024*1024: if sz > 100*1024*1024:
self.col.log("ignoring file over 100MB", f) self.col.log("ignoring file over 100MB", f)
@ -372,21 +385,20 @@ create table meta (dirMod int, lastUsn int); insert into meta values (0, 0);
# check encoding # check encoding
if not isMac: if not isMac:
normf = unicodedata.normalize("NFC", f) normf = unicodedata.normalize("NFC", f)
normpath = os.path.join(self.dir(), normf)
if f != normf: if f != normf:
# wrong filename encoding which will cause sync errors # wrong filename encoding which will cause sync errors
if os.path.exists(normpath): if os.path.exists(normf):
os.unlink(path) os.unlink(f)
else: else:
os.rename(path, normpath) os.rename(f, normf)
# newly added? # newly added?
if f not in self.cache: if f not in self.cache:
added.append(f) added.append(f)
else: else:
# modified since last time? # modified since last time?
if self._mtime(path) != self.cache[f][1]: if self._mtime(f) != self.cache[f][1]:
# and has different checksum? # and has different checksum?
if self._checksum(path) != self.cache[f][0]: if self._checksum(f) != self.cache[f][0]:
added.append(f) added.append(f)
# mark as used # mark as used
self.cache[f][2] = True self.cache[f][2] = True
@ -417,9 +429,8 @@ create table meta (dirMod int, lastUsn int); insert into meta values (0, 0);
"update media set dirty=0 where fname=?", fname) "update media set dirty=0 where fname=?", fname)
def syncDelete(self, fname): def syncDelete(self, fname):
path = os.path.join(self.dir(), fname) if os.path.exists(fname):
if os.path.exists(path): os.unlink(fname)
os.unlink(path)
self.db.execute("delete from media where fname=?", fname) self.db.execute("delete from media where fname=?", fname)
def mediaCount(self): def mediaCount(self):
@ -456,15 +467,14 @@ create table meta (dirMod int, lastUsn int); insert into meta values (0, 0);
"select fname, csum from media where dirty=1" "select fname, csum from media where dirty=1"
" limit %d"%SYNC_ZIP_COUNT)): " limit %d"%SYNC_ZIP_COUNT)):
path = os.path.join(self.dir(), fname)
fnames.append(fname) fnames.append(fname)
normname = unicodedata.normalize("NFC", fname) normname = unicodedata.normalize("NFC", fname)
if csum: if csum:
self.col.log("+media zip", fname) self.col.log("+media zip", fname)
z.write(path, str(c)) z.write(fname, str(c))
meta.append((normname, str(c))) meta.append((normname, str(c)))
sz += os.path.getsize(path) sz += os.path.getsize(fname)
else: else:
self.col.log("-media zip", fname) self.col.log("-media zip", fname)
meta.append((normname, "")) meta.append((normname, ""))
@ -499,10 +509,9 @@ create table meta (dirMod int, lastUsn int); insert into meta values (0, 0);
else: else:
name = unicodedata.normalize("NFC", name) name = unicodedata.normalize("NFC", name)
# save file # save file
path = os.path.join(self.dir(), name) open(name, "wb").write(data)
open(path, "wb").write(data)
# update db # update db
media.append((name, csum, self._mtime(path), 0)) media.append((name, csum, self._mtime(name), 0))
cnt += 1 cnt += 1
if media: if media:
self.db.executemany( self.db.executemany(

View file

@ -77,30 +77,29 @@ def test_changes():
assert not list(added()) assert not list(added())
assert not list(removed()) assert not list(removed())
# add a file # add a file
tmp_dir = tempfile.mkdtemp(prefix="anki") dir = tempfile.mkdtemp(prefix="anki")
tmp_path = os.path.join(tmp_dir, "foo.jpg") path = os.path.join(dir, "foo.jpg")
open(tmp_path, "w").write("hello") open(path, "w").write("hello")
time.sleep(1) time.sleep(1)
fname = d.media.addFile(tmp_path) path = d.media.addFile(path)
internal_path = os.path.join(d.media.dir(), fname)
# should have been logged # should have been logged
d.media.findChanges() d.media.findChanges()
assert list(added()) assert list(added())
assert not list(removed()) assert not list(removed())
# if we modify it, the cache won't notice # if we modify it, the cache won't notice
time.sleep(1) time.sleep(1)
open(internal_path, "w").write("world") open(path, "w").write("world")
assert len(list(added())) == 1 assert len(list(added())) == 1
assert not list(removed()) assert not list(removed())
# but if we add another file, it will # but if we add another file, it will
time.sleep(1) time.sleep(1)
open(internal_path+"2", "w").write("yo") open(path+"2", "w").write("yo")
d.media.findChanges() d.media.findChanges()
assert len(list(added())) == 2 assert len(list(added())) == 2
assert not list(removed()) assert not list(removed())
# deletions should get noticed too # deletions should get noticed too
time.sleep(1) time.sleep(1)
os.unlink(internal_path+"2") os.unlink(path+"2")
d.media.findChanges() d.media.findChanges()
assert len(list(added())) == 1 assert len(list(added())) == 1
assert len(list(removed())) == 1 assert len(list(removed())) == 1