mirror of
https://github.com/ankitects/anki.git
synced 2025-09-24 08:46:37 -04:00
centralize all tmp dir access
This commit is contained in:
parent
d96a0eaf08
commit
344b111b80
5 changed files with 72 additions and 44 deletions
|
@ -2,8 +2,8 @@
|
|||
# Copyright: Damien Elmes <anki@ichi2.net>
|
||||
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
import re, tempfile, os, sys, shutil, cgi, subprocess
|
||||
from anki.utils import checksum, call
|
||||
import re, os, sys, shutil, cgi, subprocess
|
||||
from anki.utils import checksum, call, namedtmp, tmpdir, isMac
|
||||
from anki.hooks import addHook
|
||||
from htmlentitydefs import entitydefs
|
||||
from anki.lang import _
|
||||
|
@ -17,10 +17,8 @@ regexps = {
|
|||
"math": re.compile(r"\[\$\$\](.+?)\[/\$\$\]", re.DOTALL | re.IGNORECASE),
|
||||
}
|
||||
|
||||
tmpdir = tempfile.mkdtemp(prefix="anki")
|
||||
|
||||
# add standard tex install location to osx
|
||||
if sys.platform == "darwin":
|
||||
if isMac:
|
||||
os.environ['PATH'] += ":/usr/texbin"
|
||||
|
||||
def stripLatex(text):
|
||||
|
@ -76,17 +74,17 @@ def _buildImg(deck, latex, fname):
|
|||
latex + "\n" +
|
||||
deck.conf["latexPost"])
|
||||
# write into a temp file
|
||||
log = open(os.path.join(tmpdir, "latex_log.txt"), "w+")
|
||||
texpath = os.path.join(tmpdir, "tmp.tex")
|
||||
texfile = file(texpath, "w")
|
||||
log = open(namedtmp("latex_log.txt"), "w")
|
||||
texfile = file(namedtmp("tmp.tex"), "w")
|
||||
texfile.write(latex)
|
||||
texfile.close()
|
||||
# make sure we have a valid mediaDir
|
||||
mdir = deck.media.dir(create=True)
|
||||
oldcwd = os.getcwd()
|
||||
png = namedtmp("tmp.png")
|
||||
try:
|
||||
# generate dvi
|
||||
os.chdir(tmpdir)
|
||||
os.chdir(tmpdir())
|
||||
if call(latexCmd + ["tmp.tex"], stdout=log, stderr=log):
|
||||
return _errMsg("latex")
|
||||
# and png
|
||||
|
@ -94,7 +92,7 @@ def _buildImg(deck, latex, fname):
|
|||
stdout=log, stderr=log):
|
||||
return _errMsg("dvipng")
|
||||
# add to media
|
||||
shutil.copy2(os.path.join(tmpdir, "tmp.png"),
|
||||
shutil.copy2(png,
|
||||
os.path.join(mdir, fname))
|
||||
return
|
||||
finally:
|
||||
|
@ -103,7 +101,7 @@ def _buildImg(deck, latex, fname):
|
|||
def _errMsg(type):
|
||||
msg = (_("Error executing %s.") % type) + "<br>"
|
||||
try:
|
||||
log = open(os.path.join(tmpdir, "latex_log.txt")).read()
|
||||
log = open(namedtmp("latex_log.txt")).read()
|
||||
if not log:
|
||||
raise Exception()
|
||||
msg += "<small><pre>" + cgi.escape(log) + "</pre></small>"
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
# Copyright: Damien Elmes <anki@ichi2.net>
|
||||
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
import os, shutil, re, urllib, urllib2, time, tempfile, unicodedata, \
|
||||
import os, shutil, re, urllib, urllib2, time, unicodedata, \
|
||||
urllib, sys
|
||||
from anki.utils import checksum, intTime
|
||||
from anki.utils import checksum, intTime, namedtmp, isWin
|
||||
from anki.lang import _
|
||||
|
||||
class MediaRegistry(object):
|
||||
|
@ -111,7 +111,7 @@ If the same name exists, compare checksums."""
|
|||
# problem is more complicated - if we percent-escape as utf8 it fixes
|
||||
# some images but breaks others. When filenames are normalized by
|
||||
# dropbox they become unreadable if we escape them.
|
||||
if sys.platform.startswith("win32"):
|
||||
if isWin:
|
||||
return string
|
||||
def repl(match):
|
||||
tag = match.group(1)
|
||||
|
@ -212,12 +212,11 @@ If the same name exists, compare checksums."""
|
|||
for f in mediaFiles(txt, remote=True):
|
||||
refs[f] = True
|
||||
|
||||
tmpdir = tempfile.mkdtemp(prefix="anki")
|
||||
failed = []
|
||||
passed = []
|
||||
for c, link in enumerate(refs.keys()):
|
||||
try:
|
||||
path = os.path.join(tmpdir, os.path.basename(link))
|
||||
path = namedtmp(os.path.basename(link))
|
||||
url = urllib2.urlopen(link)
|
||||
open(path, "wb").write(url.read())
|
||||
newpath = copyToMedia(self.deck, path)
|
||||
|
|
|
@ -3,8 +3,9 @@
|
|||
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
import re, sys, threading, time, subprocess, os, signal, errno, atexit
|
||||
import tempfile, shutil
|
||||
import shutil
|
||||
from anki.hooks import addHook, runHook
|
||||
from anki.utils import namedtmp, tmpdir, isWin, isMac
|
||||
|
||||
# Shared utils
|
||||
##########################################################################
|
||||
|
@ -30,23 +31,18 @@ processingChain = [
|
|||
["lame", "rec.wav", processingDst, "--noreplaygain", "--quiet"],
|
||||
]
|
||||
|
||||
tmpdir = None
|
||||
|
||||
# don't show box on windows
|
||||
if sys.platform == "win32":
|
||||
if isWin:
|
||||
si = subprocess.STARTUPINFO()
|
||||
try:
|
||||
si.dwFlags |= subprocess.STARTF_USESHOWWINDOW
|
||||
except:
|
||||
# python2.7+
|
||||
si.dwFlags |= subprocess._subprocess.STARTF_USESHOWWINDOW
|
||||
# tmp dir for non-hashed media
|
||||
tmpdir = unicode(
|
||||
tempfile.mkdtemp(prefix="anki"), sys.getfilesystemencoding())
|
||||
else:
|
||||
si = None
|
||||
|
||||
if sys.platform.startswith("darwin"):
|
||||
if isMac:
|
||||
# make sure lame, which is installed in /usr/local/bin, is in the path
|
||||
os.environ['PATH'] += ":" + "/usr/local/bin"
|
||||
dir = os.path.dirname(os.path.abspath(__file__))
|
||||
|
@ -64,7 +60,7 @@ def retryWait(proc):
|
|||
# Mplayer settings
|
||||
##########################################################################
|
||||
|
||||
if sys.platform.startswith("win32"):
|
||||
if isWin:
|
||||
mplayerCmd = ["mplayer.exe", "-ao", "win32"]
|
||||
dir = os.path.dirname(os.path.abspath(sys.argv[0]))
|
||||
os.environ['PATH'] += ";" + dir
|
||||
|
@ -157,13 +153,13 @@ def queueMplayer(path):
|
|||
ensureMplayerThreads()
|
||||
while mplayerEvt.isSet():
|
||||
time.sleep(0.1)
|
||||
if tmpdir and os.path.exists(path):
|
||||
if isWin and os.path.exists(path):
|
||||
# mplayer on windows doesn't like the encoding, so we create a
|
||||
# temporary file instead. oddly, foreign characters in the dirname
|
||||
# don't seem to matter.
|
||||
(fd, name) = tempfile.mkstemp(suffix=os.path.splitext(path)[1],
|
||||
dir=tmpdir)
|
||||
f = os.fdopen(fd, "wb")
|
||||
dir = tmpdir().encode(sys.getfilesystemencoding())
|
||||
name = os.path.join(dir, "audio"+os.path.splitext(path)[1])
|
||||
f = open(name, "wb")
|
||||
f.write(open(path, "rb").read())
|
||||
f.close()
|
||||
# it wants unix paths, too!
|
||||
|
@ -194,12 +190,7 @@ def stopMplayer(*args):
|
|||
return
|
||||
mplayerManager.kill()
|
||||
|
||||
def onExit():
|
||||
if tmpdir:
|
||||
shutil.rmtree(tmpdir)
|
||||
|
||||
addHook("deckClosed", stopMplayer)
|
||||
atexit.register(onExit)
|
||||
|
||||
# PyAudio recording
|
||||
##########################################################################
|
||||
|
|
11
anki/sync.py
11
anki/sync.py
|
@ -3,7 +3,7 @@
|
|||
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
import zlib, re, urllib, urllib2, socket, simplejson, time, shutil
|
||||
import os, base64, httplib, sys, tempfile, httplib, types
|
||||
import os, base64, httplib, sys, httplib, types
|
||||
from datetime import date
|
||||
import anki, anki.deck, anki.cards
|
||||
from anki.errors import *
|
||||
|
@ -851,8 +851,8 @@ and cards.id in %s""" % ids2str([c[0] for c in cards])))
|
|||
try:
|
||||
# write into a temporary file, since POST needs content-length
|
||||
src = open(path, "rb")
|
||||
(fd, name) = tempfile.mkstemp(prefix="anki")
|
||||
tmp = open(name, "w+b")
|
||||
name = namedtmp("fullsync.anki")
|
||||
tmp = open(name, "wb")
|
||||
# post vars
|
||||
for (key, value) in fields.items():
|
||||
tmp.write('--' + MIME_BOUNDARY + "\r\n")
|
||||
|
@ -900,8 +900,6 @@ and cards.id in %s""" % ids2str([c[0] for c in cards])))
|
|||
finally:
|
||||
sendProgressHook = None
|
||||
tmp.close()
|
||||
os.close(fd)
|
||||
os.unlink(name)
|
||||
finally:
|
||||
runHook("fullSyncFinished")
|
||||
|
||||
|
@ -910,8 +908,7 @@ and cards.id in %s""" % ids2str([c[0] for c in cards])))
|
|||
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")
|
||||
tmpname = namedtmp("fullsync.anki")
|
||||
tmp = open(tmpname, "wb")
|
||||
decomp = zlib.decompressobj()
|
||||
cnt = 0
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
# Copyright: Damien Elmes <anki@ichi2.net>
|
||||
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
import re, os, random, time, types, math, htmlentitydefs, subprocess
|
||||
import re, os, random, time, types, math, htmlentitydefs, subprocess, \
|
||||
tempfile, shutil
|
||||
|
||||
try:
|
||||
import hashlib
|
||||
|
@ -231,7 +232,7 @@ def joinFields(list):
|
|||
def splitFields(string):
|
||||
return string.split("\x1f")
|
||||
|
||||
# Misc
|
||||
# Checksums
|
||||
##############################################################################
|
||||
|
||||
def checksum(data):
|
||||
|
@ -241,10 +242,46 @@ def fieldChecksum(data):
|
|||
# 32 bit unsigned number from first 8 digits of md5 hash
|
||||
return int(checksum(data.encode("utf-8"))[:8], 16)
|
||||
|
||||
# Temp files
|
||||
##############################################################################
|
||||
|
||||
_tmpdir = None
|
||||
|
||||
def tmpdir():
|
||||
"A reusable temp folder which we clean out on each program invocation."
|
||||
global _tmpdir
|
||||
if not _tmpdir:
|
||||
def cleanup():
|
||||
shutil.rmtree(_tmpdir)
|
||||
import atexit
|
||||
atexit.register(cleanup)
|
||||
_tmpdir = os.path.join(tempfile.gettempdir(), "anki_temp")
|
||||
try:
|
||||
shutil.rmtree(_tmpdir)
|
||||
except (IOError, OSError):
|
||||
pass
|
||||
os.mkdir(_tmpdir)
|
||||
return _tmpdir
|
||||
|
||||
def tmpfile(prefix=None, suffix=None):
|
||||
return tempfile.mkstemp(dir=tmpdir(), prefix=prefix, suffix=suffix)
|
||||
|
||||
def namedtmp(name):
|
||||
"Return tmpdir+name. Deletes any existing file."
|
||||
path = os.path.join(tmpdir(), name)
|
||||
try:
|
||||
os.unlink(path)
|
||||
except (OSError, IOError):
|
||||
pass
|
||||
return path
|
||||
|
||||
# Cmd invocation
|
||||
##############################################################################
|
||||
|
||||
def call(argv, wait=True, **kwargs):
|
||||
"Execute a command. If WAIT, return exit code."
|
||||
# ensure we don't open a separate window for forking process on windows
|
||||
if sys.platform == "win32":
|
||||
if isWin:
|
||||
si = subprocess.STARTUPINFO()
|
||||
try:
|
||||
si.dwFlags |= subprocess.STARTF_USESHOWWINDOW
|
||||
|
@ -270,3 +307,9 @@ def call(argv, wait=True, **kwargs):
|
|||
else:
|
||||
ret = 0
|
||||
return ret
|
||||
|
||||
# OS helpers
|
||||
##############################################################################
|
||||
|
||||
isMac = sys.platform.startswith("darwin")
|
||||
isWin = sys.platform.startswith("win32")
|
||||
|
|
Loading…
Reference in a new issue