def fullSyncFromServer(self, fields, path): try: runHook("fullSyncStarted", 0) fields = urllib.urlencode(fields) src = urllib.urlopen(SYNC_URL + "fulldown", fields) (fd, tmpname) = tempfile.mkstemp(dir=os.path.dirname(path), prefix="fullsync") tmp = open(tmpname, "wb") decomp = zlib.decompressobj() cnt = 0 while 1: data = src.read(CHUNK_SIZE) if not data: tmp.write(decomp.flush()) break tmp.write(decomp.decompress(data)) cnt += CHUNK_SIZE runHook("fullSyncProgress", "fromServer", cnt) src.close() tmp.close() os.close(fd) # if we were successful, overwrite old deck os.unlink(path) os.rename(tmpname, path) # reset the deck name c = sqlite.connect(path) c.execute("update decks set syncName = ?", [checksum(path.encode("utf-8"))]) c.commit() c.close() finally: runHook("fullSyncFinished")
def copyToMedia(deck, path): """Copy PATH to MEDIADIR, and return new filename. If a file with the same md5sum exists in the DB, return that. If a file with the same name exists, return a unique name. This does not modify the media table.""" # see if have duplicate contents newpath = deck.s.scalar( "select filename from media where originalPath = :cs", cs=checksum(open(path, "rb").read())) # check if this filename already exists if not newpath: base = os.path.basename(path) mdir = deck.mediaDir(create=True) newpath = uniquePath(mdir, base) shutil.copy2(path, newpath) return os.path.basename(newpath)
def updateMediaCount(deck, file, count=1): mdir = deck.mediaDir() if deck.s.scalar( "select 1 from media where filename = :file", file=file): deck.s.statement( "update media set size = size + :c, created = :t where filename = :file", file=file, c=count, t=time.time()) elif count > 0: try: sum = str( checksum(open(os.path.join(mdir, file), "rb").read())) except: sum = "" deck.s.statement(""" insert into media (id, filename, size, created, originalPath, description) values (:id, :file, :c, :mod, :sum, '')""", id=genID(), file=file, c=count, mod=time.time(), sum=sum)
def updateMediaCount(deck, file, count=1): mdir = deck.mediaDir() if deck.s.scalar( "select 1 from media where filename = :file", file=file): deck.s.statement( "update media set size = size + :c, created = :t where filename = :file", file=file, c=count, t=time.time()) elif count > 0: try: sum = unicode( checksum(open(os.path.join(mdir, file), "rb").read())) except: sum = u"" deck.s.statement(""" insert into media (id, filename, size, created, originalPath, description) values (:id, :file, :c, :mod, :sum, '')""", id=genID(), file=file, c=count, mod=time.time(), sum=sum)
def latexImgFile(deck, latexCode): key = checksum(latexCode) return "latex-%s.png" % key
def rebuildMediaDir(deck, delete=False, dirty=True): mdir = deck.mediaDir() if not mdir: return (0, 0) deck.startProgress(title=_("Check Media DB")) # set all ref counts to 0 deck.s.statement("update media set size = 0") # look through cards for media references refs = {} normrefs = {} def norm(s): if isinstance(s, str): return unicodedata.normalize('NFD', s) return s for (question, answer) in deck.s.all( "select question, answer from cards"): for txt in (question, answer): for f in mediaFiles(txt): if f in refs: refs[f] += 1 else: refs[f] = 1 normrefs[norm(f)] = True # update ref counts for (file, count) in list(refs.items()): updateMediaCount(deck, file, count) # find unused media unused = [] for file in os.listdir(mdir): path = os.path.join(mdir, file) if not os.path.isfile(path): # ignore directories continue nfile = norm(file) if nfile not in normrefs: unused.append(file) # optionally delete if delete: for f in unused: path = os.path.join(mdir, f) os.unlink(path) # remove entries in db for unused media removeUnusedMedia(deck) # check md5s are up to date update = [] for (file, created, md5) in deck.s.all( "select filename, created, originalPath from media"): path = os.path.join(mdir, file) if not os.path.exists(path): if md5: update.append({'f':file, 'sum':"", 'c':time.time()}) else: sum = str( checksum(open(os.path.join(mdir, file), "rb").read())) if md5 != sum: update.append({'f':file, 'sum':sum, 'c':time.time()}) if update: deck.s.statements(""" update media set originalPath = :sum, created = :c where filename = :f""", update) # update deck and get return info if dirty: deck.flushMod() nohave = deck.s.column0("select filename from media where originalPath = ''") deck.finishProgress() return (nohave, unused)
def rebuildMediaDir(deck, delete=False, dirty=True): mdir = deck.mediaDir() if not mdir: return (0, 0) deck.startProgress(title=_("Check Media DB")) # set all ref counts to 0 deck.s.statement("update media set size = 0") # look through cards for media references refs = {} normrefs = {} def norm(s): if isinstance(s, unicode): return unicodedata.normalize('NFD', s) return s for (question, answer) in deck.s.all( "select question, answer from cards"): for txt in (question, answer): for f in mediaFiles(txt): if f in refs: refs[f] += 1 else: refs[f] = 1 normrefs[norm(f)] = True # update ref counts for (file, count) in refs.items(): updateMediaCount(deck, file, count) # find unused media unused = [] for file in os.listdir(mdir): path = os.path.join(mdir, file) if not os.path.isfile(path): # ignore directories continue nfile = norm(file) if nfile not in normrefs: unused.append(file) # optionally delete if delete: for f in unused: path = os.path.join(mdir, f) os.unlink(path) # remove entries in db for unused media removeUnusedMedia(deck) # check md5s are up to date update = [] for (file, created, md5) in deck.s.all( "select filename, created, originalPath from media"): path = os.path.join(mdir, file) if not os.path.exists(path): if md5: update.append({'f':file, 'sum':u"", 'c':time.time()}) else: sum = unicode( checksum(open(os.path.join(mdir, file), "rb").read())) if md5 != sum: update.append({'f':file, 'sum':sum, 'c':time.time()}) if update: deck.s.statements(""" update media set originalPath = :sum, created = :c where filename = :f""", update) # update deck and get return info if dirty: deck.flushMod() nohave = deck.s.column0("select filename from media where originalPath = ''") deck.finishProgress() return (nohave, unused)