Metadata-Version: 2.4
Name: boatrace-lzh
Version: 0.1.0
Summary: Parser for official Japanese boat race (BOATRACE) LZH data files
Project-URL: Homepage, https://github.com/miyamamoto/boatrace-lzh
Project-URL: Repository, https://github.com/miyamamoto/boatrace-lzh
Project-URL: Issues, https://github.com/miyamamoto/boatrace-lzh/issues
Author: miyamamoto
License-Expression: MIT
License-File: LICENSE
Keywords: boat-race,boatrace,japan,kyotei,lzh,parser
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Requires-Dist: requests>=2.28
Description-Content-Type: text/markdown

# boatrace-lzh

公式ボートレースデータ（LZH形式）のダウンロード・パースライブラリ。

[BOATRACE公式データ配信サーバー](https://www1.mbrace.or.jp)から提供されるLZHファイル（番組表・成績）をダウンロード、解凍、パースして構造化データとして利用できます。

## 特徴

- 📥 **自動ダウンロード** — 日付指定でLZHファイルを取得・解凍
- 📋 **番組表パース** — レーススケジュール、締切時間、出走選手情報
- 🏁 **成績パース** — 着順、展示タイム、STタイミング、払戻金
- 💾 **キャッシュ機能** — 確定データは自動キャッシュ（当日分は毎回再取得）
- ⚡ **並列ダウンロード** — 複数日分の一括取得
- 🏢 **全24場対応** — 桐生〜大村まで全会場

## インストール

```bash
pip install boatrace-lzh
```

### 前提条件

LZH解凍に `p7zip-full` または `lha` が必要です:

```bash
# Ubuntu/Debian
sudo apt install p7zip-full

# macOS
brew install p7zip
```

## クイックスタート

### 番組表（スケジュール）の取得

```python
from datetime import date
from boatrace_lzh import LzhDownloader, ScheduleParser

# ダウンロード
dl = LzhDownloader(cache_dir="./cache")
files = dl.download(date(2025, 6, 25), "schedule")

# パース
parser = ScheduleParser()
result = parser.parse(files)

for race in result.races:
    print(f"{race.venue_code} {race.race_number}R: {race.race_name}")

# 締切時間付きスケジュール
schedule = parser.parse_schedule_with_close_times(files, date(2025, 6, 25))
for race in schedule:
    print(f"{race.venue_name} {race.race_number}R 締切: {race.close_time}")
```

### 成績（レース結果）の取得

```python
from datetime import date
from boatrace_lzh import LzhDownloader, PerformanceParser

dl = LzhDownloader(cache_dir="./cache")
files = dl.download(date(2025, 6, 25), "performance")

parser = PerformanceParser()
result = parser.parse(files)

# レース結果
for entry in result.entries:
    if entry.result_position == 1:
        print(f"{entry.venue_code} {entry.race_number}R 1着: {entry.boat_number}号艇")

# 払戻金
for payout in result.payouts:
    if payout.ticket_type == "tansho":
        print(f"{payout.venue_code} {payout.race_number}R 単勝: {payout.winning_combination} ¥{payout.payout}")
```

### 複数日分の一括ダウンロード

```python
from datetime import date, timedelta
from boatrace_lzh import LzhDownloader, PerformanceParser

dl = LzhDownloader(cache_dir="./cache", max_workers=4)

# 1週間分を並列ダウンロード
dates = [date(2025, 6, 25) - timedelta(days=i) for i in range(7)]
all_files = dl.download_many(dates, "performance")

parser = PerformanceParser()
for d, files in all_files.items():
    if files:
        result = parser.parse(files)
        print(f"{d}: {len(result.races)} races, {len(result.payouts)} payouts")
```

## データ構造

### ParseResult

`ScheduleParser.parse()` / `PerformanceParser.parse()` の戻り値:

| フィールド | 型 | 説明 |
|---|---|---|
| `venues` | `list[Venue]` | 会場一覧 |
| `races` | `list[Race]` | レース情報（天候、距離等） |
| `racers` | `list[Racer]` | 選手情報（名前、級別等） |
| `entries` | `list[RaceEntry]` | 出走データ（着順、展示タイム等） |
| `payouts` | `list[Payout]` | 払戻金（成績のみ） |

### 舟券種別

| `ticket_type` | 日本語 |
|---|---|
| `tansho` | 単勝 |
| `fukusho` | 複勝 |
| `nirensho` | 2連単 |
| `nirenfuku` | 2連複 |
| `wide` | 拡連複 |
| `sanrensho` | 3連単 |
| `sanrenfuku` | 3連複 |

## キャッシュ動作

| 日付 | 動作 |
|---|---|
| 2日以上前 | キャッシュを永久使用（確定データ） |
| 昨日・今日・明日 | 毎回サーバーから再取得 |

キャッシュは `cache_dir` に pickle 形式で保存されます。

## データ提供期間

2005年1月1日から現在まで（番組表は翌日分まで先行公開）。

## ライセンス

MIT License
