上传时加文件锁

This commit is contained in:
yzqzss 2023-06-03 22:36:24 +08:00
parent df0ade28e7
commit 227f981497
2 changed files with 100 additions and 1 deletions

View File

@ -3,11 +3,24 @@ import os
import time
from internetarchive import get_item
from rich import print
from glob import glob
from _biliarchiver_archive_bvid import BILIBILI_IDENTIFIER_PERFIX
from _uploadingLock import UploadLock, AlreadyRunningError
def upload_bvid(bvid):
try:
lock_dir = f'biliarchiver/.locks/{bvid}/'
os.makedirs(lock_dir, exist_ok=True)
with UploadLock(lock_dir):
_upload_bvid(bvid)
except AlreadyRunningError:
print(f'已经有一个上传 {bvid} 的进程在运行,跳过')
except Exception as e:
print(f'上传 {bvid} 时出错:')
raise e
def _upload_bvid(bvid):
if not os.path.exists('biliarchiver.home'):
raise Exception('先创建 biliarchiver.home 文件')
access_key, secret_key = read_ia_keys(os.path.expanduser('~/.bili_ia_keys.txt'))

86
_uploadingLock.py Normal file
View File

@ -0,0 +1,86 @@
import os
import sys
import importlib.util
class AlreadyRunningError(Exception):
def __init__(self, message: str=""):
self.message = message
super().__init__(self.message)
def __str__(self):
return self.message
LOCK_FILENAME = '_uploading.lock'
class UploadLock_Basic:
def __init__(self, lock_dir):
self.lock_file = os.path.join(lock_dir, LOCK_FILENAME)
def __enter__(self):
if os.path.exists(self.lock_file):
with open(self.lock_file, 'r', encoding='utf-8') as f:
print(f.read())
print("Another instance is already running.")
raise AlreadyRunningError('Another instance is already running.')
else:
with open(self.lock_file, 'w', encoding='utf-8') as f:
f.write(f'PID: {os.getpid()}: Running')
print("Acquired lock, continuing.")
def __exit__(self, exc_type, exc_val, exc_tb):
os.remove(self.lock_file)
print("Released lock.")
# decorator
def __call__(self, func):
def wrapper(*args, **kwargs):
with self:
return func(*args, **kwargs)
return wrapper
class UploadLock_Fcntl():
fcntl = None
try:
import fcntl
except ModuleNotFoundError:
pass
def __init__(self, lock_dir):
if self.fcntl is None:
raise(ModuleNotFoundError("No module named 'fcntl'", name='fcntl'))
self.lock_file = os.path.join(lock_dir, LOCK_FILENAME)
self.lock_file_fd = None
def __enter__(self):
self.lock_file_fd = open(self.lock_file, 'w')
try:
self.fcntl.lockf(self.lock_file_fd, self.fcntl.LOCK_EX | self.fcntl.LOCK_NB)
print("Acquired lock, continuing.")
except IOError:
raise AlreadyRunningError("Another instance is already running.")
def __exit__(self, exc_type, exc_val, exc_tb):
if self.lock_file_fd is None:
raise IOError("Lock file not opened.")
self.fcntl.lockf(self.lock_file_fd, self.fcntl.LOCK_UN)
self.lock_file_fd.close()
os.remove(self.lock_file)
print("Released lock.")
# decorator
def __call__(self, func):
def wrapper(*args, **kwargs):
with self:
return func(*args, **kwargs)
return wrapper
class UploadLock():
def __new__(cls, lock_dir):
fcntl_avaivable = importlib.util.find_spec('fcntl')
if fcntl_avaivable is not None:
return UploadLock_Fcntl(lock_dir)
else:
return UploadLock_Basic(lock_dir)