Skip to content

Commit

Permalink
add scanning bdinfo function
Browse files Browse the repository at this point in the history
  • Loading branch information
LeiShi1313 committed Dec 2, 2021
1 parent 2cf5d6d commit 45f0dd6
Show file tree
Hide file tree
Showing 10 changed files with 76 additions and 9 deletions.
49 changes: 44 additions & 5 deletions differential/plugins/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,16 @@
from loguru import logger
from pymediainfo import MediaInfo

from differential import tools
from differential.torrent import TorrnetBase
from differential.version import version
from differential.constants import ImageHosting
from differential.utils.browser import open_link
from differential.utils.mediainfo import get_track_attr
from differential.utils.torrent import make_torrent
from differential.utils.parse import parse_encoder_log
from differential.utils.binary import ffprobe, execute
from differential.utils.uploader import EasyUpload, AutoFeed
from differential.utils.binary import ffprobe, execute, execute_with_output
from differential.utils.mediainfo import get_track_attr, get_full_mediainfo, get_resolution, get_duration
from differential.utils.image import byr_upload, ptpimg_upload, smms_upload, imgurl_upload, chevereto_api_upload, chevereto_username_upload

Expand Down Expand Up @@ -82,13 +83,14 @@ def add_parser(cls, parser: argparse.ArgumentParser) -> argparse.ArgumentParser:
parser.add_argument('-n', '--generate-nfo', action="store_true", help="是否用MediaInfo生成NFO文件,默认否",
default=argparse.SUPPRESS)
parser.add_argument('-s', '--screenshot-count', type=int, help="截图数量,默认为0,即不生成截图", default=argparse.SUPPRESS)
parser.add_argument('--use-short-bdinfo', action="store_true", help="使用QUICK SUMMARY作为BDInfo,默认使用完整BDInfo",
default=argparse.SUPPRESS)
parser.add_argument('--optimize-screenshot', action="store_true", help="是否压缩截图(无损),默认压缩",
default=argparse.SUPPRESS)
parser.add_argument('--image-hosting', type=ImageHosting,
help=f"图床的类型,现在支持{','.join(i.value for i in ImageHosting)}", default=argparse.SUPPRESS)
parser.add_argument('--imgurl-hosting-url', type=str, help="自建imgurl图床的地址", default=argparse.SUPPRESS)
parser.add_argument('--chevereto-hosting-url', type=str, help="自建chevereto图床的地址", default=argparse.SUPPRESS)
parser.add_argument('--ptpimg-api-key', type=str, help="PTPIMG的API Key", default=argparse.SUPPRESS)
parser.add_argument('--chevereto-hosting-url', type=str, help="自建chevereto图床的地址", default=argparse.SUPPRESS)
parser.add_argument('--chevereto-api-key', type=str, help="自建Chevereto的API Key,详情见https://v3-docs.chevereto.com/api/#api-call", default=argparse.SUPPRESS)
parser.add_argument('--chevereto-username', type=str, help="如果自建Chevereto的API未开放,请设置username和password", default=argparse.SUPPRESS)
parser.add_argument('--chevereto-password', type=str, help="如果自建Chevereto的API未开放,请设置username和password", default=argparse.SUPPRESS)
Expand All @@ -114,6 +116,7 @@ def __init__(
upload_url: str,
screenshot_count: int = 0,
optimize_screenshot: bool = True,
use_short_bdinfo: bool = False,
image_hosting: ImageHosting = ImageHosting.PTPIMG,
chevereto_hosting_url: str = '',
imgurl_hosting_url: str = '',
Expand Down Expand Up @@ -141,6 +144,7 @@ def __init__(
self.upload_url = upload_url
self.screenshot_count = screenshot_count
self.optimize_screenshot = optimize_screenshot
self.use_short_bdinfo = use_short_bdinfo
self.image_hosting = image_hosting
self.chevereto_hosting_url = chevereto_hosting_url
self.imgurl_hosting_url = imgurl_hosting_url
Expand All @@ -162,6 +166,8 @@ def __init__(
self.trim_description = trim_description
self.encoder_log = encoder_log

self.is_bdmv = False
self._bdinfo = None
self._main_file: Optional[Path] = None
self._ptgen: dict = {}
self._imdb: dict = {}
Expand Down Expand Up @@ -234,6 +240,30 @@ def _get_ptgen(self) -> dict:
logger.info(f"获取PTGen成功 {req.json().get('chinese_title', '')}")
return req.json()

def _get_bdinfo(self) -> str:
logger.info("目标为BDMV,正在扫描BDInfo...")
temp_dir = tempfile.mkdtemp()
bdinfos = []
for f in self.folder.glob("**/BDMV"):
logger.info(f"正在扫描{f.parent}...")
execute_with_output(
"mono",
f'''"{os.path.join(os.path.dirname(tools.__file__), 'BDinfoCli.0.7.3/BDInfo.exe')}" -w '''
f'"{f.parent}" {temp_dir}',
abort=True)
for info in tempfile.glob("*.txt"):
with info.open('r') as f:
content = f.read()
if self.use_short_bdinfo:
m = re.search(r'(QUICK SUMMARY:\n+(.+?\n)+)\n\n', content)
if m:
bdinfos.append(m.groups()[0])
else:
m = re.search(r'(DISC INFO:\n+(.+?\n{1,2})+)\[\/code\]\n<---- END FORUMS PASTE ---->', content)
if m:
bdinfos.append(m.groups()[0])
return '\n\n'.join(bdinfos)

def _find_mediainfo(self) -> MediaInfo:
# Always find the biggest file in the folder
logger.info(f"正在获取Mediainfo: {self.folder}")
Expand All @@ -243,8 +273,11 @@ def _find_mediainfo(self) -> MediaInfo:
logger.info("目标为文件夹,正在获取最大的文件...")
biggest_size = -1
biggest_file = None
has_bdmv = False
for f in self.folder.glob('**/*'):
if f.is_file():
if f.suffix == '.bdmv':
has_bdmv = True
s = os.stat(f.absolute()).st_size
if s > biggest_size:
biggest_size = s
Expand All @@ -257,6 +290,9 @@ def _find_mediainfo(self) -> MediaInfo:
mediainfo = MediaInfo.parse(self._main_file)
logger.info(f"已获取Mediainfo: {self._main_file}")
logger.trace(mediainfo.to_data())
if has_bdmv:
self.is_bdmv = True
self._bdinfo = self._get_bdinfo()
return mediainfo

def _generate_nfo(self):
Expand Down Expand Up @@ -291,7 +327,7 @@ def _make_screenshots(self) -> Optional[str]:
screenshot_path = f'{temp_dir}/{self._main_file.stem}.thumb_{str(i).zfill(2)}.png'
execute("ffmpeg", (
f'-y -ss {t}ms -skip_frame nokey -i "{self._main_file.absolute()}" '
f'-s {resolution} -vsync 0 -vframes 1 -c:v png -v quiet "{screenshot_path}"'))
f'-s {resolution} -vsync 0 -vframes 1 -c:v png "{screenshot_path}"'))
if self.optimize_screenshot:
image = Image.open(screenshot_path)
image.save(f"{screenshot_path}", format="PNG", optimized=True)
Expand Down Expand Up @@ -364,7 +400,10 @@ def subtitle(self):

@property
def media_info(self):
return get_full_mediainfo(self._mediainfo)
if self.is_bdmv:
return self._bdinfo
else:
return get_full_mediainfo(self._mediainfo)

@property
def media_infos(self):
Expand Down
Binary file added differential/tools/BDinfoCli.0.7.3/BDInfo.exe
Binary file not shown.
Binary file not shown.
Binary file added differential/tools/BDinfoCli.0.7.3/DiscUtils.dll
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added differential/tools/BDinfoCli.0.7.3/ZedGraph.dll
Binary file not shown.
Empty file added differential/tools/__init__.py
Empty file.
36 changes: 32 additions & 4 deletions differential/utils/binary.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os
import re
import sys
import shutil
import subprocess
Expand Down Expand Up @@ -38,8 +39,7 @@ def find_binary(name: str, alternative_names: list = None) -> Optional[Path]:
)
return None


