diff --git a/finance/ktoblzcheck-data/Makefile b/finance/ktoblzcheck-data/Makefile index bf56392695f3..0859095b1bce 100644 --- a/finance/ktoblzcheck-data/Makefile +++ b/finance/ktoblzcheck-data/Makefile @@ -1,55 +1,55 @@ PORTNAME= ktoblzcheck PORTVERSION= 1.0.0.${BANKDATA_START_DATE} CATEGORIES= finance MASTER_SITES= SF/${PORTNAME} \ LOCAL/jhale/${PORTNAME}:bankdata PKGNAMESUFFIX= -data DISTFILES= ${PORTNAME}${PKGNAMESUFFIX}-${KBCD_DATE}${EXTRACT_SUFX} \ ${PORTNAME}-bankdata-${BANKDATA_START_DATE}${EXTRACT_SUFX}:bankdata MAINTAINER= jhale@FreeBSD.org COMMENT= Bank data used by ktoblzcheck WWW= https://ktoblzcheck.sourceforge.net/ # Project does not specify a license for the resulting databases, but the data # files it processes are in the public domain. LICENSE= PD BUILD_DEPENDS= ${PYTHON_PKGNAMEPREFIX}sqlite3>0:databases/py-sqlite3@${PY_FLAVOR} \ ${PYTHON_PKGNAMEPREFIX}openpyxl>0:textproc/py-openpyxl@${PY_FLAVOR} USES= cmake python:build CMAKE_ARGS= -DDATA_FILEPATH_sepa:PATH="../data/sepa_${BANKDATA_START_DATE}.txt" CMAKE_ON= INSTALL_RAW_BANKDATA_FILE \ INSTALL_SEPA_BANKDATA_FILE CMAKE_OFF= ENABLE_BANKDATA_DOWNLOAD WRKSRC= ${WRKDIR}/${PORTNAME}${PKGNAMESUFFIX}-${KBCD_DATE} PLIST_SUB= BANKDATA_START_DATE=${BANKDATA_START_DATE} # Custom: Upstream ships a dated a distfile, but will most likely not contain # the most recent bank data. This is just used for build system changes. KBCD_DATE= 20250515 # Custom: This is the date when the bank data is officially recocognized and # supported. -BANKDATA_START_DATE= 20250609 +BANKDATA_START_DATE= 20251208 # Custom: This is the date when the bank data is officially void and can no # longer be relied upon. -BANKDATA_END_DATE= 20250907 +BANKDATA_END_DATE= 20260308 post-extract: # Out of an abundance of caution, remove the pre-built DBs and shipped SEPA data. (cd ${WRKSRC}/data && ${RM} bankdata* sepa*) # Populate ${WRKSRC}/data with the contents of our bankdata archive. .for f in blz_${BANKDATA_START_DATE}.txt ch_data.txt nl_data.xlsx sepa_${BANKDATA_START_DATE}.txt ${CP} ${WRKDIR}/${PORTNAME}-bankdata-${BANKDATA_START_DATE}/${f} ${WRKSRC}/data .endfor post-patch: # See comment in files/patch-src_CMakeLists.txt. @${REINPLACE_CMD} -e 's|%%BANKDATA_END_DATE%%|'"$$(date -j -f "%Y%m%d" "+%d.%m.%Y" ${BANKDATA_END_DATE})"'|' \ ${WRKSRC}/src/CMakeLists.txt .include diff --git a/finance/ktoblzcheck-data/distinfo b/finance/ktoblzcheck-data/distinfo index 8e559b557fe4..a6b865f08db9 100644 --- a/finance/ktoblzcheck-data/distinfo +++ b/finance/ktoblzcheck-data/distinfo @@ -1,5 +1,5 @@ -TIMESTAMP = 1751008153 +TIMESTAMP = 1767925106 SHA256 (ktoblzcheck-data-20250515.tar.gz) = 307479cd3c487ba6d6c4f5966634a6023c1f29d4386b93a5e96cea7541bebe4c SIZE (ktoblzcheck-data-20250515.tar.gz) = 267821 -SHA256 (ktoblzcheck-bankdata-20250609.tar.gz) = 36d9a5ea5c3e7b1183d8fe2f24658d7e50ac3686b14573b17f9f46cf04388065 -SIZE (ktoblzcheck-bankdata-20250609.tar.gz) = 510238 +SHA256 (ktoblzcheck-bankdata-20251208.tar.gz) = 8cfbe82f18461aa182fcc7201a9337ae34c93dd652df874f9018adc7ef1463eb +SIZE (ktoblzcheck-bankdata-20251208.tar.gz) = 425612 diff --git a/finance/ktoblzcheck-data/files/patch-src_switzerland.py b/finance/ktoblzcheck-data/files/patch-src_switzerland.py new file mode 100644 index 000000000000..528491087421 --- /dev/null +++ b/finance/ktoblzcheck-data/files/patch-src_switzerland.py @@ -0,0 +1,122 @@ +- Adapt to SIX Group converting their bankdata to CSV (semicolon separated). +- Don't use codecs.open(); deprecated in Python 3.14. + +--- src/switzerland.py.orig 2025-05-15 11:18:20 UTC ++++ src/switzerland.py +@@ -24,12 +24,11 @@ KMyMoney + @author: Christian David + """ + +-import sqlite3 +-import codecs + import argparse +-import os ++import csv ++import sqlite3 + +-def createTable(): ++def create_table(): + """ Create table structure + """ + cursor = db.cursor() +@@ -45,59 +44,65 @@ def createTable(): + ) + db.commit() + +- +-def processFile(fileName): ++def process_file(filename): + """ Fills the database with institutions saved in fileName + """ ++ with open(filename, 'r', newline='') as institutes_file: ++ reader = list(csv.reader(institutes_file, delimiter=';')) ++ rows = reader[1:] + +- rowsInserted = 0 +- cursor = db.cursor() +- cursor.execute("BEGIN") ++ bank_map = {row[0]: {"bic": row[14], "name": f"{row[8]} ({row[12]})"} for row in rows} + +- def existCode(bankCode, bic): +- cursor.execute("SELECT bankcode,bic FROM institutions WHERE bankcode = ? and bic = ?",(bankCode,bic,)) +- row_exist = cursor.fetchone() +- if row_exist is None: +- return False ++ to_insert = [] ++ for row in rows: ++ bankcode = row[0].zfill(5) + +- return True ++ # Non-concatenated "parent" entries ++ if row[2] == 'N': ++ bic = row[14] ++ name = f"{row[8]} ({row[12]})" ++ # Some bankcodes are concatenated onto other bankcodes without the BIC or other ++ # institution info on their line, so we must get these from the parent entry ++ else: ++ parent_bankcode = row[3] ++ parent_info = bank_map.get(parent_bankcode) ++ if parent_info: ++ bic = parent_info["bic"] ++ name = parent_info["name"] ++ else: ++ continue + +- def submitInstitute(bankCode, bankName, bic): +- if(not existCode(bankCode, bic)): +- try: +- cursor.execute("INSERT INTO institutions (bankcode, bic, name) VALUES(?,?,?)", (bankCode, bic, bankName)) +- except sqlite3.Error as e: +- print("Error: {0} while inserting {1} ({2})".format(e.args[0], bankCode, bic)) ++ to_insert.append((bankcode, bic, name)) + +- institutesFile = codecs.open(fileName, "r", encoding=args.encoding) +- for institute in institutesFile: +- bic = institute[284:295].strip() +- if len(bic) > 0: +- bcNumber = "{:0>5}".format(institute[2:7].strip() if institute[11:16] == " " else institute[11:16].strip()) +- name = "%s (%s)" % (institute[54:114].strip(), institute[194:229].strip()) +- submitInstitute(bcNumber, name, bic) +- rowsInserted += 1 ++ cursor = db.cursor() ++ cursor.execute("BEGIN") ++ try: ++ cursor.executemany( ++ "INSERT OR IGNORE INTO institutions (bankcode, bic, name) VALUES (?, ?, ?)", ++ to_insert ++ ) ++ db.commit() ++ return cursor.rowcount ++ except sqlite3.Error as e: ++ db.rollback() ++ print(f"Database error: {e}") ++ return 0 + +- db.commit() +- return rowsInserted +- +- + if __name__ == '__main__': + parser = argparse.ArgumentParser(description="Creates a SQLite database for KMyMoney with information about IBAN and BICs based on a swiss BC-Bankenstamm file." +- " You can get the BC-Bankenstamm file from https://www.six-group.com/interbank-clearing/de/home/bank-master-data/download-bc-bank-master.html" ++ " You can get the BC-Bankenstamm file from https://api.six-group.com/api/epcd/bankmaster/v2/public/downloads/bcbankenstamm" + ) + + parser.add_argument(dest='file', help='File to load') + parser.add_argument('-o', '--output', default="bankdata.ch.db", help='SQLite database to open/generate') +- parser.add_argument('-e', '--encoding', default="iso 8859-15", help='Charset of file') + args = parser.parse_args() + +- print("Read data from \"{0}\" with \"{1}\" encoding".format(args.file, args.encoding)) ++ print(f'Read data from "{args.file}"') + db = sqlite3.connect(args.output) + +- createTable() +- institutions = processFile(args.file) +- print("Inserted {0} institutions into database \"{1}\"".format(institutions, args.output)) ++ create_table() ++ institutions = process_file(args.file) ++ print(f'Inserted {institutions} institutions into database "{args.output}"') + + cursor = db.cursor() + cursor.execute("ANALYZE institutions")