#!/usr/bin/env python # coding: utf-8 import os import shutil import tempfile import zipfile import requests import streamlit as st import xml.etree.ElementTree as ET def elevation_change(bcf_list, z_error_correction_in_metres: float): update_data_list = [] for individual_file in file_list: if 'viewpoint' in individual_file: bcf_guid = individual_file.split('/', 1)[0] parsed_markup_file = file_open.open(bcf_guid + '/markup.bcf') xml_tree_markup = ET.parse(parsed_markup_file) xml_root_markup = xml_tree_markup.getroot() for topic_data in xml_root_markup.iter('Topic'): component_guids = [] component_batids = [] parsed_viewpoint_file = file_open.open(individual_file) xml_tree_viewpoint = ET.parse(parsed_viewpoint_file) xml_root_viewpoint = xml_tree_viewpoint.getroot() updateZValue(xml_root_viewpoint, 'CameraViewPoint', z_error_correction_in_metres) for bitmap_data in xml_root_viewpoint.iter('Bitmap'): updateZValue(bitmap_data, 'Location', z_error_correction_in_metres) for clipping_plane_data in xml_root_viewpoint.iter('ClippingPlane'): updateZValue(clipping_plane_data, 'Location', z_error_correction_in_metres) for line_data in xml_root_viewpoint.iter('Line'): updateZValue(line_data, 'StartPoint', z_error_correction_in_metres) updateZValue(line_data, 'EndPoint', z_error_correction_in_metres) individual_xml_update = { 'individual_file':individual_file, 'xml_string_update': ET.tostring(xml_root_viewpoint) } update_data_list.append(individual_xml_update) return update_data_list def updateZip(zipname, filename, data): # generate a temp file tmpfd, tmpname = tempfile.mkstemp(dir=os.path.dirname(zipname)) os.close(tmpfd) # create a temp copy of the archive without filename with zipfile.ZipFile(zipname, 'r') as zin: with zipfile.ZipFile(tmpname, 'w') as zout: zout.comment = zin.comment # preserve the comment for item in zin.infolist(): if item.filename != filename: zout.writestr(item, zin.read(item.filename)) # replace with the temp archive os.remove(zipname) os.rename(tmpname, zipname) # now add filename with its new data with zipfile.ZipFile(zipname, mode='a', compression=zipfile.ZIP_DEFLATED) as zf: zf.writestr(filename, data) def updateZipForMultipleFiles(file_names_and_data, zipname='temp.zip'): # generate a temp file # test_dataset.save_to_disk("test.hf") tmpfd, tmpname = tempfile.mkstemp(dir=os.path.dirname(zipname)) os.close(tmpfd) # create a temp copy of the archive without filename with zipfile.ZipFile(zipname, 'r') as zin: with zipfile.ZipFile(tmpname, 'w') as zout: zout.comment = zin.comment # preserve the comment for item in zin.infolist(): if not 'viewpoint' in item.filename: zout.writestr(item, zin.read(item.filename)) # replace with the temp archive os.remove(zipname) os.rename(tmpname, zipname) # now add filename with its new data for individual_update in file_names_and_data: with zipfile.ZipFile(zipname, mode='a', compression=zipfile.ZIP_DEFLATED) as zf: zf.writestr(individual_update['individual_file'], individual_update['xml_string_update']) return True def updateZValue(xml_data, xml_element_to_iterate, z_error_correction_in_metres): for location_data in xml_data.iter(xml_element_to_iterate): existing_z = float(location_data.find('Z').text) new_z = existing_z + z_error_correction_in_metres location_data.find('Z').text = str(new_z) st.markdown( ''' # Adjust the height of all issues in a BCF file Provide any bcf file. Select the height adjustment in metres. ''' ) bcf_file_button = st.text_input( "Dropbox link to BCF file", key="bcf_file_button" ) # In[ ]: if bcf_file_button: bcf_file_path = st.session_state.bcf_file_button path_original = 'original.zip' path_updated = 'temp.zip' if '=0' in bcf_file_path: bcf_file_path = bcf_file_path.replace('=0', '=1') if '.bcf' in bcf_file_path: updated = False partial_filename = bcf_file_path.rsplit('/')[-1] filename = partial_filename.split('.bcf')[0] bcf_file_path = bcf_file_path.replace('.bcf', '.zip') r = requests.get(bcf_file_path, stream=True) if r.status_code == 200: with open(path_original, 'wb') as f: for chunk in r: f.write(chunk) shutil.copy2(path_original, path_updated) file_open = zipfile.ZipFile(path_original) file_list = file_open.namelist() height_change_button = st.number_input( "Height of the sheet to be returned", format="%.3f", value=0.000, min_value=-1000.0, max_value=1000.0, step=0.001, key="height_change_button" ) if height_change_button: height_change = st.session_state.height_change_button update_bcf_info = elevation_change( file_list, height_change, ) updated = updateZipForMultipleFiles( update_bcf_info, ) if updated: with open(path_updated, "rb") as fp: btn = st.download_button( label="Download BCF file", data=fp, file_name=f"{filename}_height_{height_change}.bcf", mime="application/zip" ) else: st.write('Please provide a valid BCF file')