テキストファイルを読み込み ollamaでGoogleカレンダーに送れる形式にする

テキストファイルを読み込み ollamaでGoogleカレンダーに送れる形式にする

PDFからテキストと抽出するので

pip install pdf2image pytesseract

Tesseract OCRのインストール

brew install tesseract

日本語言語データを追加

brew install tesseract-lang

とりあえずここまではOK

以前PDFの内容の取り出しはしたことがあるので
肝心の文章から予定を ollamaで取り出しを行う

テキストから日時とイベント情報を抽出します。今回のテキストでは、日付が「10月7日~10月15日」や「10月25日(金)」のように記載されています。これらを正規表現とdateparserライブラリで解析する

pip install dateparser

PDFの前に
テキストファイルの読み込み
テキストをOllamaで解析し、日時と予定を抽出
GoogleカレンダーAPIを使って予定を追加
を行うようにする

これはメールでお知らせすることがあるため

def read_text_file(file_path):
    with open(file_path, 'r', encoding='utf-8') as file:
        text = file.read()
    return text

# 使用例
text_file_path = 'school_notice.txt'  # テキストファイルのパス
text_content = read_text_file(text_file_path)

でテキストファイルを読み込む

Ollamaを使用してテキストを解析し、日時とイベント情報を抽出
PythonからOllamaを呼び出す
Ollamaがローカルで動作している前提で、requestsライブラリを使用してHTTPリクエストを送信

import requests
import json

def parse_text_with_ollama(text):
    # OllamaのAPIエンドポイント
    ollama_url = 'http://localhost:11434/generate'

    # Ollamaに送信するプロンプトを作成
    prompt = f"""
以下の文章から、日時とそれに対応する予定を抽出してください。結果はJSON形式で、"date"と"event"のキーを持つオブジェクトのリストとして返してください。

文章:
{text}

出力例:
[
    {{"date": "2024-10-07", "event": "ペットボトルの準備"}},
    {{"date": "2024-10-25", "event": "準備物の確認"}}
]
"""

    payload = {
        'model': 'your-ollama-model-name',  # 使用するOllamaモデルの名前
        'prompt': prompt
    }

    response = requests.post(ollama_url, json=payload)
    response_text = response.text

    # Ollamaの出力からJSON部分を抽出
    try:
        start_index = response_text.index('[')
        end_index = response_text.rindex(']') + 1
        json_str = response_text[start_index:end_index]
        events = json.loads(json_str)
    except (ValueError, json.JSONDecodeError) as e:
        print("Ollamaからのレスポンスの解析に失敗しました:", e)
        events = []

    return events

# 使用例
events = parse_text_with_ollama(text_content)
print("抽出されたイベント:", events)


抽出されたイベントをGoogleカレンダーに追加
import os
from datetime import datetime, timedelta
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build

def add_events_to_calendar(events):
    SCOPES = ['https://www.googleapis.com/auth/calendar']
    creds = None
    if os.path.exists('token.json'):
        creds = Credentials.from_authorized_user_file('token.json', SCOPES)
    else:
        print("token.json が見つかりません。認証を実行してください。")
        return

    service = build('calendar', 'v3', credentials=creds)

    for event in events:
        # 日付の形式を確認し、必要に応じて変換
        try:
            event_date = datetime.strptime(event['date'], '%Y-%m-%d')
        except ValueError:
            print(f"無効な日付形式: {event['date']}")
            continue

        event_body = {
            'summary': event['event'],
            'start': {
                'date': event_date.strftime('%Y-%m-%d'),
                'timeZone': 'Asia/Tokyo',
            },
            'end': {
                'date': (event_date + timedelta(days=1)).strftime('%Y-%m-%d'),
                'timeZone': 'Asia/Tokyo',
            },
        }

        # イベントをカレンダーに追加
        created_event = service.events().insert(calendarId='primary', body=event_body).execute()
        print(f"イベントが作成されました: {created_event.get('htmlLink')}")

# 使用例
add_events_to_calendar(events)

これらを

import os
import requests
import json
from datetime import datetime, timedelta
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build

def read_text_file(file_path):
    with open(file_path, 'r', encoding='utf-8') as file:
        text = file.read()
    return text

