import requests
import time
import os
import random
from datetime import datetime
import json

# 定义输出文件名
output_file = 'tvmao.xml'

# 如果文件存在，先删除再重建
if os.path.exists(output_file):
    os.remove(output_file)

# 初始化 XML 文件，写入根节点
with open(output_file, 'w', encoding='utf-8') as file:
    file.write('<?xml version="1.0" encoding="UTF-8"?>\n<tv>\n</tv>\n')

# 频道替换表
channel_replace_map = {
    "CCTV-1综合": "CCTV1",
    "CCTV-2财经": "CCTV2",
    "CCTV-3综艺": "CCTV3",
    "CCTV-4中文国际": "CCTV4",
    "CCTV-5体育": "CCTV5",
    "CCTV-6电影": "CCTV6",
    "CCTV-7国防军事": "CCTV7",
    "CCTV-8电视剧": "CCTV8",
    "CCTV-9记录": "CCTV9",
    "CCTV-10科教": "CCTV10",
    "CCTV-11戏曲": "CCTV11",
    "CCTV-12社会与法": "CCTV12",
    "CCTV-13新闻": "CCTV13",
    "CCTV-14少儿": "CCTV14",
    "CCTV-15音乐": "CCTV15",
    "CCTV5加": "CCTV5+"
}

# 从 tvmao.txt 中读取内容并进行过滤
with open('tvmao.txt', 'r', encoding='utf-8') as f:
    # 筛选需要的频道
    lines = [line for line in f.readlines() if any(keyword in line for keyword in ['CCTV', '卫视', '河南', '南阳'])]

# 记录总任务数
total_tasks = len(lines)
current_task = 0

def log_message(message):
    """带时间戳的日志输出函数"""
    current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    print(f"[{current_time}] {message}")

def remove_last_line(file_path):
    """删除文件的最后一行"""
    with open(file_path, 'r+', encoding='utf-8') as file:
        lines = file.readlines()
        if lines:
            file.seek(0)
            file.writelines(lines[:-1])  # 删除最后一行
            file.truncate()

for line in lines:
    # 记录当前任务编号
    current_task += 1
    
    # 获取 # 左侧的 tvmaoid
    tvmaoid = line.split('#')[0].strip()
    
    # 构建 URL
    url = f'https://lighttv.tvmao.com/qa/qachannelschedule?epgCode={tvmaoid}&op=getProgramByChnid&epgName=&isNew=on&day='

    retry_count = 0  # 重试计数
    
    while True:
        try:
            log_message(f"Processing task {current_task}/{total_tasks}: tvmaoid = {tvmaoid}")
            
            # 发送请求
            response = requests.get(url)
            response.raise_for_status()  # 检查请求是否成功
            
            response_text = response.text.strip()
            
            # 检测响应内容是否为空或错误
            if response_text == '[0,""]':
                retry_count += 1
                wait_time = 120 * retry_count  # 每次重试后增加等待时间
                log_message(f"[Retry {retry_count}] Empty response for tvmaoid: {tvmaoid}, retrying in {wait_time} seconds...")
                time.sleep(wait_time)  # 等待重试的时间
                continue  # 重新获取当前tvmaoid

            elif response_text == '[0,"数据库错误，请重试","peace.org.tm.web.servlet.quickapp.ChannelScheduleServlet:servlet error!java.lang.NullPointerException"]':
                log_message(f"Error detected for tvmaoid: {tvmaoid}. Skipping this id...")
                break  # 跳过当前tvmaoid，不再重试

            else:
                # 删除 XML 文件的最后一行
                remove_last_line(output_file)

                # 解析 JSON 数据
                parsed_data = json.loads(response_text)
                programmes = parsed_data[2]['pro']  # 获取节目列表
                channel_name = parsed_data[2]['epgName']  # 获取频道名称
                
                # 检查频道名称是否在替换表中，并替换
                if channel_name in channel_replace_map:
                    channel_name = channel_replace_map[channel_name]

                date_str = '2024' + parsed_data[2]['week'][0]['date'].replace('.', '')  # 获取日期并格式化

                # 构建 XML 节点并追加到 tvmao.xml 文件中
                with open(output_file, 'a', encoding='utf-8') as file:
                    # 写入 channel 信息
                    file.write(f'<channel id="{channel_name}">\n')
                    file.write(f'    <display-name lang="zh">{channel_name}</display-name>\n')
                    file.write('</channel>\n')

                    for i in range(len(programmes)):
                        programme = programmes[i]

                        # 计算开始时间
                        start_time = datetime.strptime(f'{date_str}{programme["time"]}', "%Y%m%d%H:%M")

                        if i < len(programmes) - 1:
                            # 获取下一个节目的开始时间作为当前节目的结束时间
                            next_programme = programmes[i + 1]
                            stop_time = datetime.strptime(f'{date_str}{next_programme["time"]}', "%Y%m%d%H:%M")
                        else:
                            # 如果是最后一个节目，结束时间为当天的 23:59
                            stop_time = start_time.replace(hour=23, minute=59)

                        # 构建 XML 节点，确保正确格式化
                        xml_node = (
                            f'<programme start="{start_time.strftime("%Y%m%d%H%M%S")} +0800" '
                            f'stop="{stop_time.strftime("%Y%m%d%H%M%S")} +0800" channel="{channel_name}">\n'
                            f'    <title lang="zh">{programme["name"]}</title>\n'
                            '</programme>\n'
                        )
                        
                        # 追加写入 XML 文件
                        file.write(xml_node)

                    # 重新添加 </tv> 标签，确保 XML 文件完整
                    file.write('</tv>\n')

            break  # 跳出 while 循环，继续处理下一个 tvmaoid
        
        except requests.exceptions.RequestException as e:
            log_message(f"Failed to retrieve data for tvmaoid: {tvmaoid}. Error: {e}")
            break

    # 控制请求速度，生成 9 到 12 秒之间的随机浮点数时间
    sleep_time = random.uniform(9, 12)
    log_message(f"Waiting for {sleep_time:.2f} seconds before next request...\n")
    time.sleep(sleep_time)
    

log_message("任务完成。")
