diff --git a/config/config.yaml b/config/config.yaml deleted file mode 100644 index c48e09a6..00000000 --- a/config/config.yaml +++ /dev/null @@ -1,217 +0,0 @@ -# 【配置注意要符合yaml语法,:号后有1个空格,不能使用全角标点符号】 -# 【最新版本已经可以通过WEB页面对所有配置项进行配置,推荐使用WEB页面进行配置】 -# 【文件转移方式的说明】 -# 目前支持的文件转移方式:link、copy、softlink、move、rclone、rclonecopy,link即硬链接、softlink为软链接、copy为复制、move为移动、rclone针对rclone网盘挂载(rclone为移动、rclonecopy为复制) -# link要求源目录和目的目录或媒体库目录在一个磁盘分区或者存储空间,Docker运行时link模式需要直接映射源目录和目的目录或媒体库目录的上级目录,否则docker可能仍然会认为是跨盘 -# softlink模式注意宿主机的源目录映射到docker容器中后要路径要一致,否则可能软链接成功但无法在宿主机使用 -# copy模式会直接复制一份文件数据 -# move会直接移动原文件,会影响做种,请谨慎使用 -# rclone需要自行映射rclone配置目录到容器中,或在容器内完成rclone配置 -app: - # 【日志记录类型】:server、file、console - # 如果是使用Docker安装建议设置为console,通过Docker管理器查看日志 - # 如果是使用群晖套件建议配置为 server,可将日志输出到群晖的日志中心便于查看 - # 其它情况可以设置为file,将日志写入文件 - logtype: console - # 【日志文件的路径】:logtype为file时生效 - logpath: - # 【群晖日志中心IP和端口】:logtype为SERVER时生效。端口一般是514,只需要改动IP为群晖的IP,示例:127.0.0.1:514 - logserver: 127.0.0.1:514 - # 【日志级别】:info、debug、error - loglevel: info - # 【WEB管理界面监听地址】:如需支持ipv6需设置为::,如::无法访问可改为0.0.0.0 - web_host: "::" - # 【WEB管理界面端口】:默认3000 - web_port: 3000 - # 【WEB管理页面登录用户】,默认admin - login_user: admin - # 【WEB管理页面登录密码】:默认password,如果是全数字密码,要用''括起来 - login_password: password - # 【WEB管理界面使用的HTTPS的证书和KEY的路径】,留空则不启用HTTPS - ssl_cert: - ssl_key: - # 【设置代理】,themoviedb、fanart、telegram等将使用代理访问,http和https均需配置,可以是http也可以是socks5、socks5h(remote DNS) ,但需要带http或socks5前缀,两项可以配置为一样,留空则不启用 - # 示例:'http://127.0.0.1:7890' 'socks5://127.0.0.1:8018' 'socks5h://127.0.0.1:8018' - proxies: - http: - https: - # 【TMDB API KEY】:需要在https://www.themoviedb.org/申请,必须配置,否则无法识别媒体资源和重命名 - # 以下地址需要网络能够正常访问:api.themoviedb.org、webservice.fanart.tv - rmt_tmdbkey: - # 【使用TMDB服务器域名】:api.themoviedb.org、api.tmdb.org,如api.themoviedb.org无法访问可偿试使用api.tmdb.org - tmdb_domain: api.tmdb.org - # 【TMDB图片代理地址】:加速图片下载,留空使用TMDB官方地址 - tmdb_image_url: https://image.tmdb.org - # 【TMDB匹配模式】:normal、strict,normal模式下如使用文件名/种子名中的年份无法匹配到媒体信息,会去掉年份再匹配一次;strict模式则严格按文件中年份匹配 - # normal模式下会提升识别成功率,但也可能会导致误识别率增加;strict模式可以降低误识别率,但可能导致很多文件名/种子名中年份不正确的无法被识别(特别是剧集,需要是首播年份) - rmt_match_mode: normal - # 【本系统的WEB的外网地址】:需要是外网IP或者域名,需要包含端口,用于微信/Telegram信息点击跳转,如不需要可配空 - # 示例:http://IP:3000 - domain: "" - # 【UserAgent】:可适当修改,用于站点签到、豆瓣数据抓取等 - user_agent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36" - # 【登录界面壁纸】:themoviedb、bing,设置为themoviedb时需要配置TMDB API Key时才生效 - wallpaper: bing - # Debug mode - debug: true - # 开启后,只有Releases更新,才会有更新提示 - releases_update_only: false - -# 【配置媒体库信息】 -media: - # 【媒体库电影文件存放目录】:支持配置多个目录,不同的硬盘需映射为不同的根目录,以更于程序区分 - movie_path: - # 【媒体库电视剧文件存放目录】:支持配置多个目录,不同的硬盘需映射为不同的根目录,以更于程序区分 - tv_path: - # 【媒体库动漫文件单独存放目录】:支持配置多个目录,不同的硬盘需映射为不同的根目录,以更于程序区分 - # 如果设置了该目录,则所有动漫电视剧都会识别为动漫并存放在该目录下,否则动漫电视剧会识别为电视剧并存放在电视剧目录分类下;动漫电影仍然在电影目录分类下 - anime_path: - # 【无法识别时转移存放的目录】:如有多个磁盘,需要对应配置多个目录,否则跨盘无法硬链接 - # 注意:如果你在sync区域配置了未识别目录,由会优先转移到对应未识别目录下,只有下载文件转移及sync未配置未识别目录时才会使用该目录 - # 未识别的记录同时会在媒体整理->手动识别下面出现,unknown_path只是硬链接一份用于备份,同时手工识别处理后程序也不会主动删除,如果不想要多硬链接一份,可以不配置该目录 - unknown_path: - # 【二级分类开关】:电影/电视剧/动漫是否需要二级分类,启用二级分类后会在电影/电视剧/动漫目录下按二级分类名建立子目录 - # 此处配置分类的策略名,配置文件目录中需要有与策略名同名的.yaml配置文件 - # 默认策略default-category分类设置可参考"default-category.yaml",分类参见README.MD说明 - # 如不需要启动分类,则该项配置为空 - category: "default-category" - # 【媒体库管理软件】:emby、jellyfin、plex,需要在emby或jellyfin或plex区配置详细信息,用于下载检查控重、媒体库展示等,建议配置 - media_server: emby - # 【媒体库数据同步周期】:定时同步媒体服务器数据到本地,单位小时 - mediasync_interval: 12 - # 【转移到媒体库的最小文件大小】:避免预告片/MV等影响识别,单位M - min_filesize: 150 - # 【文件名转移忽略词】:文件名包含忽略词,忽略转移 - ignored_files: - # 【文件路径转移忽略词】:文件路径包含忽略词,忽略转移 - ignored_paths: - # 【洗版开关】:如开启则则新下载了更大的文件会覆盖媒体库目录中已有的文件 - filesize_cover: true - # 【电影命名定义】:程序会按定义的命名格式对电影进行重命名;/代表上下级目录,{}内为占位符;占位符会使用文件识别出来的实际值替换;占位符外的字符会当成普通字符,直接体现在名称上 - # 电影占位符有:{title}:标题,{en_title}:英文标题,{original_title}:原语种标题,{original_name}:原文件名,{year}:年份,{edition}:版本(Bluray/WEB-DL等),{videoFormat}:分辨率(1080p/4k等),{videoCodec}:视频编码,{audioCodec}:音频编码及声道,{effect}: 视频特效(DV,HDR等), {tmdbid}:TMDB的ID, {imdbid}:IMDB的ID,{part}:part1/disc1/dvd1,{releaseGroup}:制作组/字幕组等 - movie_name_format: "{title} ({year})/{title}-{part} ({year}) - {videoFormat}" - # 【电视剧命名定义】:程序会按定义的命名格式对电视剧进行重命名;/代表上下级目录,{}内为占位符;占位符会使用文件识别出来的实际值替换,占位符外的字符会当成普通字符,直接体现在名称上 - # 电视剧占位符有:{title}:标题,{en_title}:英文标题,{original_title}:原语种标题,{original_name}:原文件名,{year}:年份,{edition}:版本(Bluray/WEB-DL等),{videoFormat}:分辨率(1080p/4k等),{videoCodec}:视频编码,{audioCodec}:音频编码及声道,{effect}: 视频特效(DV,HDR等), {tmdbid}:TMDB的ID,{imdbid}:IMDB的ID,{season}:季数,{episode}:集数,{season_episode}:剧集SxxExx,{part}:part1/disc1/dvd1,{releaseGroup}:制作组/字幕组等 - tv_name_format: "{title} ({year})/Season {season}/{title}-{part} - {season_episode} - 第{episode}集" - # 【刮削元数据及图片】:开启后文件转移完成时会自动生成nfo描述文件及poster海报,协助媒体服务器识别和搜刮 - nfo_poster: false - # 文件管理、自定义识别等默认路径 - media_default_path: - # 默认文件转移方式 - default_rmt_mode: copy - # 默认TMDB信息语种 - tmdb_language: zh - # 【搜索结果中包含成人内容条目】:需要先去TMDB个人设置中将<搜索结果中包含成人内容条目>选项开启,开启该选项后将会在刮削或者检索时包含成人内容 - tmdb_include_adult: false - # 【使用横杠替换冒号】:如开启,文件名中的中英文冒号将替换为横杠 - filename_prefer_barre: false - # 【获取视频元数据】:如开启,视频文件名不包含视频元数据的情况,则会通过ffmpeg获取,将会大幅增加转移时间,低配置机器不建议开启 - ffmpeg_video_meta: false - -# 配置Emby服务器信息 -emby: - # 【Emby服务器IP地址和端口】:注意区分http和https,http时可以不加http://,https时必须加https:// - host: http://127.0.0.1:8096 - # 【Emby ApiKey】:在Emby设置->高级->API密钥处生成,注意不要复制到了应用名称 - api_key: - # 【Emby媒体播放地址和端口】:播放设备的访问地址,注意区分http和https,http时可以不加http://,https时必须加https:// - play_host: http://127.0.0.1:8096 - -# 配置Jellyfin服务器信息 -jellyfin: - # 【Jellyfin服务器IP地址和端口】:注意区分http和https,http时可以不加http://,https时必须加https:// - host: http://127.0.0.1:8096 - # 【Jellyfin ApiKey】:在Jellyfin设置->高级->API密钥处生成 - api_key: - # 【Jellyfin媒体播放地址和端口】:播放设备的访问地址,注意区分http和https,http时可以不加http://,https时必须加https:// - play_host: http://127.0.0.1:8096 - -# 配置Plex服务器信息 -plex: - # 【Plex服务器IP地址和端口】:注意区分http和https,http时可以不加http://,https时必须加https:// - host: http://127.0.0.1:32400 - # 【X-Plex-Token】:Plex页面Cookie中的X-Plex-Token,如填写token则无需填写servername、username、password - token: - # 【Plex服务器的名称】 - servername: - # 【Plex用户名】 - username: - # 【Plex用户密码】 - password: - -# 【配置站点搜索信息】 -pt: - #【聚合搜索使用的检索器】:builtin - search_indexer: builtin - # 【远程搜索自动择优下载开关】:如开启则微信等渠道搜索后会自动择优选择一项下载,如不开启则需要手工点击进入WEB页面选择下载 - # 如没有配置app.domain或无公网环境建议开启,否则无法跳转WEB页面手工选择 - search_auto: true - # 【远程下载不完整自动订阅】:如开启,远程搜索下载不完整时,会自动添加RSS订阅 - search_no_result_rss: false - # 【RSS订阅开关】:此处配置RSS订阅检查时间间隔,即每隔多长时间检查一下各站点是否有资源更新,建议不要少于30分钟,单位时间为秒 - # 配置为空或者0则不启用RSS订阅功能 - pt_check_interval: 1800 - # 【定量搜索RSS开关】:打开后,每隔设置时间会通过站点资源检索的方式查询和下载订阅,单位:小时,配置小于6小时时强制为6小时,不配置则为关 - search_rss_interval: 6 - # 【下载优先规则】:订阅及远程搜索下载将按此优先规则选择下载资源,字典:site 站点优先、seeder做种数优先 - download_order: site - # 【搜索结果数量限制】:每个站点返回搜索结果的最大数量 - site_search_result_num: 100 - # 【强制开启刷流】:一般情况需要新人在考核期摸索完PT规则才可以开启刷流,开启后将会允许无视该规则强制刷流 - force_enable_brush: false - -# 【openai】 -openai: - # 【openai api key】:openai的api key,可在openai官网申请 - api_key: - # 【openai api url】:自定义openai请求地址 - api_url: - -# 【OCR】 -ocr: - # 【custom_ocr_url】: 默认使用 https://github.com/jxxghp/MoviePilot-OCR 自建OCR本地后端,用于辅助站点签到验证码识别,需要添加http/https,如果baidu ocr填写优先使用baidu - custom_ocr_url: - # 【baiduocr api key】: BaiduOCR的api key,如果需要正常使用,需要在申请后去 https://console.bce.baidu.com/ai/#/ai/ocr/overview/resource/getFree 领取免费额度 - baiduocr_api_key: - # 【baiduocr secret key】: BaiduOCR的secret key,如果需要正常使用,需要在申请后去 https://console.bce.baidu.com/ai/#/ai/ocr/overview/resource/getFree 领取免费额度 - baiduocr_secret key: - -# 【配置安全】 -security: - # 【媒体服务器webhook允许ip范围】:即只有如下范围的IP才允许调用webhook - media_server_webhook_allow_ip: - ipv4: 0.0.0.0/0 - ipv6: ::/0 - # 【Telegram webhook允许ip范围】:即只有如下范围的IP才允许调用webhook - telegram_webhook_allow_ip: - ipv4: 127.0.0.1 - ipv6: ::/0 - # 【Synology Chat webhook允许ip范围】:即只有如下范围的IP才允许调用webhook - synology_webhook_allow_ip: - ipv4: 127.0.0.1 - ipv6: ::/0 - # 【API认证密钥】:用于Jellyseerr、Overseerr中Authorization认证以及非客户端类的API调用 - api_key: - # 【是否验证apikey】:开启时需要在回调地址中传递api密钥进行验证,以增强安全性 - check_apikey: false - -# 【实验室】 -laboratory: - # 【识别增强】:关键字猜想 - search_keyword: false - # 【WEB识别增强】:通过TMDB WEB检索 - search_tmdbweb: false - # 【ChatGPT识别增强】通过ChatGPT识别文件名 - chatgpt_enable: false - # 【增强识别V2】:开启后会使用增强识别V2识别,优先级最高,关闭后将使用原版的识别方式识别 - recognize_enhance_enable: true - # 【TMDB缓存过期策略】:是否开启TMDB缓存过期策略,默认7天过期,过期缓存将被删除, 7天内访问过期时间可以被刷新 - tmdb_cache_expire: true - # 【默认搜索豆瓣资源】:开启将使用豆瓣进行电影电视剧的名称搜索,否则使用TMDB的数据 - use_douban_titles: false - # 【精确搜索使用英文名称】:开启后对于精确搜索场景(远程搜索、订阅搜索等)将会使用英文名检索站点资源以提升匹配度,但对有些站点资源标题全是中文的则需要关闭,否则匹配不到 - search_en_title: false - # 【显示更多内置站点】:开启后会展示更多内置站点,有些需要手动进行映射 - show_more_sites: true - # 【入库通知精简】:开启后会简化入库推送通知 - simplify_library_notification: false diff --git a/web/action.py b/web/action.py index b909af85..aad0d561 100644 --- a/web/action.py +++ b/web/action.py @@ -4076,6 +4076,25 @@ def __get_sub_path(data): for f in os.listdir("C:/")] else: dirs = [os.path.join("/", f) for f in os.listdir("/")] + elif d == "[SYNC-FOLDERS]": + sync_dirs = [] + for id, conf in Sync().get_sync_path_conf().items(): + sync_dirs.append(conf["from"]) + sync_dirs.append(conf["to"]) + dirs = list(set(sync_dirs)) + elif d == "[DOWNLOAD-FOLDERS]": + dirs = [path.rstrip('/') for path in Downloader().get_download_visit_dirs()] + elif d == "[MEDIA-FOLDERS]": + media_dirs = [] + movie_path = Config().get_config('media').get('movie_path') + tv_path = Config().get_config('media').get('tv_path') + anime_path = Config().get_config('media').get('anime_path') + unknown_path = Config().get_config('media').get('unknown_path') + if movie_path is not None: media_dirs.extend([path.rstrip('/') for path in movie_path]) + if tv_path is not None: media_dirs.extend([path.rstrip('/') for path in tv_path]) + if anime_path is not None: media_dirs.extend([path.rstrip('/') for path in anime_path]) + if unknown_path is not None: media_dirs.extend([path.rstrip('/') for path in unknown_path]) + dirs = list(set(media_dirs)) else: d = os.path.normpath(unquote(d)) if not os.path.isdir(d): @@ -4133,7 +4152,7 @@ def __get_hardlinks(data): def parse_hardlinks(hardlinks): paths = [] for link in hardlinks: - paths.append(SystemUtils.shorten_path(link["file"], 'left', 2)) + paths.append([SystemUtils.shorten_path(link["file"], 'left', 2), link["file"], link["filepath"]]) return paths r = {} diff --git a/web/main.py b/web/main.py index 13072cb8..6f5094c2 100644 --- a/web/main.py +++ b/web/main.py @@ -13,7 +13,7 @@ from pathlib import Path from threading import Lock from urllib import parse -from urllib.parse import unquote +from urllib.parse import quote, unquote from flask import Flask, request, json, render_template, make_response, session, send_from_directory, send_file, \ redirect, Response @@ -1053,11 +1053,49 @@ def do(): @App.route('/dirlist', methods=['POST']) @login_required def dirlist(): + def get_hardlink_info(folder): + """ + 获取硬链接信息 + """ + sync_class = "" + link_path = "" + link_direction = "" + sync_dirs = Sync().get_hardlinks_sync_dirs() + for dir in sync_dirs: + if folder.startswith(dir[0]): + if folder == dir[0]: + link_path = f'{SystemUtils.shorten_path(dir[1])}' + link_direction = '' + sync_class = "sync-src" + break + elif folder.startswith(dir[1]): + if folder == dir[1]: + link_path = f'{SystemUtils.shorten_path(dir[0])}' + link_direction = '' + sync_class = "sync-dest" + break + return sync_class, link_path, link_direction + + def get_media_dirs(): + media_dirs = [] + movie_path = Config().get_config('media').get('movie_path') + tv_path = Config().get_config('media').get('tv_path') + anime_path = Config().get_config('media').get('anime_path') + unknown_path = Config().get_config('media').get('unknown_path') + if movie_path is not None: media_dirs.extend([path.rstrip('/') for path in movie_path]) + if tv_path is not None: media_dirs.extend([path.rstrip('/') for path in tv_path]) + if anime_path is not None: media_dirs.extend([path.rstrip('/') for path in anime_path]) + if unknown_path is not None: media_dirs.extend([path.rstrip('/') for path in unknown_path]) + return list(set(media_dirs)) + + def get_download_dirs(): + return [path.rstrip('/') for path in Downloader().get_download_visit_dirs()] + r = ['