def parse_text_with_ollama(text):
    # OllamaのAPIエンドポイント
    ollama_url = 'http://localhost:11434/generate'

    # Ollamaに送信するプロンプトを作成
    prompt = f"""
以下の文章から、日時とそれに対応する予定を抽出してください。結果はJSON形式で、"date"と"event"のキーを持つオブジェクトのリストとして返してください。

文章:
{text}

出力例:
[
    {{"date": "2024-10-07", "event": "ペットボトルの準備"}},
    {{"date": "2024-10-25", "event": "準備物の確認"}}
]
"""

    payload = {
        'model': 'your-ollama-model-name',  # 使用するOllamaモデルの名前
        'prompt': prompt
    }

    response = requests.post(ollama_url, json=payload)
    response_text = response.text

    # Ollamaの出力からJSON部分を抽出
    try:
        start_index = response_text.index('[')
        end_index = response_text.rindex(']') + 1
        json_str = response_text[start_index:end_index]
        events = json.loads(json_str)
    except (ValueError, json.JSONDecodeError) as e:
        print("Ollamaからのレスポンスの解析に失敗しました:", e)
        events = []

    return events

def add_events_to_calendar(events):
    SCOPES = ['https://www.googleapis.com/auth/calendar']
    creds = None
    if os.path.exists('token.json'):
        creds = Credentials.from_authorized_user_file('token.json', SCOPES)
    else:
        print("token.json が見つかりません。認証を実行してください。")
        return

    service = build('calendar', 'v3', credentials=creds)

    for event in events:
        # 日付の形式を確認し、必要に応じて変換
        try:
            event_date = datetime.strptime(event['date'], '%Y-%m-%d')
        except ValueError:
            print(f"無効な日付形式: {event['date']}")
            continue

        event_body = {
            'summary': event['event'],
            'start': {
                'date': event_date.strftime('%Y-%m-%d'),
                'timeZone': 'Asia/Tokyo',
            },
            'end': {
                'date': (event_date + timedelta(days=1)).strftime('%Y-%m-%d'),
                'timeZone': 'Asia/Tokyo',
            },
        }

        # イベントをカレンダーに追加
        created_event = service.events().insert(calendarId='primary', body=event_body).execute()
        print(f"イベントが作成されました: {created_event.get('htmlLink')}")

# メインの実行部分
text_file_path = 'school_notice.txt'  # テキストファイルのパス
text_content = read_text_file(text_file_path)
events = parse_text_with_ollama(text_content)
print("抽出されたイベント:", events)
add_events_to_calendar(events)

というように1つにすることもできるが
検証と後で他でも使えるように
モジュールにして他でも使えるようにしたい

calendar_module.py

read_text_file(file_path)
parse_text_with_ollama(text, model_name)
add_events_to_calendar(events, calendar_id='primary', token_file='token.json')

を入れる

touch calendar_module.py

でファイルを作成

import os
import requests
import json
from datetime import datetime, timedelta
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build

def read_text_file(file_path):
    """テキストファイルを読み込み、その内容を文字列として返します。"""
    with open(file_path, 'r', encoding='utf-8') as file:
        text = file.read()
    return text

def parse_text_with_ollama(text, model_name='your-ollama-model-name'):
    """
    Ollamaを使用してテキストから日時とイベントを抽出します。

    Args:
        text (str): 解析するテキスト。
        model_name (str): 使用するOllamaモデルの名前。

    Returns:
        list: 抽出されたイベントのリスト。
    """
    # OllamaのAPIエンドポイント
    ollama_url = 'http://localhost:11434/generate'

    # Ollamaに送信するプロンプトを作成
    prompt = f"""
以下の文章から、日時とそれに対応する予定を抽出してください。結果はJSON形式で、"date"と"event"のキーを持つオブジェクトのリストとして返してください。

文章:
{text}

出力例:
[
    {{"date": "2024-10-07", "event": "ペットボトルの準備"}},
    {{"date": "2024-10-25", "event": "準備物の確認"}}
]
"""

    payload = {
        'model': model_name,
        'prompt': prompt
    }

    response = requests.post(ollama_url, json=payload)
    response_text = response.text

    # Ollamaの出力からJSON部分を抽出
    try:
        start_index = response_text.index('[')
        end_index = response_text.rindex(']') + 1
        json_str = response_text[start_index:end_index]
        events = json.loads(json_str)
    except (ValueError, json.JSONDecodeError) as e:
        print("Ollamaからのレスポンスの解析に失敗しました:", e)
        events = []

    return events

