Тоже искал ридер для FB2, нечего путного не нашёл. Установил Komga, она читает EPUB,PDF и комиксы(не использую). С помощью ChatGPT написал утилиту для (автоматизации) конвертации FB2->EPUB на python. Для этого требуется Calibre, я использую portable-версию. Из недостатков - конвертирует оч долго, 3,5 гб fb2 обрабатывала около 10 часов, всю ночь.
использвать так:
PS C:\Users\user> python.exe .\convert_fb2_to_epub.py --calibre-path="d:\\Calibre Portable\\Calibre\\ebook-convert.exe" --input-dir="d:\\Downloads\\temp\\Евгений Лисицин_Дорничев Дмитрий_Меж двух миров_Имя нам Легион\\"
Не знаю как прикрепить файл!
вставляю так.
convert_fb2_to_epub.py
import os
import subprocess
import argparse
def main():
# Парсинг аргументов командной строки
parser = argparse.ArgumentParser(description="Convert FB2 files to EPUB using Calibre")
parser.add_argument(
"--calibre-path",
required=True,
help="Path to ebook-convert.exe (e.g., E:\\calibre\\Calibre Portable\\Calibre\\ebook-convert.exe)",
)
parser.add_argument(
"--input-dir",
required=True,
help="Directory containing FB2 files (e.g., E:\\torrent\\Фабер Ник)",
)
args = parser.parse_args()
CALIBRE_PATH = os.path.normpath(args.calibre_path)
INPUT_DIR = os.path.normpath(args.input_dir)
# Проверка существования ebook-convert.exe
if not os.path.isfile(CALIBRE_PATH):
print(f"Ошибка: ebook-convert.exe не найден в {CALIBRE_PATH}")
input("Нажмите Enter для выхода...")
return
# Проверка существования папки
if not os.path.isdir(INPUT_DIR):
print(f"Ошибка: Папка {INPUT_DIR} не существует")
input("Нажмите Enter для выхода...")
return
# Поиск FB2-файлов во всех подпапках
fb2_files = []
print(f"Поиск FB2-файлов в {INPUT_DIR} и подпапках...")
for root, _, files in os.walk(INPUT_DIR):
print(f"Проверяю папку: {root}")
for file in files:
if file.lower().endswith(".fb2"):
fb2_files.append(os.path.join(root, file))
if not fb2_files:
print(f"Ошибка: FB2-файлы не найдены в {INPUT_DIR} и ее подпапках")
with open(os.path.join(INPUT_DIR, "file_list.txt"), "w", encoding="utf-8") as f:
for root, _, files in os.walk(INPUT_DIR):
for file in files:
f.write(os.path.join(root, file) + "\n")
print(f"Список файлов сохранен в {os.path.join(INPUT_DIR, 'file_list.txt')}")
input("Нажмите Enter для выхода...")
return
# Конвертация файлов
count = 0
skipped = 0
for fb2_file in fb2_files:
output_file = os.path.splitext(fb2_file)[0] + ".epub"
log_file = os.path.splitext(fb2_file)[0] + ".log"
# Проверка существования EPUB-файла
if os.path.isfile(output_file):
print(f"Пропущен: {output_file} уже существует")
skipped += 1
continue
print(f"Конвертирую: {fb2_file}")
try:
# Вызов ebook-convert
result = subprocess.run(
[
CALIBRE_PATH,
fb2_file,
output_file,
"--enable-heuristics",
"--preserve-cover",
"--verbose",
],
capture_output=True,
text=True,
encoding="utf-8",
)
# Сохранение лога
with open(log_file, "w", encoding="utf-8") as f:
f.write(result.stdout)
f.write(result.stderr)
if result.returncode == 0:
print(f"Успешно конвертирован: {output_file}")
count += 1
else:
print(f"Ошибка при конвертации: {fb2_file}. Подробности в {log_file}")
except Exception as e:
print(f"Ошибка при конвертации {fb2_file}: {str(e)}")
with open(log_file, "w", encoding="utf-8") as f:
f.write(str(e))
# Итоговое сообщение
print()
if count > 0:
print(f"Конвертация завершена. Обработано файлов: {count}, пропущено: {skipped}")
else:
print(f"Конвертация не выполнена. Пропущено файлов: {skipped}. Проверьте файлы и пути.")
input("Нажмите Enter для выхода...")
if __name__ == "__main__":
main()
вдруг кому пригодиться