mirror of
https://github.com/saveweb/biliarchiver.git
synced 2024-09-19 11:05:28 -07:00
上传时加文件锁
This commit is contained in:
parent
df0ade28e7
commit
227f981497
@ -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
86
_uploadingLock.py
Normal 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)
|
Loading…
Reference in New Issue
Block a user