feat: add nodejs install and optimize log print

This commit is contained in:
ihmily 2024-10-22 05:32:18 +08:00
parent 76e56f3673
commit 34e038784f
8 changed files with 237 additions and 14 deletions

View File

@ -0,0 +1,189 @@
# -*- coding: utf-8 -*-
"""
Author: Hmily
GitHub:https://github.com/ihmily
Copyright (c) 2024 by Hmily, All Rights Reserved.
"""
import os
import subprocess
import sys
import platform
import requests
import re
import distro
from tqdm import tqdm
from .logger import logger
current_platform = platform.system()
def install_nodejs_windows():
try:
logger.warning("Node.js is not installed.")
logger.debug("Installing the stable version of Node.js for Windows...")
response = requests.get('https://nodejs.cn/download/')
if response.status_code == 200:
match = re.search('href="(https://npmmirror.com/mirrors/node/v.*?/node-v.*?.msi)"> <svg class="d',
response.text)
if match:
url = match.group(1)
version = url.rsplit('/', maxsplit=2)[1]
else:
logger.error("Failed to retrieve the download URL for the latest version of Node.js...")
return
temp_dir = os.path.split(os.path.realpath(sys.argv[0]))[0]
file_path = os.path.join(temp_dir, url.rsplit('/', maxsplit=1)[-1])
if os.path.exists(file_path):
logger.debug("Node.js installation file already exists, start install...")
else:
response = requests.get(url, stream=True)
total_size = int(response.headers.get('Content-Length', 0))
block_size = 1024
with tqdm(total=total_size, unit="B", unit_scale=True,
ncols=100, desc=f'Downloading Node.js ({version})') as t:
with open(file_path, 'wb') as f:
for data in response.iter_content(block_size):
t.update(len(data))
f.write(data)
powershell_command = f"Start-Process 'msiexec' -ArgumentList '/i {file_path} /quiet' -Wait -NoNewWindow"
result = subprocess.run(["powershell", "-Command", powershell_command], capture_output=True, text=True)
if result.returncode == 0:
logger.debug('Node.js installation was successful. Restart for changes to take effect.')
return True
else:
logger.error("Node.js installation failed")
else:
logger.error("Failed to retrieve the stable Node.js version page")
except Exception as e:
logger.error(f"type: {type(e).__name__}, Node.js installation failed")
def install_nodejs_centos():
try:
logger.warning("Node.js is not installed.")
logger.debug("Installing the latest version of Node.js for CentOS...")
result = subprocess.run('curl -fsSL https://mirrors.tuna.tsinghua.edu.cn/nodesource/rpm/setup_lts.x | '
'bash -', shell=True, capture_output=True)
if result.returncode != 0:
logger.error("Failed to run NodeSource installation script")
return
result = subprocess.run(['yum', 'install', '-y', 'epel-release'], capture_output=True)
if result.returncode != 0:
logger.error("Failed to install EPEL repository")
return
result = subprocess.run(['yum', 'install', '-y', 'nodejs'], capture_output=True)
if result.returncode == 0:
logger.debug('Node.js installation was successful. Restart for changes to take effect.')
return True
else:
logger.error("Node.js installation failed")
except Exception as e:
logger.error(f"type: {type(e).__name__}, Node.js installation failed {e}")
def install_nodejs_ubuntu():
try:
logger.warning("Node.js is not installed.")
logger.debug("Installing the latest version of Node.js for Ubuntu...")
install_script = 'curl -fsSL https://deb.nodesource.com/setup_lts.x | bash -'
result = subprocess.run(install_script, shell=True, capture_output=True)
if result.returncode != 0:
logger.error("Failed to run NodeSource installation script")
return
install_command = ['apt', 'install', '-y', 'nodejs']
result = subprocess.run(install_command, capture_output=True)
if result.returncode == 0:
logger.debug('Node.js installation was successful. Restart for changes to take effect.')
return True
else:
logger.error("Node.js installation failed")
except Exception as e:
logger.error(f"type: {type(e).__name__}, Node.js installation failed, {e}")
def install_nodejs_mac():
logger.warning("Node.js is not installed.")
logger.debug("Installing the latest version of Node.js for macOS...")
try:
result = subprocess.run(["brew", "install", "node"], capture_output=True)
if result.returncode == 0:
logger.debug('Node.js installation was successful. Restart for changes to take effect.')
return True
else:
logger.error("Node.js installation failed")
except subprocess.CalledProcessError as e:
logger.error(f"Failed to install Node.js using Homebrew. {e}")
logger.error("Please install Node.js manually or check your Homebrew installation.")
except Exception as e:
logger.error(f"An unexpected error occurred: {e}")
def install_nodejs():
if current_platform == "Windows":
return install_nodejs_windows()
elif current_platform == "Linux":
dist = distro.id()
if dist.lower() == "centos":
return install_nodejs_centos()
elif dist.lower() == "ubuntu":
return install_nodejs_ubuntu()
elif current_platform == "Darwin":
return install_nodejs_mac()
else:
logger.debug(f"Node.js auto installation is not supported on this platform: {current_platform}. "
f"Please install Node.js manually.")
def ensure_nodejs_installed(func):
def wrapper(*args, **kwargs):
try:
result = subprocess.run(['node', '-v'], capture_output=True)
version = result.stdout.strip()
if result.returncode == 0 and version:
return func(*args, **kwargs)
except FileNotFoundError:
pass
return False
def wrapped_func(*args, **kwargs):
if sys.version_info >= (3, 7):
res = wrapper(*args, **kwargs)
else:
res = wrapper(*args, **kwargs)
if not res:
install_nodejs()
res = wrapper(*args, **kwargs)
if not res:
raise RuntimeError("Node.js is not installed.")
return func(*args, **kwargs)
return wrapped_func
def check_nodejs_installed():
try:
result = subprocess.run(['node', '-v'], capture_output=True)
version = result.stdout.strip()
if result.returncode == 0 and version:
return True
except FileNotFoundError:
pass
return False
def check_node():
res = check_nodejs_installed()
if not res:
return install_nodejs()

