import gradio as gr import re import os import base64 import time from datetime import datetime, timedelta, timezone # 設定 SUPPORT_URL = "https://github.com/X1288664/LINE-Log-Manager-for-Hugging-face/blob/main/README.md" HELP_URL = "https://github.com/X1288664/LINE-Log-Manager-for-Hugging-face/blob/Q%26A/README.md" COPYRIGHT_URL = "https://github.com/X1288664/LINE-Log-Manager-for-Hugging-face/blob/copyright/README.md" CONTACT_URL = "https://forms.gle/mAUj1CdhufHFbiWs7" TS_URL = "https://github.com/X1288664/LINE-Log-Manager-for-Hugging-face/blob/troubleshooting/README.md" MANUAL_URL = "https://youtu.be/j2GJtO5BydA" JST = timezone(timedelta(hours=9)) def load_log_file(file, progress=gr.Progress()): """ログファイルを読み込む(プログレスバー付き)""" if not file: return None, "エラー(FILE-001): ファイルが選択されていません。" if not file.name.endswith(".txt"): return None, "エラー(FILE-005): TXTファイルを選択してください。" try: with open(file.name, "r", encoding="utf-8") as f: content = f.readlines() for _ in progress.tqdm(range(1, 101), desc="ログファイルを読み込み中..."): time.sleep(0.01) return content, None except Exception as e: return None, f"エラー(FILE-002): ファイルの読み込みに失敗しました ({str(e)})" def extract_date_range_logs(lines, start_date, end_date): """指定された日付範囲のログを抽出""" results = [] current_date = None for line in lines: date_match = re.match(r"(\d{4}/\d{1,2}/\d{1,2})", line) if date_match: try: current_date = datetime.strptime(date_match.group(1), "%Y/%m/%d") except ValueError: continue # 無効な日付フォーマットはスキップ if current_date and start_date <= current_date < end_date: results.append(line.strip()) return results def search_logs(file, keyword, year, month, day, progress=gr.Progress()): """ログ検索(プログレスバー付き)""" log_lines, error = load_log_file(file) if error: return "", error, None if not log_lines: return "", "エラー(FILE-003): ファイルが空です。", None is_word_search = bool(keyword.strip()) is_date_search = year != "----" and month != "----" and day != "----" if is_word_search and is_date_search: return "", "エラー(SEARCH-001): ワード検索と日付検索は同時に行えません。", None search_condition = "検索条件: なし" results = [] if is_word_search: search_condition = f"検索条件: ワード[{keyword}]" for line in progress.tqdm(log_lines, desc="検索中..."): if keyword in line: results.append(f"- {line.strip()}") elif is_date_search: try: search_date = f"{year}/{month}/{day}" start_date = datetime.strptime(search_date, "%Y/%m/%d") end_date = start_date + timedelta(days=1) search_condition = f"検索条件: 日付[{search_date}]" results = extract_date_range_logs(log_lines, start_date, end_date) results = [f"- {line.strip()}" for line in results] except ValueError: return "", "エラー(SEARCH-002): 無効な日付形式です。", None formatted_results = "\n".join(results) if results else "エラー(SEARCH-003): 一致する結果が見つかりませんでした。" return formatted_results, f"{len(results)} 件の結果が見つかりました。", search_condition def generate_download_link(results, search_condition, progress=gr.Progress()): """エクスポート処理(プログレスバー付き)""" if not results: return "エラー(EXPORT-001): エクスポートするデータがありません。" execution_time = datetime.now(JST).strftime("%Y%m%d_%H%M%S") JPN_date = datetime.now(JST).strftime("%Y/%m/%d %H:%M:%S") if "ワード" in search_condition: condition_text = search_condition.replace("検索条件: ワード[", "").replace("]", "").replace(" ", "_") elif "日付" in search_condition: condition_text = search_condition.replace("検索条件: 日付[", "").replace("]", "").replace("/", "_") else: condition_text = "検索条件なし" file_name = f"{execution_time}_LINE-Log-Manager-search-Export-{condition_text}.txt" file_content = ( "プログラム名: LINEログマネージャー\n" f"検索実行日: {JPN_date}\n" f"{search_condition}\n" f"ヒット件数: {len(results.splitlines())} 件\n" + "-" * 40 + "\n" + results + "\n" ) encoded_file = base64.b64encode(file_content.encode()).decode() for _ in progress.tqdm(range(1, 101), desc="エクスポート処理中..."): time.sleep(0.01) href = f'結果をダウンロード' return href with gr.Blocks() as demo: gr.HTML("