From: Shane Jaroch Date: Fri, 26 Dec 2025 11:08:55 +0000 (-0500) Subject: better loop logic for import with empty row X-Git-Url: https://git.nutra.tk/v1?a=commitdiff_plain;h=507e89e41a53baa465f42fd7a3dd432c897db3c5;p=gamesguru%2Fffpass.git better loop logic for import with empty row --- diff --git a/ffpass/__init__.py b/ffpass/__init__.py index 061404a..e7f7a09 100755 --- a/ffpass/__init__.py +++ b/ffpass/__init__.py @@ -368,46 +368,43 @@ def exportLogins(key, jsonLogins): def readCSV(csv_file): - # Peek at the first line to detect if header exists - first_line = csv_file.readline() - logging.debug(f"first_line: {first_line}") - if not first_line: - logging.warning('WARN: Nothing detected, first line is blank.') - return [] - - # Heuristic: if it contains both keys (at index=2,3), assume it's a header - is_header = ( - first_line[1].lower() in {"username", "uname", "user", "u"} - and first_line[2].lower() in {"password", "passwd", "pass", "p"} # noqa: W503 line break before binary operator - ) - if is_header: - # Re-chain the first line, but ensure DictReader lowercases the header row - # by creating an iterator that lowercases the first item only - def normalized_iter(): - yield first_line.lower() - yield from csv_file - logging.info("Using CSV DictReader.") - reader = csv.DictReader(normalized_iter()) - else: - logging.info("Using CSV RowReader.") - reader = csv.reader(csv_file) + reader = csv.reader(csv_file) logins = [] - for row in reader: - logging.error(f"row: {row}") + first_row = None - if not row or (row[0] == '\x04' and len(row) < 3): - break # Windows doesn't have Ctrl+D, so let's break on first empty line + # Loop through logins + for i, row in enumerate(reader): - if isinstance(reader, csv.DictReader): - logging.error("DictReader it is!") - u = row.get("url", "") - n = row.get("username", "") - p = row.get("password", "") - else: - logging.error("RowReader it is!") - u, n, p = row + logging.debug(f"row: {row}") + + # Peek at the first line to detect if it is a header or normal row + if first_row is None: + logging.debug(f"first_row: {row}") + first_row = row + + # Break if we get an empty first row + if (not row) or (len(row) != 3) or (not row[1] and not row[2]): + logging.debug(f"Breaking loop since we got an empty row at index={i}.") + break + # Heuristic: if it lacks a URL (index=1) and has user,pass (index=2,3), assume it's a header and continue + if ( + "http://" not in first_row[0] + and first_row[1].lower() in {"username", "uname", "user", "u"} # noqa: W503 line break before binary operator + and first_row[2].lower() in {"password", "passwd", "pass", "p"} # noqa: W503 + ): + logging.debug(f"Continuing (skipping) over first row: [is_header={True}].") + continue + + # ~~~ END peek at first row ~~~~~~~~~~ + + # Break if we get an empty row at any time + if (not row) or (len(row) != 3) or (not row[1] and not row[2]): + logging.debug(f"Breaking loop since we got an empty row at index={i}.") + break + + u, n, p = row logins.append((rawURL(u), n, p)) return logins