def populate_categories(): """ask blockchain for categories and update the database """ if app.config["BYPASS_API_CALLS"] or app.config["BYPASS_LEDGER_CALLS"]: return print("Retrieving blockchain categories ...") categories = get_blockchain_categories() # delete old categories if their UUID's no longer exists new_uuids = [category_dict["uuid"] for category_dict in categories] parts = db_session.query(Part).all() for category in db_session.query(Category).all(): if category.uuid not in new_uuids: db_session.delete(category) # delete all the parts relations that had this category for part in parts: for part_category in part.categories: if part_category.uuid == category.uuid: part.categories.remove(part_category) db_session.flush() # update existing or insert new categories for category_dict in categories: category_query = db_session.query(Category).filter( Category.uuid == category_dict["uuid"]) if category_query.count() == 1: # update category = category_query.one() category.name = category_dict["name"] category.description = category_dict["description"] else: # insert category = Category() category.uuid = category_dict["uuid"] category.name = category_dict["name"] category.description = category_dict["description"] db_session.add(category) db_session.flush() db_session.commit()
def delete_part(): """json route for deleting a part. expects part_id. """ response_data = {} data = request.json # validate supplier password response_data["incorrect_password"] = \ not supplier_password_is_correct(data["supplier_id"], data["password"]) if response_data["incorrect_password"]: return jsonify(response_data) # make sure that the part exists part_query = db_session.query(Part).filter(Part.id == data["part_id"]) response_data["part_exists"] = (part_query.count() == 1) if not response_data["part_exists"]: return jsonify(response_data) try: part = part_query.one() db_session.delete(part) db_session.flush() if part.envelope: delete_envelope(part.envelope) db_session.commit() response_data["failed"] = False except: response_data["failed"] = True response_data["error_message"] = stacktrace() return jsonify(response_data)
def delete_envelope(envelope): """delete envelope and all its associated artifacts, boms, and files """ if envelope.boms: boms = envelope.boms[:] envelope.boms = [] db_session.flush() for bom in boms: bomitems = bom.items[:] bom.items = [] db_session.flush() for item in bomitems: db_session.delete(item) db_session.flush() db_session.delete(bom) db_session.flush() artifacts = envelope.artifacts[:] envelope.artifacts = [] db_session.flush() for artifact in artifacts: db_session.delete(artifact) artifact_path = os.path.join(app.config["ARTIFACT_FOLDER"], artifact.checksum) if os.path.exists(artifact_path): os.remove(artifact_path) db_session.delete(envelope) db_session.flush() db_session.commit() shutil.rmtree(envelope.extract_dir)
def reset_handler(): """respond to conductor call RESET by purging the database and repopulating with sample data """ response_data = {} try: # clear all the tables for part in db_session.query(Part).all(): part.categories = [] part.envelope = None part.supplier = None db_session.delete(part) db_session.flush() db_session.query(Category).delete() db_session.query(Supplier).delete() for envelope in db_session.query(Envelope).all(): envelope.boms = [] envelope.artifacts = [] db_session.delete(envelope) db_session.flush() for bom in db_session.query(BOM).all(): bom.items = [] bom.artifact = None db_session.delete(bom) db_session.flush() db_session.query(Artifact).delete() db_session.query(BOMItem).delete() db_session.flush() db_session.commit() # delete all envelope and artifact files empty_directory(app.config["UPLOAD_FOLDER"]) empty_directory(app.config["ARTIFACT_FOLDER"]) # insert suppliers for supplier_dict in read_csv_file("suppliers.csv"): supplier = Supplier() supplier.name = supplier_dict["name"] supplier.uuid = supplier_dict["uuid"] supplier.password = hashlib.md5(codecs.encode(supplier_dict["password"], "utf-8"))\ .hexdigest() supplier.blockchain = (supplier_dict["blockchain"] == "true") if supplier.blockchain: supplier.save_to_blockchain() db_session.add(supplier) db_session.flush() # insert categories categories_by_uuid = {} for category_dict in read_csv_file("categories.csv"): category = Category() category.name = category_dict["name"] category.uuid = category_dict["uuid"] category.description = category_dict["description"] db_session.add(category) category.save_to_blockchain() categories_by_uuid[category.uuid] = category db_session.flush() # read part category association table part_category_instances = {} for part_category_relation in read_csv_file("part-categories.csv"): if part_category_relation[ "part_uuid"] not in part_category_instances: part_category_instances[ part_category_relation["part_uuid"]] = [] part_category_instances[part_category_relation["part_uuid"]].append( \ categories_by_uuid[part_category_relation["category_uuid"]]) # insert parts categories = db_session.query(Category).all() for part_dict in read_csv_file("parts.csv"): part = Part() part_supplier_query = db_session.query(Supplier)\ .filter(Supplier.uuid == part_dict["supplier_uuid"]) assert part_supplier_query.count() == 1, \ "Invalid supplier UUID in the following sample part. \n" \ + json.dumps(part_dict) + " Could not find a supplier with UUID '" \ + part_dict["supplier_uuid"] + "'" part.supplier = part_supplier_query.one() part.blockchain = (part_dict["blockchain"] == "true") for field in ["uuid", "usku", "supplier_part_id", "name", "version", \ "licensing", "url", "status", "description", "checksum", "src_uri"]: setattr(part, field, part_dict[field]) if part.uuid in part_category_instances: for category in part_category_instances[part.uuid]: part.categories.append(category) db_session.add(part) if part.blockchain: part.save_to_blockchain() for category in part.categories: save_part_category_relation(part, category) save_part_supplier_relation(part, part.supplier) db_session.flush() # read envelope part association table envelope_parts = {} for envelope_parts_dict in read_csv_file("part-envelopes.csv"): envelope_parts[envelope_parts_dict[ "envelope_uuid"]] = envelope_parts_dict["part_uuid"] # unpack and parse envelopes for envelope_path in glob.glob(\ os.path.join(app.config["SAMPLE_DATA_FOLDER"], "envelopes/*")): envelope = create_envelope(envelope_path) part_query = db_session.query(Part).filter( Part.uuid == envelope_parts[envelope.uuid]) assert part_query.count() == 1, \ "Invalid sample data. No part was found with UUID " + envelope_parts[envelope.uuid] part = part_query.one() part.envelope = envelope envelope.blockchain = part.blockchain if envelope.blockchain: envelope.save_to_blockchain() save_part_envelope_relation(part, envelope) db_session.flush() db_session.commit() response_data["status"] = "success" except AssertionError as error: response_data["status"] = "failed" response_data["error_message"] = str(error) except APIError as error: response_data["status"] = "failed" response_data["error_message"] = "Encountered an error while calling blockchain API. " \ + str(error) except (OSError, IOError): response_data["status"] = "failed" response_data["error_message"] = stacktrace() except: response_data["status"] = "failed" response_data[ "error_message"] = "Unhandled Exception \n\n" + stacktrace() return jsonify(response_data)