Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
script-name: bilitool/cli.py
mode: app
include-data-files: |
./bilitool/authenticate/config.json=./bilitool/authenticate/config.json
./bilitool/model/config.json=./bilitool/model/config.json

- name: Upload Artifacts
uses: actions/upload-artifact@v4
Expand Down
6 changes: 3 additions & 3 deletions bilitool/authenticate/wbi_sign.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
import urllib.parse
import time
import requests
from bilitool.authenticate.ioer import ioer
from bilitool.model.model import Model

# https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/misc/sign/wbi.md

class WbiSign(object):
def __init__(self):
self.config = ioer().get_config()
self.config = Model().get_config()

mixinKeyEncTab = [
46, 47, 18, 2, 53, 8, 23, 32, 15, 50, 10, 31, 58, 3, 45, 35, 27, 43, 5, 49,
Expand All @@ -22,7 +22,7 @@ def __init__(self):

def get_wbi_keys(self) -> tuple[str, str]:
"""Get the refresh token"""
headers = ioer().get_headers_with_cookies_and_refer()
headers = Model().get_headers_with_cookies_and_refer()
resp = requests.get('https://api.bilibili.com/x/web-interface/nav', headers=headers)
resp.raise_for_status()
json_content = resp.json()
Expand Down
55 changes: 17 additions & 38 deletions bilitool/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,11 @@
import sys
import os
import logging
from bilitool.authenticate.ioer import ioer
from bilitool.login.login_bili import login_bili
from bilitool.utils.parse_cookies import parse_cookies
from bilitool.upload.bili_upload import BiliUploader
from bilitool.utils.parse_yaml import parse_yaml
from bilitool.controller.login_controller import LoginController
from bilitool.controller.upload_controller import UploadController
from bilitool.login.check_login import CheckLogin
from bilitool.login.logout_bili import Logout
from bilitool.controller.download_controller import DownloadController
from bilitool.controller.feed_controller import FeedController
from bilitool.utils.get_ip_info import IPInfo
from bilitool.feed.bili_video_list import BiliVideoList
from bilitool.utils.check_format import CheckFormat

def cli():
Expand Down Expand Up @@ -86,49 +80,34 @@ def cli():
sys.exit()

if args.subcommand == 'login':
login_bili(args.export)
LoginController().login_bilibili(args.export)

if args.subcommand == 'logout':
Logout().logout_bili()
LoginController().logout_bilibili()

if args.subcommand == 'check':
LoginController().check_bilibili_login()

if args.subcommand == 'upload':
# print(args)
if args.yaml:
# * is used to unpack the tuple
upload_metadata = UploadController.package_upload_metadata(*parse_yaml(args.yaml))
else:
upload_metadata = UploadController.package_upload_metadata(
args.line, args.copyright, args.tid, args.title,
args.desc, args.tag, args.source, args.cover, args.dynamic
)
ioer().update_multiple_config(args.subcommand, upload_metadata)
upload_controller = UploadController()
upload_controller.upload_and_publish_video(args.video_path)

if args.subcommand == 'check':
CheckLogin().check_bili_login()
UploadController().upload_video_entry(args.video_path, args.yaml, args.line,
args.copyright, args.tid, args.title, args.desc, args.tag, args.source, args.cover, args.dynamic)

if args.subcommand == 'download':
# print(args)
download_metadata = DownloadController.package_download_metadata(args.danmaku, args.quality, args.chunksize, args.multiple)
ioer().update_multiple_config(args.subcommand, download_metadata)
bvid = CheckFormat().only_bvid(args.vid)
download_controller = DownloadController()
download_controller.download_video(bvid)

if args.subcommand == 'ip':
IPInfo.get_ip_address(args.ip)
DownloadController().download_video_entry(args.vid, args.danmaku, args.quality, args.chunksize, args.multiple)

if args.subcommand == 'list':
bili = BiliVideoList()
bili.print_video_list_info(bili.get_bili_video_list(args.size, args.status))
FeedController().print_video_list_info(args.size, args.status)

if args.subcommand == 'show':
FeedController().print_video_info(args.vid)

if args.subcommand == 'convert':
CheckFormat().convert_bv_and_av(args.vid)

if args.subcommand == 'show':
bvid = CheckFormat().only_bvid(args.vid)
BiliVideoList().print_video_info_via_bvid(bvid)

if args.subcommand == 'ip':
IPInfo.get_ip_address(args.ip)

if __name__ == '__main__':
cli()
14 changes: 11 additions & 3 deletions bilitool/controller/download_controller.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
# Copyright (c) 2025 bilitool

from bilitool.authenticate.ioer import ioer
from bilitool.model.model import Model
from bilitool.download.bili_download import BiliDownloader
from bilitool.utils.check_format import CheckFormat
import re
import logging


class DownloadController:
def __init__(self):
self.logger = logging.getLogger('bilitool')
self.ioer = ioer()
self.model = Model()
self.bili_downloader = BiliDownloader(self.logger)
self.config = self.ioer.get_config()
self.config = self.model.get_config()

def extract_filename(self, filename):
illegal_chars = r'[\\/:"*?<>|]'
Expand Down Expand Up @@ -51,3 +52,10 @@ def download_biv_and_danmaku(self, bvid, cid, name_raw="video"):

def download_danmaku(self, cid, name="video"):
self.bili_downloader.download_danmaku(cid, name)

def download_video_entry(self, vid, danmaku, quality, chunksize, multiple):
download_metadata = self.package_download_metadata(danmaku, quality, chunksize, multiple)
Model().update_multiple_config('download', download_metadata)
bvid = CheckFormat().only_bvid(vid)
self.download_video(bvid)

18 changes: 18 additions & 0 deletions bilitool/controller/feed_controller.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright (c) 2025 bilitool

from bilitool.feed.bili_video_list import BiliVideoList
from bilitool.utils.check_format import CheckFormat

class FeedController(object):
def __init__(self):
self.bili_video_list = BiliVideoList()


def print_video_list_info(self, size: int = 20, status_type: str = 'pubed,not_pubed,is_pubing'):
self.bili_video_list.print_video_list_info(size, status_type)

def print_video_info(self, vid: str):
bvid = CheckFormat().only_bvid(vid)
video_info = self.bili_video_list.get_video_info(bvid)
extracted_info = self.bili_video_list.extract_video_info(video_info)
self.bili_video_list.print_video_info(extracted_info)
30 changes: 30 additions & 0 deletions bilitool/controller/login_controller.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Copyright (c) 2025 bilitool

from bilitool.model.model import Model
import qrcode
from bilitool.login.login_bili import LoginBili
from bilitool.login.logout_bili import LogoutBili
from bilitool.login.check_bili_login import CheckBiliLogin


class LoginController(object):
def __init__(self):
self.model = Model()
self.login_bili = LoginBili()
self.logout_bili = LogoutBili()
self.check_bili_login = CheckBiliLogin()

def login_bilibili(self, export):
input("Please maximize the window to ensure the QR code is fully displayed, press Enter to continue: ")
login_url, auth_code = self.login_bili.get_tv_qrcode_url_and_auth_code()
qr = qrcode.QRCode()
qr.add_data(login_url)
qr.print_ascii()
print("Or copy this link to your phone Bilibili:", login_url)
self.login_bili.verify_login(auth_code, export)

def logout_bilibili(self):
self.logout_bili.logout_bili()

def check_bilibili_login(self):
return self.check_bili_login.check_bili_login()
22 changes: 18 additions & 4 deletions bilitool/controller/upload_controller.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# Copyright (c) 2025 bilitool

from bilitool.authenticate.ioer import ioer
from bilitool.model.model import Model
from bilitool.upload.bili_upload import BiliUploader
from pathlib import Path
import re
from math import ceil
import logging
from bilitool.utils.parse_yaml import parse_yaml


class UploadController:
Expand All @@ -32,8 +33,8 @@ def upload_and_publish_video(self, file):
file = Path(file)
assert file.exists(), f'The file {file} does not exist'
filename = file.name
title = ioer().get_config()["upload"]["title"] or file.stem
ioer().update_specific_config("upload", "title", title)
title = Model().get_config()["upload"]["title"] or file.stem
Model().update_specific_config("upload", "title", title)
filesize = file.stat().st_size
self.logger.info(f'The {title} to be uploaded')

Expand Down Expand Up @@ -78,4 +79,17 @@ def upload_and_publish_video(self, file):
else:
self.logger.error(publish_video_response['message'])
# reset the video title
ioer().update_specific_config("upload", "title", "")
Model().update_specific_config("upload", "title", "")

def upload_video_entry(self, video_path, yaml, line, copyright, tid, title, desc, tag, source, cover, dynamic):
if yaml:
# * is used to unpack the tuple
upload_metadata = self.package_upload_metadata(*parse_yaml(yaml))
else:
upload_metadata = self.package_upload_metadata(
line, copyright, tid, title,
desc, tag, source, cover, dynamic
)
Model().update_multiple_config('upload', upload_metadata)
self.upload_and_publish_video(video_path)

6 changes: 3 additions & 3 deletions bilitool/download/bili_download.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
import time
import sys
from tqdm import tqdm
from bilitool.authenticate.ioer import ioer
from bilitool.model.model import Model


class BiliDownloader:
def __init__(self, logger) -> None:
self.logger = logger
self.config = ioer().get_config()
self.headers = ioer().get_headers_with_cookies_and_refer()
self.config = Model().get_config()
self.headers = Model().get_headers_with_cookies_and_refer()

def get_cid(self,bvid):
url="https://api.bilibili.com/x/player/pagelist?bvid="+bvid
Expand Down
18 changes: 7 additions & 11 deletions bilitool/feed/bili_video_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@

import time
import requests
from bilitool.authenticate.ioer import ioer
from bilitool.model.model import Model
from bilitool.authenticate.wbi_sign import WbiSign
from bilitool.feed import VideoListInfo, state_dict, video_info_dict


class BiliVideoList(object):
def __init__(self):
self.cookies = ioer().get_config()['cookies']
self.headers = ioer().get_headers_with_cookies_and_refer()
self.headers = Model().get_headers_with_cookies_and_refer()

@staticmethod
def save_video_list_info(archive: dict):
Expand All @@ -26,13 +25,13 @@ def save_video_list_info(archive: dict):
info['state_panel'] = archive.get('state_panel')
return info

def get_bili_video_list(self, size: int = 20, target_type: str = 'pubed,not_pubed,is_pubing'):
def get_bili_video_list(self, size: int = 20, status_type: str = 'pubed,not_pubed,is_pubing'):
"""Query the video list

:param size: page size
:param target_type: pubed,not_pubed,is_pubing
:param status_type: pubed,not_pubed,is_pubing
"""
url = f"https://member.bilibili.com/x/web/archives?status={target_type}&pn=1&ps={size}"
url = f"https://member.bilibili.com/x/web/archives?status={status_type}&pn=1&ps={size}"
resp = requests.get(url=url, headers=self.headers)
if resp.status_code != 200:
raise Exception(f"HTTP ERROR code {resp.status_code}")
Expand All @@ -55,8 +54,8 @@ def get_bili_video_list(self, size: int = 20, target_type: str = 'pubed,not_pube
}
return data

@staticmethod
def print_video_list_info(video_data):
def print_video_list_info(self, size: int = 20, status_type: str = 'pubed,not_pubed,is_pubing'):
video_data = self.get_bili_video_list(size, status_type)
for item in video_data['items']:
info = f"{item['state_desc']} | {item['bvid']} | {item['title']}"
extra_info = []
Expand Down Expand Up @@ -111,6 +110,3 @@ def print_video_info(video_info):
value = '原创' if value == 1 else '转载'
label = video_info_dict.get(key, key)
print(f"{label}: {value}")

def print_video_info_via_bvid(self, bvid: str):
BiliVideoList.print_video_info(BiliVideoList.extract_video_info(self.get_video_info(bvid)))
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Copyright (c) 2025 bilitool

from bilitool.authenticate.ioer import ioer
from bilitool.model.model import Model
import requests
import json

class CheckLogin(object):
class CheckBiliLogin(object):
def __init__(self):
self.config = ioer().get_config()
self.config = Model().get_config()

def check_bili_login(self):
url = 'https://api.bilibili.com/x/web-interface/nav'
Expand Down
Loading