def execute(binary_name: str, args: str, abort: bool = False) -> str:
def build_cmd(binary_name: str, args: str, abort: bool = False) -> str:
executable = find_binary(binary_name)
if executable is None:
if abort:
Expand All @@ -48,9 +48,37 @@ def execute(binary_name: str, args: str, abort: bool = False) -> str:
return ""
cmd = f'"{executable}" {args}'
logger.trace(cmd)
return cmd

def execute_with_output(binary_name: str, args: str, abort: bool = False) -> int:
cmd = build_cmd(binary_name, args, abort)
return_code = 0

def _execute():
proc = subprocess.Popen(cmd, shell=True, bufsize=1, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
universal_newlines=True)
for stdout in iter(proc.stdout.readline, ""):
yield stdout
proc.stdout.close()
return_code = proc.wait()
prev = ''
for out in iter(_execute()):
out = out.strip()
if re.sub('(\d| )', '', out) != re.sub('(\d| )', '', prev):
print(out)
else:
print(out, end='\r')
sys.stdout.flush()
prev = out
if return_code != 0:
logger.warning(f"{binary_name} exit with return code {return_code}")
return return_code


def execute(binary_name: str, args: str, abort: bool = False) -> str:
cmd = build_cmd(binary_name, args, abort)
proc = subprocess.run(
cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
)
cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
logger.trace(proc)
ret = "\n".join([proc.stdout.decode(), proc.stderr.decode()])
if proc.returncode != 0:
Expand Down

0 comments on commit 45f0dd6

Please sign in to comment.