#!/usr/bin/env python3 # -*- coding: utf-8 -*- import sys import io sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace') sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8', errors='replace') import os import json import time from datetime import date, timedelta from pathlib import Path import requests import pymysql # ========================================= # CONFIGURATION # ========================================= ACCOUNTS_FILE = r"../accounts.json" JSON_BASE_DIR = r"u:\Dropbox\!!!Days\Downloads Z230\Fio" DB = { "host": "192.168.1.76", "port": 3306, "user": "root", "password": "Vlado9674+", "database": "fio", "charset": "utf8mb4", } BATCH_SIZE = 500 DAYS_BACK = 90 # ========================================= # HELPERS # ========================================= def load_accounts(path): with open(path, "r", encoding="utf-8") as f: accounts = json.load(f) for acc in accounts: for key in ("name", "account_number", "token"): if key not in acc: raise ValueError(f"Missing '{key}' in account config: {acc}") return accounts def fio_url_for_period(token, d_from, d_to): return f"https://fioapi.fio.cz/v1/rest/periods/{token}/{d_from:%Y-%m-%d}/{d_to:%Y-%m-%d}/transactions.json" def fetch_fio_json(token, d_from, d_to): url = fio_url_for_period(token, d_from, d_to) resp = requests.get(url, timeout=30) if resp.status_code != 200: print(f"❌ HTTP {resp.status_code} from Fio") return None return resp.json() def safe_col(t, n): val = t.get(f"column{n}") return None if not val else val.get("value") def clean_date(dt_str): return None if not dt_str else dt_str[:10] def ensure_dir(path): Path(path).mkdir(parents=True, exist_ok=True) def save_json_for_account(base_dir, account_cfg, data, d_from, d_to): acc_folder = account_cfg["account_number"].replace("/", "_") out_dir = Path(base_dir) / acc_folder ensure_dir(out_dir) filename = f"{d_from:%Y-%m-%d}_to_{d_to:%Y-%m-%d}.json" out_path = out_dir / filename with open(out_path, "w", encoding="utf-8") as f: json.dump(data, f, ensure_ascii=False, indent=2) return out_path # ========================================= # MAIN # ========================================= def main(): today = date.today() d_from = today - timedelta(days=DAYS_BACK) d_to = today print(f"=== Fio import {d_from} → {d_to} ===") accounts = load_accounts(ACCOUNTS_FILE) conn = pymysql.connect(**DB) cur = conn.cursor() sql = """ INSERT INTO transactions ( id_operace, cislo_uctu, transaction_date, amount, currency, protiucet, kod_banky, nazev_protiuctu, nazev_banky, typ, vs, ks, ss, zprava_pro_prijemce, uziv_identifikace, provedl, id_pokynu, komentar, upr_objem_mena, api_bic, reference_platce ) VALUES ( %(id_operace)s, %(cislo_uctu)s, %(transaction_date)s, %(amount)s, %(currency)s, %(protiucet)s, %(kod_banky)s, %(nazev_protiuctu)s, %(nazev_banky)s, %(typ)s, %(vs)s, %(ks)s, %(ss)s, %(zprava)s, %(uziv_identifikace)s, %(provedl)s, %(id_pokynu)s, %(komentar)s, %(upr_objem_mena)s, %(api_bic)s, %(reference_platce)s ) ON DUPLICATE KEY UPDATE transaction_date = VALUES(transaction_date), amount = VALUES(amount), currency = VALUES(currency), protiucet = VALUES(protiucet), kod_banky = VALUES(kod_banky), nazev_protiuctu = VALUES(nazev_protiuctu), nazev_banky = VALUES(nazev_banky), typ = VALUES(typ), vs = VALUES(vs), ks = VALUES(ks), ss = VALUES(ss), zprava_pro_prijemce = VALUES(zprava_pro_prijemce), uziv_identifikace = VALUES(uziv_identifikace), provedl = VALUES(provedl), id_pokynu = VALUES(id_pokynu), komentar = VALUES(komentar), upr_objem_mena = VALUES(upr_objem_mena), api_bic = VALUES(api_bic), reference_platce = VALUES(reference_platce) """ total_inserted = 0 for acc in accounts: print(f"\n--- {acc['name']} ---") data = fetch_fio_json(acc["token"], d_from, d_to) if not data: continue save_json_for_account(JSON_BASE_DIR, acc, data, d_from, d_to) tlist = data["accountStatement"]["transactionList"].get("transaction", []) if isinstance(tlist, dict): tlist = [tlist] fio_acc_id = data["accountStatement"]["info"]["accountId"] rows = [] for t in tlist: row = { "id_operace": safe_col(t, 22), "cislo_uctu": fio_acc_id, "transaction_date": clean_date(safe_col(t, 0)), "amount": safe_col(t, 1), "currency": safe_col(t, 14), "protiucet": safe_col(t, 2), "kod_banky": safe_col(t, 3), "nazev_protiuctu": safe_col(t, 10), "nazev_banky": safe_col(t, 15), "typ": safe_col(t, 8), "vs": safe_col(t, 5), "ks": safe_col(t, 4), "ss": safe_col(t, 6), "zprava": safe_col(t, 16), "uziv_identifikace": safe_col(t, 12), "provedl": safe_col(t, 12), "id_pokynu": safe_col(t, 19), "komentar": safe_col(t, 25), "upr_objem_mena": safe_col(t, 20), "api_bic": safe_col(t, 26), "reference_platce": safe_col(t, 27), } if row["id_operace"]: rows.append(row) inserted = 0 for i in range(0, len(rows), BATCH_SIZE): chunk = rows[i:i+BATCH_SIZE] cur.executemany(sql, chunk) conn.commit() inserted += len(chunk) print(f"✓ Insert/Update: {inserted}") total_inserted += inserted cur.close() conn.close() print(f"\n=== DONE → {total_inserted} rows processed ===") if __name__ == "__main__": main()