mirror of
https://github.com/moparisthebest/SickRage
synced 2024-12-15 04:22:17 -05:00
cec4ed573d
Switched out sqlite3 libs in favour of SQLAlchemy v0.9, will gradually migrate dialects and scheme to be fully SQLAlchemy compliant for using there ORM with sessions instead of direct. Fixed getEpisode function to stop making unrequired scene number conversions on already converted data thats available now from cache.
148 lines
3.2 KiB
Python
148 lines
3.2 KiB
Python
"""
|
|
Platform-independent file locking. Inspired by and modeled after zc.lockfile.
|
|
"""
|
|
|
|
import os
|
|
|
|
try:
|
|
import msvcrt
|
|
except ImportError:
|
|
pass
|
|
|
|
try:
|
|
import fcntl
|
|
except ImportError:
|
|
pass
|
|
|
|
|
|
class LockError(Exception):
|
|
|
|
"Could not obtain a lock"
|
|
|
|
msg = "Unable to lock %r"
|
|
|
|
def __init__(self, path):
|
|
super(LockError, self).__init__(self.msg % path)
|
|
|
|
|
|
class UnlockError(LockError):
|
|
|
|
"Could not release a lock"
|
|
|
|
msg = "Unable to unlock %r"
|
|
|
|
|
|
# first, a default, naive locking implementation
|
|
class LockFile(object):
|
|
|
|
"""
|
|
A default, naive locking implementation. Always fails if the file
|
|
already exists.
|
|
"""
|
|
|
|
def __init__(self, path):
|
|
self.path = path
|
|
try:
|
|
fd = os.open(path, os.O_CREAT | os.O_WRONLY | os.O_EXCL)
|
|
except OSError:
|
|
raise LockError(self.path)
|
|
os.close(fd)
|
|
|
|
def release(self):
|
|
os.remove(self.path)
|
|
|
|
def remove(self):
|
|
pass
|
|
|
|
|
|
class SystemLockFile(object):
|
|
|
|
"""
|
|
An abstract base class for platform-specific locking.
|
|
"""
|
|
|
|
def __init__(self, path):
|
|
self.path = path
|
|
|
|
try:
|
|
# Open lockfile for writing without truncation:
|
|
self.fp = open(path, 'r+')
|
|
except IOError:
|
|
# If the file doesn't exist, IOError is raised; Use a+ instead.
|
|
# Note that there may be a race here. Multiple processes
|
|
# could fail on the r+ open and open the file a+, but only
|
|
# one will get the the lock and write a pid.
|
|
self.fp = open(path, 'a+')
|
|
|
|
try:
|
|
self._lock_file()
|
|
except:
|
|
self.fp.seek(1)
|
|
self.fp.close()
|
|
del self.fp
|
|
raise
|
|
|
|
self.fp.write(" %s\n" % os.getpid())
|
|
self.fp.truncate()
|
|
self.fp.flush()
|
|
|
|
def release(self):
|
|
if not hasattr(self, 'fp'):
|
|
return
|
|
self._unlock_file()
|
|
self.fp.close()
|
|
del self.fp
|
|
|
|
def remove(self):
|
|
"""
|
|
Attempt to remove the file
|
|
"""
|
|
try:
|
|
os.remove(self.path)
|
|
except:
|
|
pass
|
|
|
|
#@abc.abstract_method
|
|
# def _lock_file(self):
|
|
# """Attempt to obtain the lock on self.fp. Raise LockError if not
|
|
# acquired."""
|
|
|
|
def _unlock_file(self):
|
|
"""Attempt to obtain the lock on self.fp. Raise UnlockError if not
|
|
released."""
|
|
|
|
|
|
class WindowsLockFile(SystemLockFile):
|
|
|
|
def _lock_file(self):
|
|
# Lock just the first byte
|
|
try:
|
|
msvcrt.locking(self.fp.fileno(), msvcrt.LK_NBLCK, 1)
|
|
except IOError:
|
|
raise LockError(self.fp.name)
|
|
|
|
def _unlock_file(self):
|
|
try:
|
|
self.fp.seek(0)
|
|
msvcrt.locking(self.fp.fileno(), msvcrt.LK_UNLCK, 1)
|
|
except IOError:
|
|
raise UnlockError(self.fp.name)
|
|
|
|
if 'msvcrt' in globals():
|
|
LockFile = WindowsLockFile
|
|
|
|
|
|
class UnixLockFile(SystemLockFile):
|
|
|
|
def _lock_file(self):
|
|
flags = fcntl.LOCK_EX | fcntl.LOCK_NB
|
|
try:
|
|
fcntl.flock(self.fp.fileno(), flags)
|
|
except IOError:
|
|
raise LockError(self.fp.name)
|
|
|
|
# no need to implement _unlock_file, it will be unlocked on close()
|
|
|
|
if 'fcntl' in globals():
|
|
LockFile = UnixLockFile
|