File size: 7,064 Bytes
21f3395
8a7fd4e
 
 
 
 
 
 
 
 
 
e45342e
 
8a7fd4e
e45342e
18d567f
e45342e
 
 
21f3395
e45342e
8a7fd4e
 
 
 
 
 
 
 
 
 
 
d57f1c8
8a7fd4e
 
 
 
 
d57f1c8
8a7fd4e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5936f93
8a7fd4e
 
5936f93
8a7fd4e
 
 
 
 
 
d57f1c8
8a7fd4e
 
 
 
 
d57f1c8
8a7fd4e
 
5936f93
8a7fd4e
21f3395
8a7fd4e
 
5936f93
8a7fd4e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5936f93
8a7fd4e
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
import requests
from bs4 import BeautifulSoup
from concurrent.futures import ThreadPoolExecutor, as_completed
import re
import pypub
import os
import time  # Thư viện để tính thời gian
import gradio as gr  # Thêm thư viện Gradio

# Hàm để phân tích URL và tạo api_url và base_url
def parse_story_url(story_url):
    # Cố gắng tìm kiếm tên và ID truyện từ URL
    match = re.search(r"https://truyenfull\.tv/([^/]+)(?:-f\d+)?\.(\d+)/", story_url)
    if match:
        story_name = match.group(1)  # Trích xuất tên truyện
        story_id = match.group(3)     # Trích xuất ID truyện
        api_url = f"https://truyenfull.tv/api/chapters/{story_id}/"  # Tạo URL API
        base_url = f"https://truyenfull.tv/{story_name}/chuong-"  # Tạo URL cơ bản cho các chương
        return story_name, story_id, api_url, base_url  # Trả về thông tin đã trích xuất và tạo
    else:
        raise ValueError("URL không hợp lệ")  # Ném lỗi nếu định dạng URL không hợp lệ

# Hàm để lấy thông tin các chương từ API
def get_chapter_info(api_url):
    response = requests.get(api_url)
    response.raise_for_status()  # Ném lỗi nếu không thành công
    data = response.json()
    return data.get('items', [])

# Hàm để lấy nội dung của một chương dựa trên thứ tự chương
def get_chapter_content(chapter_index, base_url):
    chapter_url = base_url + str(chapter_index) + ".html"
    try:
        response = requests.get(chapter_url)
        response.raise_for_status()
        soup = BeautifulSoup(response.content, 'html.parser')
        content_div = soup.find('div', id='chapter-c', class_='chapter-c')
        return content_div.get_text(separator='\n').strip() if content_div else "Không tìm thấy nội dung chương."
    except Exception as e:
        print(f"Lỗi khi lấy nội dung chương {chapter_index}: {e}")
        return "Không thể lấy nội dung."