View File

@ -3,9 +3,24 @@
import os
import sys
custom_format = "<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green> | <level>{level: <8}</level> - <level>{message}</level>"
os.environ["LOGURU_FORMAT"] = custom_format
from loguru import logger
script_path = os.path.split(os.path.realpath(sys.argv[0]))[0]
logger.add(
f"{script_path}/logs/DouyinLiveRecorder.log",
level="DEBUG",
format="{time:YYYY-MM-DD HH:mm:ss.SSS} | {level: <8} | {name}:{function}:{line} - {message}",
filter=lambda i: i["level"].name == "DEBUG",
serialize=False,
enqueue=True,
retention=1,
rotation="100 KB",
encoding='utf-8'
)
logger.add(
f"{script_path}/logs/PlayURL.log",
level="INFO",
@ -15,13 +30,16 @@ logger.add(
enqueue=True,
retention=1,
rotation="300 KB",
encoding='utf-8'
)
logger.add(
f"{script_path}/logs/DouyinLiveRecorder.log",
level="WARNING",
format="{time:YYYY-MM-DD HH:mm:ss.SSS} | {level: <8} | {name}:{function}:{line} - {message}",
serialize=False,
enqueue=True,
retention=1,
rotation="100 KB",
encoding='utf-8'
)

View File

@ -2,7 +2,7 @@
"""
Author: Hmily
Github:https://github.com/ihmily
GitHub:https://github.com/ihmily
Date: 2023-07-17 23:52:05
Update: 2024-10-08 23:35:00
Copyright (c) 2023 by Hmily, All Rights Reserved.
@ -127,4 +127,4 @@ if __name__ == '__main__':
room_url = "https://v.douyin.com/iQLgKSj/"
_room_id, sec_uid = get_sec_user_id(room_url)
web_rid = get_live_room_id(_room_id, sec_uid)
print("return web_rid:", web_rid)
print("return web_rid:", web_rid)

View File

@ -4,18 +4,31 @@ import os
import functools
import hashlib
import re
import time
import traceback
from typing import Union, Any
import execjs
from .logger import logger
import configparser
is_install_node = False
def trace_error_decorator(func: callable) -> callable:
@functools.wraps(func)
def wrapper(*args: list, **kwargs: dict) -> Any:
try:
return func(*args, **kwargs)
except execjs.ProgramError:
global is_install_node
if not is_install_node:
is_install_node = True
logger.warning('Failed to execute JS code. Please check if the Node.js environment')
from .initializer import check_node
is_install_node = check_node()
if is_install_node:
time.sleep(3)
os._exit(0)
except Exception as e:
error_line = traceback.extract_tb(e.__traceback__)[-1].lineno
error_info = f"错误信息: type: {type(e).__name__}, {str(e)} in function {func.__name__} at line: {error_line}"
@ -57,7 +70,6 @@ def read_config_value(file_path, section, key) -> Union[str, None]:
def update_config(file_path, section, key, new_value) -> None:
config = configparser.ConfigParser()
try:

View File

@ -241,7 +241,7 @@ def adjust_max_request():
if pre_max_request != max_request:
pre_max_request = max_request
print(f"同一时间访问网络的线程数动态改为 {max_request}")
print(f"\r同一时间访问网络的线程数动态改为 {max_request}")
error_window.append(error_count)
if len(error_window) > error_window_size:

View File

@ -1,5 +1,5 @@
[project]
requires-python = ">=3.8,<3.13"
requires-python = ">=3.10,<3.13"
[build-system]
requires = ["poetry-core>=1.0.0"]
@ -7,7 +7,7 @@ build-backend = "poetry.core.masonry.api"
[tool.poetry]
name = "douyinliverecorder"
version = "3.0.8"
version = "3.0.9"
description = "An easy tool for recording live streams"
authors = ["Hmily"]
license = "MIT"
@ -17,8 +17,10 @@ repository = "https://github.com/ihmily/DouyinLiveRecorder"
keywords = ["douyin", "live", "recorder"]
[tool.poetry.dependencies]
python = "^3.8"
python = "^3.10"
requests = "^2.25.1"
PyExecJS = "^1.5.1"
loguru = "^0.5.3"
pycryptodome = "^3.10.1"
pycryptodome = "^3.10.1"
distro = "^1.9.0"
tqdm = "^4.66.5"

View File

@ -1,4 +1,6 @@
requests
PyExecJS
loguru==0.7.2
pycryptodome==3.20.0
pycryptodome==3.20.0
distro==1.9.0
tqdm==4.66.5

View File

@ -3,7 +3,7 @@ from setuptools import setup, find_packages
setup(
name='douyinliverecorder',
version='3.0.8',
version='3.0.9',
author='Hmily',
description='An easy tool for recording live streams',
long_description=open('README.md', encoding='utf-8').read(),
@ -14,15 +14,15 @@ setup(
'requests',
'PyExecJS',
'loguru',
'pycryptodome'
'pycryptodome',
'distro',
'tqdm'
],
classifiers=[
'Development Status :: 3 - Alpha',
'Intended Audience :: Developers',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3 :: Only',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
'Programming Language :: Python :: 3.12',