#!/usr/bin/python3 """ Import final p111. For each survey in configuration.surveys(), check for new or modified final P1/11 files and (re-)import them into the database. """ import os import sys import pathlib import re import time import configuration import p111 import fwr from datastore import Datastore def add_pending_remark(db, sequence): text = '

Marked as PENDING.

\n' with db.conn.cursor() as cursor: qry = "SELECT remarks FROM raw_lines WHERE sequence = %s;" cursor.execute(qry, (sequence,)) remarks = cursor.fetchone()[0] rx = re.compile("^(.*\n)") m = rx.match(remarks) if m is None: remarks = text + remarks qry = "UPDATE raw_lines SET remarks = %s WHERE sequence = %s;" cursor.execute(qry, (remarks, sequence)) db.maybe_commit() def del_pending_remark(db, sequence): with db.conn.cursor() as cursor: qry = "SELECT remarks FROM raw_lines WHERE sequence = %s;" cursor.execute(qry, (sequence,)) row = cursor.fetchone() if row is not None: remarks = row[0] rx = re.compile("^(.*\n)") m = rx.match(remarks) if m is not None: remarks = rx.sub("",remarks) qry = "UPDATE raw_lines SET remarks = %s WHERE sequence = %s;" cursor.execute(qry, (remarks, sequence)) db.maybe_commit() if __name__ == '__main__': print("Reading configuration") file_min_age = configuration.read().get('imports', {}).get('file_min_age', 10) print("Connecting to database") db = Datastore() surveys = db.surveys() print("Reading surveys") for survey in surveys: print(f'Survey: {survey["id"]} ({survey["schema"]})') db.set_survey(survey["schema"]) try: final_p111 = survey["final"]["p111"] except KeyError: print("No final P1/11 configuration") exit(0) lineNameInfo = final_p111.get("lineNameInfo") pattern = final_p111.get("pattern") if not lineNameInfo: if not pattern: print("ERROR! Missing final.p111.lineNameInfo in project configuration. Cannot import final P111") raise Exception("Missing final.p111.lineNameInfo") else: print("WARNING! No `lineNameInfo` in project configuration (final.p111). You should add it to the settings.") rx = None if pattern and pattern.get("regex"): rx = re.compile(pattern["regex"]) if "pending" in survey["final"]: pendingRx = re.compile(survey["final"]["pending"]["pattern"]["regex"]) for fileprefix in final_p111["paths"]: realprefix = configuration.translate_path(fileprefix) print(f"Path prefix: {fileprefix} → {realprefix}") for globspec in final_p111["globs"]: for physical_filepath in pathlib.Path(realprefix).glob(globspec): physical_filepath = str(physical_filepath) logical_filepath = configuration.untranslate_path(physical_filepath) print(f"Found {logical_filepath}") pending = False if pendingRx: pending = pendingRx.search(physical_filepath) is not None if not db.file_in_db(logical_filepath): age = time.time() - os.path.getmtime(physical_filepath) if age < file_min_age: print("Skipping file because too new", logical_filepath) continue print("Importing") if rx: match = rx.match(os.path.basename(logical_filepath)) if not match: error_message = f"File path not match the expected format! ({logical_filepath} ~ {pattern['regex']})" print(error_message, file=sys.stderr) print("This file will be ignored!") continue file_info = dict(zip(pattern["captures"], match.groups())) file_info["meta"] = {} if lineNameInfo: basename = os.path.basename(physical_filepath) fields = lineNameInfo.get("fields", {}) fixed = lineNameInfo.get("fixed") try: parsed_line = fwr.parse_line(basename, fields, fixed) except ValueError as err: parsed_line = "Line format error: " + str(err) if type(parsed_line) == str: print(parsed_line, file=sys.stderr) print("This file will be ignored!") continue file_info = {} file_info["sequence"] = parsed_line["sequence"] file_info["line"] = parsed_line["line"] del(parsed_line["sequence"]) del(parsed_line["line"]) file_info["meta"] = { "fileInfo": parsed_line } if pending: print("Skipping / removing final file because marked as PENDING", logical_filepath) db.del_sequence_final(file_info["sequence"]) add_pending_remark(db, file_info["sequence"]) continue else: del_pending_remark(db, file_info["sequence"]) p111_data = p111.from_file(physical_filepath) print("Saving") p111_records = p111.p111_type("S", p111_data) file_info["meta"]["lineName"] = p111.line_name(p111_data) db.save_final_p111(p111_records, file_info, logical_filepath, survey["epsg"]) else: print("Already in DB") if pending: print("Removing from database because marked as PENDING") db.del_sequence_final(file_info["sequence"]) add_pending_remark(db, file_info["sequence"]) print("Done")