# Hàm để lấy nội dung tất cả các chương và lưu vào file
def get_all_chapters_content(story_url, start_chapter, max_chapters):
    story_name, story_id, api_url, base_url = parse_story_url(story_url)
    
    chapters = get_chapter_info(api_url)
    if not chapters:
        return "Không tìm thấy chương nào."

    # Giới hạn số chương tải xuống
    chapters_to_load = chapters[start_chapter - 1:start_chapter - 1 + max_chapters]
    chapter_contents = []  # Danh sách lưu nội dung các chương theo thứ tự
    total_time = 0  # Biến để tính tổng thời gian thực hiện từng chương

    # Sử dụng ThreadPoolExecutor để lấy nội dung các chương song song
    with ThreadPoolExecutor(max_workers=10) as executor:
        future_to_chapter = {executor.submit(get_chapter_content, idx + 1, base_url): idx + 1 for idx in range(len(chapters_to_load))}
        for future in as_completed(future_to_chapter):
            chapter_index = future_to_chapter[future]
            start_time = time.time()  # Bắt đầu đo thời gian cho mỗi chương
            try:
                content = future.result()
                # Lưu nội dung chương vào danh sách theo thứ tự
                chapter_contents.append((chapter_index, content, chapters[chapter_index - 1]['chapter_name']))  # Thêm tiêu đề chương
                print(f"Đã lưu chương {chapter_index}")
            except Exception as e:
                print(f"Lỗi khi lấy nội dung chương {chapter_index}: {e}")
            end_time = time.time()  # Kết thúc đo thời gian
            chapter_time = end_time - start_time
            total_time += chapter_time  # Cộng dồn thời gian cho mỗi chương
            print(f"Thời gian tải chương {chapter_index}: {chapter_time:.2f} giây")

    # Tính tổng thời gian và thời gian trung bình cho mỗi chương
    avg_time_per_chapter = total_time / max_chapters if max_chapters > 0 else 0
    print(f"Tổng thời gian tải {max_chapters} chương: {total_time:.2f} giây")
    print(f"Thời gian trung bình cho mỗi chương: {avg_time_per_chapter:.2f} giây")

    # Ghi nội dung các chương vào file theo thứ tự đã lưu
    chapter_contents.sort(key=lambda x: x[0])  # Sắp xếp theo chỉ số chương
    output_file = f"{story_name}.txt"
    with open(output_file, 'w', encoding='utf-8') as f:
        for chapter_index, content, chapter_title in chapter_contents:
            chapter_name = f"{chapter_title}"  # Tạo tên chương với tiêu đề
            f.write(f"{chapter_name}\n\n")
            f.write(f"{content}\n")
            f.write("-" * 50 + "\n")

    # Tạo file EPUB từ nội dung đã lưu
    epubfile=create_epub_from_chapters(chapter_contents, story_name)

    # Trả về kết quả
    return [f"Đã tải thành công {max_chapters} chương. Tổng thời gian: {total_time:.2f} giây, Thời gian trung bình: {avg_time_per_chapter:.2f} giây. File TXT: {output_file}",epubfile]

# Hàm để tạo file EPUB từ nội dung các chương
def create_epub_from_chapters(chapter_contents, story_name):
    try:
        # Tạo đối tượng Epub
        my_epub = pypub.Epub(story_name)

        # Thêm từng chương vào EPUB
        for chapter_index, content, chapter_title in chapter_contents:
            # Tạo chương từ nội dung đã có
            my_chapter = pypub.create_chapter_from_text(content, chapter_title)
            my_epub.add_chapter(my_chapter)

        # Lưu file EPUB
        output_directory = f"./{story_name}.epub"
        epubfile=my_epub.create(output_directory)  # Lưu file EPUB
        print(f"Đã tạo file EPUB: {output_directory}")

    except Exception as e:
        print(f"Lỗi khi tạo file EPUB: {e}")
    return epubfile
# Giao diện Gradio
def gradio_interface(story_url, start_chapter, max_chapters):
    # Bắt đầu đo thời gian cho toàn bộ quá trình
    start_total_time = time.time()

    # Gọi hàm tải và xử lý nội dung
    result = get_all_chapters_content(story_url, int(start_chapter), int(max_chapters))

    # Kết thúc đo thời gian
    end_total_time = time.time()

    # Tính tổng thời gian cho toàn bộ quá trình
    total_process_time = end_total_time - start_total_time
    result += f"\nTổng thời gian hoàn thành tất cả các chức năng: {total_process_time:.2f} giây"
    return result

# Tạo giao diện với Gradio
gr.Interface(
    fn=gradio_interface,
    inputs=[
        gr.Textbox(label="URL Truyện", placeholder="Nhập URL của truyện từ truyenfull.tv"),
        gr.Textbox(label="Số chương bắt đầu", placeholder="Nhập số chương bắt đầu"),
        gr.Textbox(label="Số chương muốn tải", placeholder="Nhập số chương muốn tải")
    ],
    outputs=["text","file"],
    title="Truyện Full Downloader",
    description="Công cụ tải truyện từ truyenfull.tv và tạo file EPUB."
).launch()