def add_events_to_calendar(events, calendar_id='primary', token_file='token.json'):
    """
    抽出されたイベントをGoogleカレンダーに追加します。

    Args:
        events (list): イベントのリスト。
        calendar_id (str): イベントを追加するカレンダーのID。
        token_file (str): 認証トークンファイルのパス。
    """
    SCOPES = ['https://www.googleapis.com/auth/calendar']
    creds = None
    if os.path.exists(token_file):
        creds = Credentials.from_authorized_user_file(token_file, SCOPES)
    else:
        print(f"{token_file} が見つかりません。認証を実行してください。")
        return

    service = build('calendar', 'v3', credentials=creds)

    for event in events:
        # 日付の形式を確認し、必要に応じて変換
        try:
            event_date = datetime.strptime(event['date'], '%Y-%m-%d')
        except ValueError:
            print(f"無効な日付形式: {event['date']}")
            continue

        event_body = {
            'summary': event['event'],
            'start': {
                'date': event_date.strftime('%Y-%m-%d'),
                'timeZone': 'Asia/Tokyo',
            },
            'end': {
                'date': (event_date + timedelta(days=1)).strftime('%Y-%m-%d'),
                'timeZone': 'Asia/Tokyo',
            },
        }

        # イベントをカレンダーに追加
        created_event = service.events().insert(calendarId=calendar_id, body=event_body).execute()
        print(f"イベントが作成されました: {created_event.get('htmlLink')}")

として保存

モジュールを作成したら、別のスクリプトからインポートして使用

 touch main.py

でファイルを作成

from calendar_module import read_text_file, parse_text_with_ollama, add_events_to_calendar

# テキストファイルのパス
text_file_path = 'school_notice.txt'  # 処理するテキストファイルのパス

# テキストの読み込み
text_content = read_text_file(text_file_path)

# Ollamaでテキストを解析(モデル名を指定)
events = parse_text_with_ollama(text_content, model_name='your-ollama-model-name')

# 抽出されたイベントを表示
print("抽出されたイベント:", events)

# Googleカレンダーにイベントを追加
add_events_to_calendar(events, calendar_id='primary', token_file='token.json')

とする

ただし今回はテストなので
とりあえずカレンダーにイベントを追加する部分はコメントアウトし
まずは Ollamaの結果を見る

またモデルには
parse_text_with_ollama関数内のモデル名をelyzaに変更
model_name引数のデフォルト値をelyza:jp8bに設定

ということで

import os
import requests
import json
from datetime import datetime, timedelta
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build

def read_text_file(file_path):
    """テキストファイルを読み込み、その内容を文字列として返します。"""
    with open(file_path, 'r', encoding='utf-8') as file:
        text = file.read()
    return text

def parse_text_with_ollama(text, model_name='elyza:jp8b'):
    """
    Ollamaを使用してテキストから日時とイベントを抽出します。

    Args:
        text (str): 解析するテキスト。
        model_name (str): 使用するOllamaモデルの名前(デフォルトは 'elyza:jp8b')。

    Returns:
        list: 抽出されたイベントのリスト。
    """
    # OllamaのAPIエンドポイント
    ollama_url = 'http://localhost:11434/generate'

    # Ollamaに送信するプロンプトを作成
    prompt = f"""
以下の文章から、日時とそれに対応する予定を抽出してください。結果はJSON形式で、"date"と"event"のキーを持つオブジェクトのリストとして返してください。

文章:
{text}

出力例:
[
    {{"date": "2024-10-07", "event": "ペットボトルの準備"}},
    {{"date": "2024-10-25", "event": "準備物の確認"}}
]
"""

    payload = {
        'model': model_name,
        'prompt': prompt
    }

    response = requests.post(ollama_url, json=payload)
    response_text = response.text

    # Ollamaの出力からJSON部分を抽出
    try:
        # レスポンスをJSONとして直接パース
        events = json.loads(response_text.strip())
    except json.JSONDecodeError:
        try:
            # JSON部分のみを抽出
            start_index = response_text.index('[')
            end_index = response_text.rindex(']') + 1
            json_str = response_text[start_index:end_index]
            events = json.loads(json_str)
        except (ValueError, json.JSONDecodeError) as e:
            print("Ollamaからのレスポンスの解析に失敗しました:", e)
            events = []

    return events

