Path: blob/main/scripts/reports/inventory_legacy_uploader.py
1128 views
import json1import lmfdb.inventory_app.inventory_helpers as ih2import lmfdb.inventory_app.lmfdb_inventory as inv3import lmfdb.inventory_app.inventory_db_core as invc4from lmfdb.inventory_app.inventory_upload_data import (upload_collection_structure, extract_specials, delete_all_tables, recreate_rollback_table, MAX_SZ, delete_by_collection)56def upload_all_structure(db, structure_dat):7"""Upload an everything from a structure json document89db -- LMFDB connection to inventory database10structure_dat -- JSON document containing all db/collections to upload11"""1213inv.log_dest.info("_____________________________________________________________________________________________")14inv.log_dest.info("Processing structure data")15n_dbs = len(structure_dat.keys())16progress_tracker = 01718for DB_name in structure_dat:19progress_tracker += 120inv.log_dest.info("Uploading " + DB_name+" ("+str(progress_tracker)+" of "+str(n_dbs)+')')21invc.set_db(db, DB_name, DB_name)2223for coll_name in structure_dat[DB_name]:24inv.log_dest.info(" Uploading collection "+coll_name)25orphaned_keys = upload_collection_structure(db, DB_name, coll_name, structure_dat, fresh=False)26if len(orphaned_keys) != 0:27with open('Orph_'+DB_name+'_'+coll_name+'.json', 'w') as file:28file.write(json.dumps(orphaned_keys))29inv.log_dest.info(" Orphans written to Orph_"+ DB_name+'_'+coll_name+'.json')3031def upload_from_files(db, master_file_name, list_file_name, fresh=False):32"""Upload an entire inventory. CLOBBERS CONTENT3334db -- LMFDB connection to inventory database35master_file_name -- path to report tool database structure file36list_file_name -- path to file containing list of all additional inventory info files37fresh -- set to sync tables according to whether this is a fresh or new upload38"""39#For a complete upload is more logical to fill things in thing by thing40#so we do all the db's first, then the collections and finish with the additional description4142decoder = json.JSONDecoder()43structure_dat = decoder.decode(read_file(master_file_name))4445inv.log_dest.info("_____________________________________________________________________________________________")46inv.log_dest.info("Processing autogenerated inventory")47n_dbs = len(structure_dat.keys())48progress_tracker = 04950for DB_name in structure_dat:51progress_tracker += 152inv.log_dest.info("Uploading " + DB_name+" ("+str(progress_tracker)+" of "+str(n_dbs)+')')53invc.set_db(db, DB_name, DB_name)5455for coll_name in structure_dat[DB_name]:56inv.log_dest.info(" Uploading collection "+coll_name)57orphaned_keys = upload_collection_structure(db, DB_name, coll_name, structure_dat, fresh=fresh)58if len(orphaned_keys) != 0:59with open('Orph_'+DB_name+'_'+coll_name+'.json', 'w') as file:60file.write(json.dumps(orphaned_keys))61inv.log_dest.info(" Orphans written to Orph_"+ DB_name+'_'+coll_name+'.json')6263inv.log_dest.info("_____________________________________________________________________________________________")64inv.log_dest.info("Processing additional inventory")65file_list = read_list(list_file_name)66last_db = ''67progress_tracker = 068for file in file_list:69data = decoder.decode(read_file(file))70record_name = ih.get_description_key(file)71DB_name = record_name[0]72if DB_name != last_db:73inv.log_dest.info("Uploading " + DB_name+" ("+str(progress_tracker)+" of <="+str(n_dbs)+')')74last_db = DB_name75progress_tracker += 176coll_name = record_name[1]77inv.log_dest.info(" Uploading collection "+coll_name)7879upload_collection_description(db, DB_name, coll_name, data)808182def upload_collection_from_files(db, db_name, coll_name, master_file_name, json_file_name, fresh=False):83"""Freshly upload inventory for a single collection. CLOBBERS CONTENT8485db -- LMFDB connection to inventory database86db_name -- Name of database this collection is in87coll_name -- Name of collection to upload88master_file_name -- path to report tool database structure file89json_file_name -- path to file containing additional inventory data90fresh -- set to skip some syncing if this is a fresh or new upload91"""9293decoder = json.JSONDecoder()9495inv.log_dest.info("Uploading collection structure for "+coll_name)96structure_data = decoder.decode(read_file(master_file_name))9798#Do we need to keep the orphans?99#orphaned_keys = upload_collection_structure(db, db_name, coll_name, structure_data, fresh=fresh)100upload_collection_structure(db, db_name, coll_name, structure_data, fresh=fresh)101102inv.log_dest.info("Uploading collection description for "+coll_name)103data = decoder.decode(read_file(json_file_name))104upload_collection_description(db, db_name, coll_name, data, fresh=fresh)105106def upload_collection_description(db, db_name, coll_name, data, fresh=False):107"""Upload the additional description108109db -- LMFDB connection to inventory database110db_name -- Name of database this collection is in111coll_name -- Name of collection to upload112data -- additional data as json object for this collection113fresh -- whether to delete existing info (otherwise extra description will be added, overwriting if required, but anything absent from new info will not be clobbered114115Note this only uploads actual data. All mandatory fields should have been filled by the structure upload116"""117118try:119db_entry = invc.get_db_id(db, db_name)120_c_id = invc.get_coll_id(db, db_entry['id'], coll_name)121if not (db_entry['exist'] and _c_id['exist']):122#All dbs/collections should have been added from the struc: if not is error123inv.log_dest.error("Cannot add descriptions, db or collection not found")124return125except Exception as e:126inv.log_dest.error("Failed to refresh collection "+str(e))127128try:129split_data = extract_specials(data)130#Insert the notes and info fields into the collection131try:132notes_data = split_data[inv.STR_NOTES]133notes_data = ih.blank_all_empty_fields(notes_data)134inv.log_dest.debug(notes_data)135except Exception:136notes_data = None137try:138info_data = split_data[inv.STR_INFO]139info_data = ih.blank_all_empty_fields(info_data)140inv.log_dest.debug(info_data)141except Exception:142info_data = None143_c_id = invc.set_coll(db, db_entry['id'], coll_name, coll_name, notes_data, info_data)144except Exception as e:145inv.log_dest.error("Failed to refresh collection info "+str(e))146147try:148for field in split_data['data']:149dat = split_data['data'][field]150if not ih.is_record_name(dat):151inv.log_dest.info(" Processing "+field)152invc.set_field(db, _c_id['id'], field, dat, type='human')153else:154inv.log_dest.info(" Processing record "+field)155#Data may not actually contain the name or description fields156rec_set = {'hash':field}157try:158rec_set['name'] = dat['name']159except Exception:160pass161try:162rec_set['description'] = dat['description']163except Exception:164pass165invc.set_record(db, _c_id['id'], rec_set, type='human')166167except Exception as e:168inv.log_dest.error("Failed to refresh collection "+str(e))169170def read_file(filename):171"""Read entire file contents """172with open(filename, 'r') as in_file:173dat = in_file.read()174return dat175176def read_list(listfile):177"""Read file line-wise into list of lines """178with open(listfile, 'r') as in_file:179lines = in_file.read().splitlines()180return lines181182#Initial uploader routines ---------------------------------------------------------------183184def fresh_upload(master_file_name, list_file_name):185"""Delete existing data and upload a fresh copy.186CLOBBERS ALL EXISTING CONTENT187188Arguments:189190- master_file_name -- path to structure file from report tool (e.g. lmfdb_structure.json)191192- list_file_name -- path to file containing names of all json files to upload (one per collection)193"""194got_client = inv.setup_internal_client(editor=True)195if not got_client:196inv.log_dest.error("Cannot connect to db")197return198db = inv.int_client[inv.get_inv_db_name()]199200#DELETE all existing inventory!!!201delete_all_tables(db)202203upload_from_files(db, master_file_name, list_file_name, fresh=True)204recreate_rollback_table(db, MAX_SZ)205206def fresh_upload_coll(db_name, coll_name, master_file_name, json_file_name):207"""Delete existing data and upload a fresh copy for a single collection.208CLOBBERS ALL EXISTING CONTENT FOR THIS COLLECTION209210Arguments:211212- db_name -- name of database to refresh213- coll_name -- name of collection to refresh214- master_file_name -- path to structure file from report tool (entire or single collection)215- json_file_name -- path to additional json file for this collection216"""217got_client = inv.setup_internal_client(editor=True)218if not got_client:219inv.log_dest.error("Cannot connect to db")220return221db = inv.int_client[inv.get_inv_db_name()]222223delete_by_collection(db, db_name, coll_name)224upload_collection_from_files(db, db_name, coll_name, master_file_name, json_file_name, fresh=True)225226227