#可以下载pornhub 文件格式为 url-*-name
#20250509 直接使用url下载  
import os,time,subprocess,sys,tempfile,requests

#小于多少大小的内存
MEM_size = 50

processes = []

fork_pid = os.fork()  # 第一次 fork

if fork_pid > 0:
    sys.exit(0)  # 父进程退出，子进程继续运行

os.setsid()  # 创建新的会话，子进程 A 脱离控制终端

fork_pid = os.fork()  # 第二次 fork
if fork_pid > 0:
    sys.exit(0)  # 子进程 A 退出，确保没有父进程


print_file = open("down_output.log", "w", buffering=1)
sys.stdout = print_file
sys.stderr = print_file

with open('example_2.txt', 'r') as file:
    lines = file.readlines()
    for line in lines:
        raw_line = line
        url = line = line.split('\n')[0]

        url,name = line.split('-*-')
        print(name)
        try:
            with open(f'{name}.mp4'):
                print('文件存在')
                #continue
        except IOError as e:pass

        # 获取远程文件大小
        r = requests.head(url, allow_redirects=True)
        remote_size = int(r.headers.get("Content-Length", 0))

        try:
            # 获取本地文件大小
            local_size = os.path.getsize(f'{name}.mp4')
            print(f"响应码:{r.status_code} 远程文件大小 {remote_size} 本地文件大小 {local_size}   {name}")
            if remote_size == local_size:
                continue
        except FileNotFoundError:
            pass
        
        print(name)

        temp_files_obj = tempfile.NamedTemporaryFile(mode='w+', delete=True) 

        process = subprocess.Popen([
                                'nice', '-n', '19',
                                'curl',
                                "-L",
                                '-C', '-',   
                                '-H', 'accept: */*',
                                '-H', 'accept-language: zh-CN,zh;q=0.9,ja;q=0.8,ru;q=0.7',
                                '-H', 'cache-control: no-cache',
                                '-H', 'dnt: 1',
                                '-H', 'pragma: no-cache',
                                '-H', 'priority: i',

                                '-H', 'sec-ch-ua: "Chromium";v="124", "Google Chrome";v="124", "Not-A.Brand";v="99"',
                                '-H', 'sec-ch-ua-mobile: ?0',
                                '-H', 'sec-ch-ua-platform: "Windows"',

                                '-H', 'sec-fetch-dest: video',
                                '-H', 'sec-fetch-mode: no-cors',
                                '-H', 'sec-fetch-site: same-site',

                                '-H', 'user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36',

                                '-o', f'{name}.mp4',
                                url
                                ],        
                                    stdout=temp_files_obj,
                                    stderr=temp_files_obj,
                                    text=True
                                    )
        
        print(f'{temp_files_obj.name}')
        
        processes.append({'p':process,
                        'url':url,
                        'name':name,
                        'file':temp_files_obj})

        time.sleep(10)         

        while True:
            result = subprocess.run(['free', '-m'], stdout=subprocess.PIPE, text=True)
            # 解析命令输出
            for line in result.stdout.splitlines():
                if line.startswith('Mem'):
                    available = int(line.split()[6])  # 获取 available 字段，位于第 7 列
                    break
            #print(f'可分配内容容量 {available}M')
            if available > MEM_size:break
            print(f'可分配内存小于{MEM_size}M {available}M')
            time.sleep(20)
        
        for process in processes[:]:
            return_code = process['p'].poll()
            if return_code is not None:
                if return_code != 0:
                    print(f'进程异常退出 {process["name"]} {process["url"]} 返回值{return_code}\n')

                process['file'].close()
                processes.remove(process)

#当所有url已经创建下载 等待下载完成
while len(processes) > 0:
    for process in processes[:]:
        return_code = process['p'].poll()
        if return_code is not None:
            if return_code != 0:
                print(f'进程异常退出 {process["name"]} {process["url"]} 返回值{return_code}\n')

            process['file'].close()
            processes.remove(process)
    time.sleep(0.5)

print('全部完成...')
print_file.close()