def add_events_to_calendar(events, calendar_id='primary', token_file='token.json'):
    """
    抽出されたイベントをGoogleカレンダーに追加します。

    Args:
        events (list): イベントのリスト。
        calendar_id (str): イベントを追加するカレンダーのID。
        token_file (str): 認証トークンファイルのパス。
    """
    SCOPES = ['https://www.googleapis.com/auth/calendar']
    creds = None
    if os.path.exists(token_file):
        creds = Credentials.from_authorized_user_file(token_file, SCOPES)
    else:
        print(f"{token_file} が見つかりません。認証を実行してください。")
        return

    service = build('calendar', 'v3', credentials=creds)

    for event in events:
        # 日付の形式を確認し、必要に応じて変換
        try:
            event_date = datetime.strptime(event['date'], '%Y-%m-%d')
        except ValueError:
            print(f"無効な日付形式: {event['date']}")
            continue

        event_body = {
            'summary': event['event'],
            'start': {
                'date': event_date.strftime('%Y-%m-%d'),
                'timeZone': 'Asia/Tokyo',
            },
            'end': {
                'date': (event_date + timedelta(days=1)).strftime('%Y-%m-%d'),
                'timeZone': 'Asia/Tokyo',
            },
        }

        # イベントをカレンダーに追加
        created_event = service.events().insert(calendarId=calendar_id, body=event_body).execute()
        print(f"イベントが作成されました: {created_event.get('htmlLink')}")

というように

calendar_module.py

を変更

またmain.pyを

from calendar_module import read_text_file, parse_text_with_ollama, add_events_to_calendar

# テキストファイルのパス
text_file_path = 'school_notice.txt'  # 処理するテキストファイルのパス

# テキストの読み込み
text_content = read_text_file(text_file_path)

# Ollamaでテキストを解析(モデル名を指定)
events = parse_text_with_ollama(text_content, model_name='elyza:jp8b')

# 抽出されたイベントを表示
print("抽出されたイベント:", events)

# Googleカレンダーにイベントを追加
#add_events_to_calendar(events, calendar_id='primary', token_file='token.json')

としておく

touch school_notice.txt

でテキストを
学校からのお知らせ内容をテキストファイルにして実験

しかし

Ollamaからのレスポンスの解析に失敗しました: substring not found
抽出されたイベント: []

となってしまう

機能を分割して問題を探す

以前のコードを見たらリクエストURLが

