#!/usr/bin/env python3 """ チェックイン機能確認ツール: 総合的にチェックイン機能の状態を調査 """ import subprocess import requests import json from datetime import datetime import time def check_checkin_api_status(): """ チェックインAPIの基本動作確認 """ print("🔍 チェックインAPI動作確認") print("=" * 50) # 基本的な接続確認 test_urls = [ "http://localhost:8100/gifuroge/checkin_from_rogapp", "http://localhost:8100/api/checkin_from_rogapp" ] for url in test_urls: try: # GETリクエストでエンドポイントの存在確認 response = requests.get(url, timeout=5) print(f"✅ {url} → HTTP {response.status_code}") if response.status_code == 405: print(f" 💡 405 Method Not Allowed は正常(POSTのみ許可)") elif response.status_code == 404: print(f" ❌ 404 Not Found - エンドポイントが見つからない") except requests.exceptions.ConnectionError: print(f"❌ {url} → 接続エラー") except Exception as e: print(f"❌ {url} → エラー: {e}") print() def test_checkin_with_real_data(): """ 実際のデータでチェックインテスト """ print("🎯 実際のデータでチェックインテスト") print("-" * 50) # 実際のイベントとチームを取得 try: result = subprocess.run([ 'docker', 'compose', 'exec', 'app', 'python', 'manage.py', 'shell', '-c', """ from rog.models import NewEvent2, Entry, Team # 最新のイベント取得 event = NewEvent2.objects.first() if event: print(f"EVENT:{event.event_name}") # そのイベントのエントリー取得 entry = Entry.objects.filter(event=event).first() if entry and entry.team: print(f"TEAM:{entry.team.team_name}") print(f"ZEKKEN:{entry.zekken_number}") # スタート済みかチェック from rog.models import GpsLog start_log = GpsLog.objects.filter( zekken_number=entry.zekken_number, event_code=event.event_name, cp_number='START' ).first() print(f"STARTED:{bool(start_log)}") else: print("TEAM:None") else: print("EVENT:None") """ ], capture_output=True, text=True) lines = result.stdout.strip().split('\n') event_name = None team_name = None zekken_number = None is_started = False for line in lines: if line.startswith('EVENT:'): event_name = line.split(':', 1)[1] elif line.startswith('TEAM:'): team_name = line.split(':', 1)[1] elif line.startswith('ZEKKEN:'): zekken_number = line.split(':', 1)[1] elif line.startswith('STARTED:'): is_started = line.split(':', 1)[1] == 'True' print(f"📊 取得したテストデータ:") print(f" イベント: {event_name}") print(f" チーム: {team_name}") print(f" ゼッケン: {zekken_number}") print(f" スタート済み: {is_started}") if event_name and team_name and event_name != 'None' and team_name != 'None': # チェックインテスト実行 test_data = { "event_code": event_name, "team_name": team_name, "cp_number": "1", "image": "data:image/jpeg;base64,test", "buy_flag": False } print(f"\n🚀 チェックインテスト実行:") print(f" URL: http://localhost:8100/api/checkin_from_rogapp") print(f" データ: {json.dumps(test_data, ensure_ascii=False, indent=2)}") try: response = requests.post( "http://localhost:8100/api/checkin_from_rogapp", json=test_data, headers={'Content-Type': 'application/json'}, timeout=10 ) print(f"\n📥 レスポンス:") print(f" ステータス: HTTP {response.status_code}") print(f" 内容: {response.text}") if response.status_code == 400: response_data = response.json() if "スタートしていません" in response_data.get('message', ''): print(f"\n💡 スタート処理が必要です。start_from_rogapp APIを先に実行してください。") return test_start_api(event_name, team_name) except Exception as e: print(f"❌ チェックインテストエラー: {e}") else: print(f"❌ テストデータが不足しています") except Exception as e: print(f"❌ データ取得エラー: {e}") def test_start_api(event_name, team_name): """ スタートAPIのテスト """ print(f"\n🏁 スタートAPIテスト") print("-" * 30) start_data = { "event_code": event_name, "team_name": team_name, "image": "data:image/jpeg;base64,start_test" } try: response = requests.post( "http://localhost:8100/gifuroge/start_from_rogapp", json=start_data, headers={'Content-Type': 'application/json'}, timeout=10 ) print(f"📥 スタートAPIレスポンス:") print(f" ステータス: HTTP {response.status_code}") print(f" 内容: {response.text}") if response.status_code == 200: print(f"✅ スタート成功!チェックインを再試行します...") time.sleep(1) # チェックインを再試行 test_checkin_after_start(event_name, team_name) except Exception as e: print(f"❌ スタートAPIエラー: {e}") def test_checkin_after_start(event_name, team_name): """ スタート後のチェックインテスト """ print(f"\n🎯 スタート後チェックインテスト") print("-" * 30) checkin_data = { "event_code": event_name, "team_name": team_name, "cp_number": "1", "image": "data:image/jpeg;base64,checkin_test", "buy_flag": False } try: response = requests.post( "http://localhost:8100/api/checkin_from_rogapp", json=checkin_data, headers={'Content-Type': 'application/json'}, timeout=10 ) print(f"📥 チェックインレスポンス:") print(f" ステータス: HTTP {response.status_code}") print(f" 内容: {response.text}") if response.status_code == 200: print(f"🎉 チェックイン成功!") elif response.status_code == 400: print(f"⚠️ チェックイン失敗(400)") except Exception as e: print(f"❌ チェックインエラー: {e}") def check_recent_logs(): """ 最近のログを確認 """ print(f"\n📋 最近のチェックイン関連ログ") print("-" * 50) try: result = subprocess.run([ 'docker', 'compose', 'logs', '--tail=30', 'app' ], capture_output=True, text=True) lines = result.stdout.split('\n') checkin_logs = [] for line in lines: if any(keyword in line.lower() for keyword in ['checkin', 'start', 'gpslog', '502', '400', '405']): checkin_logs.append(line) if checkin_logs: print("🔍 関連ログ:") for log in checkin_logs[-10:]: # 最新10件 print(f" {log}") else: print(" 📝 チェックイン関連のログが見つかりませんでした") except Exception as e: print(f"❌ ログ確認エラー: {e}") def check_database_status(): """ データベースの状態確認 """ print(f"\n💾 データベース状態確認") print("-" * 50) try: result = subprocess.run([ 'docker', 'compose', 'exec', 'app', 'python', 'manage.py', 'shell', '-c', """ from rog.models import GpsLog, NewEvent2, Entry import datetime # 最近のGpsLogエントリー recent_logs = GpsLog.objects.order_by('-id')[:5] print(f"RECENT_LOGS:{len(recent_logs)}") for log in recent_logs: print(f"LOG:{log.id}|{log.event_code}|{log.zekken_number}|{log.cp_number}|{log.checkin_time}") # イベント数 event_count = NewEvent2.objects.count() print(f"EVENTS:{event_count}") # エントリー数 entry_count = Entry.objects.count() print(f"ENTRIES:{entry_count}") """ ], capture_output=True, text=True) lines = result.stdout.strip().split('\n') for line in lines: if line.startswith('RECENT_LOGS:'): count = line.split(':', 1)[1] print(f" 最近のGpsLogエントリー: {count}件") elif line.startswith('LOG:'): parts = line.split(':', 1)[1].split('|') if len(parts) >= 5: print(f" ID:{parts[0]} イベント:{parts[1]} ゼッケン:{parts[2]} CP:{parts[3]} 時刻:{parts[4]}") elif line.startswith('EVENTS:'): count = line.split(':', 1)[1] print(f" 総イベント数: {count}") elif line.startswith('ENTRIES:'): count = line.split(':', 1)[1] print(f" 総エントリー数: {count}") except Exception as e: print(f"❌ データベース確認エラー: {e}") def main(): """ メイン実行関数 """ print("🚀 チェックイン機能 総合確認ツール") print(f"実行時刻: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") print("=" * 60) # 1. API基本動作確認 check_checkin_api_status() # 2. データベース状態確認 check_database_status() # 3. 実際のデータでテスト test_checkin_with_real_data() # 4. 最近のログ確認 check_recent_logs() print(f"\n📊 確認完了") print("=" * 60) print("💡 次のステップ:") print(" 1. 502エラーが出る場合 → nginx設定確認") print(" 2. 405エラーが出る場合 → URLパス確認") print(" 3. 400エラーが出る場合 → データ確認") print(" 4. スタート前エラー → start_from_rogapp API実行") if __name__ == "__main__": main()