response = requests.post("http://localhost:11434/api/generate", 

なので

ollama_url = 'http://localhost:11434/api/generate'

に修正

import requests
import json

def parse_text_with_ollama(text, model_name='elyza/jp8b'):
    """
    Ollamaを使用してテキストから日時とイベントを抽出します。

    Args:
        text (str): 解析するテキスト。
        model_name (str): 使用するOllamaモデルの名前(デフォルトは 'elyza/jp8b')。

    Returns:
        list: 抽出されたイベントのリスト。
    """
    # OllamaのAPIエンドポイント(修正)
    ollama_url = 'http://localhost:11434/api/generate'

    # Ollamaに送信するプロンプトを作成
    prompt = f"""
以下の文章から、日時とそれに対応する予定を抽出してください。結果はJSON形式で、"date"と"event"のキーを持つオブジェクトのリストとして返してください。

文章:
{text}

出力例:
[
    {{"date": "2024-10-07", "event": "ペットボトルの準備"}},
    {{"date": "2024-10-25", "event": "準備物の確認"}}
]
"""

    payload = {
        'model': model_name,
        'prompt': prompt
    }

    try:
        response = requests.post(ollama_url, json=payload)
        response.raise_for_status()
        # レスポンスをJSONとしてパース
        response_json = response.json()
        # テキスト部分を取得
        response_text = response_json.get('response', '')
    except requests.exceptions.RequestException as e:
        print("Ollamaへのリクエストに失敗しました:", e)
        return []
    except json.JSONDecodeError as e:
        print("OllamaからのレスポンスがJSON形式ではありません:", e)
        return []

    # Ollamaの出力からJSON部分を抽出
    try:
        start_index = response_text.index('[')
        end_index = response_text.rindex(']') + 1
        json_str = response_text[start_index:end_index]
        events = json.loads(json_str)
    except (ValueError, json.JSONDecodeError) as e:
        print("Ollamaからのレスポンスの解析に失敗しました:", e)
        events = []

    return events

とした

しかし

Ollamaからのレスポンスの解析に失敗しました: Expecting value: line 1 column 2 (char 1)
抽出されたイベント:

となる

ChatGGPTで情報を調べると以下の方になる

Ollamaはストリーミング形式でレスポンスを返しています。
つまり、モデルの生成結果が複数のJSONオブジェクトとして順次送られてきています

{“model”:”elyza:jp8b”,”created_at”:”…”,”response”:”…”,”done”:false}

この”response”フィールドに、モデルが生成したテキストの一部が含まれています。全体のレスポンスを組み立てるには、これらの”response”フィールドを順番に連結する必要があります

requestsライブラリを使用して、ストリーミングレスポンスを処理します。response.iter_lines()を使用して、各行を逐次処理

各行をJSONとしてパースし、”response”フィールドの値を取り出して連結

連結したテキストがJSON文字列(リスト)であることを前提に、json.loads()でパース

となるようにコード変更

import requests
import json

def parse_text_with_ollama(text, model_name='elyza:jp8b'):
    """
    Ollamaを使用してテキストから日時とイベントを抽出します。

    Args:
        text (str): 解析するテキスト。
        model_name (str): 使用するOllamaモデルの名前。

    Returns:
        list: 抽出されたイベントのリスト。
    """
    # OllamaのAPIエンドポイント
    ollama_url = 'http://localhost:11434/api/generate'

    # Ollamaに送信するプロンプトを作成
    prompt = f"""
以下の文章から、日付とそれに対応する予定を抽出してください。結果は純粋なJSON形式で、日本語で、"date"と"event"のキーを持つオブジェクトのリストとして返してください。

文章:
{text}

出力例:
[
    {{"date": "2024-10-07", "event": "ペットボトルの準備"}},
    {{"date": "2024-10-25", "event": "準備物の確認"}}
]

重要事項:
- 出力は純粋なJSON形式で、追加のテキストや説明は含めないでください。
- 日付は"YYYY-MM-DD"の形式で出力してください。
- イベント名は元の文章から適切に抽出してください。
"""

    payload = {
        'model': model_name,
        'prompt': prompt
    }

    try:
        # ストリーミングレスポンスを取得
        response = requests.post(ollama_url, json=payload, stream=True)
        response.raise_for_status()

        # レスポンスのストリームを処理
        response_text = ''
        for line in response.iter_lines():
            if line:
                line_str = line.decode('utf-8')
                # 各行をJSONとしてパース
                line_json = json.loads(line_str)
                # "response"フィールドを連結
                response_text += line_json.get('response', '')

        print("Ollamaのレスポンス:")
        print(response_text)
    except requests.exceptions.RequestException as e:
        print("Ollamaへのリクエストに失敗しました:", e)
        return []
    except json.JSONDecodeError as e:
        print("レスポンスの解析に失敗しました:", e)
        return []

    # 連結したテキストをJSONとして解析
    try:
        events = json.loads(response_text)
    except json.JSONDecodeError as e:
        print("Ollamaからのレスポンスの解析に失敗しました:", e)
        events = []

    return events

とする

実行結果は

{'date': '2024-10-07', 'event': 'ペットボトルの準備'}
{'date': '2024-10-15', 'event': None}
{'date': '2024-10-25', 'event': '準備物の確認'}
{'date': '2024-10-26', 'event': None}

となる

一応はエラーは消えたが他のものを試してみる

台風10号の影響により、9月2日(月)の給食が中止となりました。 弁当の準備をお願いします。 8月30日(金)現時点では、日課の変更はありません。 台風や大雨の状況によっては、変更する場合があります。 4月にコドモンで知らせした、「R6年度 自然災害発生時、警報発表・避難情報発表時等に伴う学校の対処」とおり対応します。 今一度御確認ください。
という文章で実験すると

{'date': '8月30日', 'event': '弁当の準備'}
{'date': '9月2日', 'event': '給食中止'}

とほぼ目的に近いものになる

PTA会員 様  Caros membros do PTA
 
 日頃よりPTA活動に御理解・御協力いただいき、ありがとうございます。
 令和7年度のPTA本部役員候補選考の時期になりました。
 アンケート形式にて本部役員の立候補を募ります。
 添付の文書を御一読いただき、以下のリンクからアンケートに回答をお願いします。
 回答期限は9月30日(月)とします。

だと

Ollamaのレスポンス:
[
    {"date": "2024-09-25", "event": "PTA本部役員候補選出についてのアンケート"},
    {"date": "2024-09-30", "event": "アンケート回答期限"}
]
抽出されたイベント:
{'date': '2024-09-25', 'event': 'PTA本部役員候補選出についてのアンケート'}
{'date': '2024-09-30', 'event': 'アンケート回答期限'}

テキストファイルの内容によっては

抽出されたイベント: {'date': '2024-10-07', 'event': 'ペットボトルの準備'} {'date': '2024-10-15', 'event': None} {'date': '2024-10-25', 'event': '準備物の確認'} {'date': '2024-10-26', 'event': None}

となるため
プロンプトを改善して、モデルにeventがnullにならないように強調

prompt = f"""
以下の文章から、日付とそれに対応する予定を抽出してください。結果は純粋なJSON形式で、日本語で、"date"と"event"のキーを持つオブジェクトのリストとして返してください。

文章:
{text}

出力例:
[
    {{"date": "2024-10-07", "event": "ペットボトルの準備"}},
    {{"date": "2024-10-25", "event": "準備物の確認"}}
]

重要事項:
- 出力は純粋なJSON形式で、追加のテキストや説明は含めないでください。
- 日付は"YYYY-MM-DD"の形式で出力してください。
- **イベント名が存在しない場合、そのエントリを出力しないでください。**
- イベント名は元の文章から適切に抽出してください。
"""



リスト内包表記を使用:eventsリストからevent['event']がNoneでないイベントだけを新しいリストにします。
is not Noneを使用:event['event']がNoneでないことを確認

# Ollamaでテキストを解析(モデル名を指定)
events = parse_text_with_ollama(text_content, model_name='elyza:jp8b')

# 抽出されたイベントを表示
print("抽出されたイベント:")
for event in events:
    print(event)

# eventがNoneのものを削除
events = [event for event in events if event['event'] is not None]

# フィルタリング後のイベントを表示
print("有効なイベント:")
for event in events:
    print(event)

これらを変更するので

import requests
import json

def parse_text_with_ollama(text, model_name='elyza:jp8b'):
    """
    Ollamaを使用してテキストから日時とイベントを抽出します。

    Args:
        text (str): 解析するテキスト。
        model_name (str): 使用するOllamaモデルの名前。

    Returns:
        list: 抽出されたイベントのリスト。
    """
    # OllamaのAPIエンドポイント
    ollama_url = 'http://localhost:11434/api/generate'

    # Ollamaに送信するプロンプトを作成
    prompt = f"""
以下の文章から、日付とそれに対応する予定を抽出してください。結果は純粋なJSON形式で、日本語で、"date"と"event"のキーを持つオブジェクトのリストとして返してください。

文章:
{text}

出力例:
[
    {{"date": "2024-10-07", "event": "ペットボトルの準備"}},
    {{"date": "2024-10-25", "event": "準備物の確認"}}
]

重要事項:
- 出力は純粋なJSON形式で、追加のテキストや説明は含めないでください。
- 日付は"YYYY-MM-DD"の形式で出力してください。
- イベント名は元の文章から適切に抽出してください。
"""

    payload = {
        'model': model_name,
        'prompt': prompt
    }

    try:
        # ストリーミングレスポンスを取得
        response = requests.post(ollama_url, json=payload, stream=True)
        response.raise_for_status()

        # レスポンスのストリームを処理
        response_text = ''
        for line in response.iter_lines():
            if line:
                line_str = line.decode('utf-8')
                # 各行をJSONとしてパース
                line_json = json.loads(line_str)
                # "response"フィールドを連結
                response_text += line_json.get('response', '')

        print("Ollamaのレスポンス:")
        print(response_text)
    except requests.exceptions.RequestException as e:
        print("Ollamaへのリクエストに失敗しました:", e)
        return []
    except json.JSONDecodeError as e:
        print("レスポンスの解析に失敗しました:", e)
        return []

    # 連結したテキストをJSONとして解析
    try:
        events = json.loads(response_text)
    except json.JSONDecodeError as e:
        print("Ollamaからのレスポンスの解析に失敗しました:", e)
        events = []

    return events

import requests
import json

def parse_text_with_ollama(text, model_name='elyza:jp8b'):
    """
    Ollamaを使用してテキストから日時とイベントを抽出します。

    Args:
        text (str): 解析するテキスト。
        model_name (str): 使用するOllamaモデルの名前。

    Returns:
        list: 抽出されたイベントのリスト。
    """
    # OllamaのAPIエンドポイント
    ollama_url = 'http://localhost:11434/api/generate'

    # Ollamaに送信するプロンプトを作成
    prompt = f"""
以下の文章から、日付とそれに対応する予定を抽出してください。結果は純粋なJSON形式で、日本語で、"date"と"event"のキーを持つオブジェクトのリストとして返してください。

文章:
{text}

出力例:
[
    {{"date": "2024-10-07", "event": "ペットボトルの準備"}},
    {{"date": "2024-10-25", "event": "準備物の確認"}}
]

重要事項:
- 出力は純粋なJSON形式で、追加のテキストや説明は含めないでください。
- 日付は"YYYY-MM-DD"の形式で出力してください。
- **イベント名が存在しない場合、そのエントリを出力しないでください。**
- イベント名は元の文章から適切に抽出してください。
"""

    payload = {
        'model': model_name,
        'prompt': prompt
    }

    try:
        # ストリーミングレスポンスを取得
        response = requests.post(ollama_url, json=payload, stream=True)
        response.raise_for_status()

        # レスポンスのストリームを処理
        response_text = ''
        for line in response.iter_lines():
            if line:
                line_str = line.decode('utf-8')
                # 各行をJSONとしてパース
                line_json = json.loads(line_str)
                # "response"フィールドを連結
                response_text += line_json.get('response', '')

        print("Ollamaのレスポンス:")
        print(response_text)
    except requests.exceptions.RequestException as e:
        print("Ollamaへのリクエストに失敗しました:", e)
        return []
    except json.JSONDecodeError as e:
        print("レスポンスの解析に失敗しました:", e)
        return []

    # 連結したテキストをJSONとして解析
    try:
        events = json.loads(response_text)
    except json.JSONDecodeError as e:
        print("Ollamaからのレスポンスの解析に失敗しました:", e)
        events = []

    return events

にして

from ollama_module import parse_text_with_ollama
from google_calendar_module import add_events_to_calendar

# テキストファイルのパス
text_file_path = 'school_notice.txt'  # 処理するテキストファイルのパス

# テキストの読み込み
with open(text_file_path, 'r', encoding='utf-8') as file:
    text_content = file.read()

# Ollamaでテキストを解析(モデル名を指定)
events = parse_text_with_ollama(text_content, model_name='elyza:jp8b')

# 抽出されたイベントを表示
print("抽出されたイベント:")
for event in events:
    print(event)

# Googleカレンダーにイベントを追加
# add_events_to_calendar(events, calendar_id='primary', token_file='token.json', credentials_file='credentials.json')

from ollama_module import parse_text_with_ollama
from google_calendar_module import add_events_to_calendar

# テキストファイルのパス
text_file_path = 'school_notice.txt'  # 処理するテキストファイルのパス

# テキストの読み込み
with open(text_file_path, 'r', encoding='utf-8') as file:
    text_content = file.read()

# Ollamaでテキストを解析(モデル名を指定)
events = parse_text_with_ollama(text_content, model_name='elyza:jp8b')

# 抽出されたイベントを表示
print("抽出されたイベント:")
for event in events:
    print(event)

# eventがNoneのものを削除
events = [event for event in events if event['event'] is not None]

# フィルタリング後のイベントを表示
print("有効なイベント:")
for event in events:
    print(event)

# 有効なイベントがある場合のみGoogleカレンダーに追加
if events:
    add_events_to_calendar(events, calendar_id='primary', token_file='token.json', credentials_file='credentials.json')
else:
    print("有効なイベントがありません。")

とした