MeasurementTesting / google_sheet_Legend.py
Marthee's picture
Update google_sheet_Legend.py
2070f92 verified
# -*- coding: utf-8 -*-
"""Google Sheet to XML.ipynb
Automatically generated by Colaboratory.
Original file is located at
https://colab.research.google.com/drive/1T-b1N8Gq6wwbBurODzJIdhRQNeRbyBnz
"""
from googleapiclient.discovery import build
from google.oauth2 import service_account
import pygsheets
import ast
import re
import pandas as pd
from google.oauth2 import service_account
from googleapiclient.discovery import build
import pygsheets
import tsadropboxretrieval
import requests
import fitz
import numpy as np
from PyPDF2 import PdfReader, PdfWriter
from io import BytesIO
from PyPDF2.generic import NameObject, DictionaryObject, FloatObject, TextStringObject
import dropbox
def authorizeLegend():
SCOPES = [
'https://www.googleapis.com/auth/spreadsheets',
'https://www.googleapis.com/auth/drive',
'https://www.googleapis.com/auth/drive.metadata'
]
credentials = service_account.Credentials.from_service_account_file('credentials.json', scopes=SCOPES)
spreadsheet_service = build('sheets', 'v4', credentials=credentials)
drive_service = build('drive', 'v3', credentials=credentials)
gc = pygsheets.authorize(custom_credentials=credentials, client_secret='credentials.json')
return spreadsheet_service,drive_service,gc
#########################
global gc
global pdfpath0
global pdftitle
global worksheetw
spreadsheet_service,drive_service,gc=authorizeLegend()
#########################
def create_new_sheet(path):
spreadsheet_details = {
'properties': {
'title': path
}
}
sheet = spreadsheet_service.spreadsheets().create(body=spreadsheet_details, fields='spreadsheetId').execute()
spreadsheetId = sheet.get('spreadsheetId')
permission1 = {
'type': 'anyone',
'role': 'writer',
}
drive_service.permissions().create(fileId=spreadsheetId, body=permission1, supportsAllDrives=True).execute()
return spreadsheetId
#########################
def update_sheet(spreadsheetId, SimilarAreaDictionary, pdfpath):
ws = gc.open_by_key(spreadsheetId)
global pdfpath0
pdfpath0=pdfpath
worksheet = ws.worksheet(0)
worksheet.title = 'Legend and data created'
worksheet.clear()
ws.create_developer_metadata('path', pdfpath)
splittedpdfpath = re.split(r'[`\-=~!@#$%^&*()_+\[\]{};\'\\:"|<,/<>?]', pdfpath)
if splittedpdfpath[-2].startswith('2.2') or splittedpdfpath[-2].startswith('2.1'):
worksheet.set_dataframe(start='A1', df=SimilarAreaDictionary)
# if splittedpdfpath[-2].startswith('2.8'):
# DoorsLegend(SimilarAreaDictionary,spreadsheetId)
# return
else:
top_header_format = [
{'mergeCells': { # areas
'mergeType': 'MERGE_ROWS',
'range': {
'sheetId': '0',
'startRowIndex': 1,
'endRowIndex': 2,
'startColumnIndex': 3,
'endColumnIndex': 5
}
}},
{'mergeCells': { # perimeters
'mergeType': 'MERGE_ROWS',
'range': {
'sheetId': '0',
'startRowIndex': 1,
'endRowIndex': 2,
'startColumnIndex': 5,
'endColumnIndex': 7
}
}},
{'mergeCells': { # lengths
'mergeType': 'MERGE_ROWS',
'range': {
'sheetId': '0',
'startRowIndex': 1,
'endRowIndex': 2,
'startColumnIndex': 7,
'endColumnIndex': 9
}
}},
{'mergeCells': { # legend and data created
'mergeType': 'MERGE_ROWS',
'range': {
'sheetId': '0',
'startRowIndex': 0,
'endRowIndex': 1,
'startColumnIndex': 0,
'endColumnIndex': 11
}
}}
]
spreadsheet_service.spreadsheets().batchUpdate(spreadsheetId=spreadsheetId, body={'requests': top_header_format}).execute()
worksheet.cell((1, 1)).value = 'Legend and Data Created'
worksheet.cell((2, 1)).value = 'Guess'
worksheet.cell((2, 2)).value = 'Color'
worksheet.cell((2, 3)).value = 'Count'
worksheet.cell((2, 4)).value = 'Areas'
worksheet.cell((2, 6)).value = 'Perimeters'
worksheet.cell((2, 8)).value = 'Lengths'
worksheet.cell((2, 10)).value = 'Texts'
worksheet.cell((2, 11)).value = 'Comments'
second_row_data = ['Nr', 'm2', 'Total', 'm', 'Total', 'm', 'Total']
worksheet.update_row(3, second_row_data, col_offset=2)
if len(list(SimilarAreaDictionary['Guess']))>0:
worksheet.update_col(1, list(SimilarAreaDictionary['Guess']), row_offset=3)
worksheet.update_col(3, list(SimilarAreaDictionary['Occurences']), row_offset=3)
worksheet.update_col(4, list(SimilarAreaDictionary['Area']), row_offset=3)
worksheet.update_col(5, list(SimilarAreaDictionary['Total Area']), row_offset=3)
worksheet.update_col(6, list(SimilarAreaDictionary['Perimeter']), row_offset=3)
worksheet.update_col(7, list(SimilarAreaDictionary['Total Perimeter']), row_offset=3)
worksheet.update_col(8, list(SimilarAreaDictionary['Length']), row_offset=3)
worksheet.update_col(9, list(SimilarAreaDictionary['Total Length']), row_offset=3)
worksheet.update_col(10, list(SimilarAreaDictionary['Texts']), row_offset=3)
worksheet.update_col(11, list(SimilarAreaDictionary['Comments']), row_offset=3)
if splittedpdfpath[-2].startswith('1.0'):
colorsUsed = [
[SimilarAreaDictionary['R'].iloc[i], SimilarAreaDictionary['G'].iloc[i], SimilarAreaDictionary['B'].iloc[i]]
for i in range(len(SimilarAreaDictionary))
]
elif splittedpdfpath[-2].startswith('3.2') or splittedpdfpath[-2].startswith('3.3') or splittedpdfpath[-2].startswith('2.7'):
colorsUsed = list(SimilarAreaDictionary['Color'])
rowsLen = len(SimilarAreaDictionary.values.tolist())
lastcell = worksheet.cell((rowsLen + 2, 1))
lastcellNotation = str(lastcell.address.label)
columnsLen = len(SimilarAreaDictionary.columns.values.tolist())
lastUsedCol = columnsLen + 1
worksheet.adjust_column_width(start=2, end=3)
worksheet.adjust_column_width(start=10, end=10)
worksheet.adjust_column_width(start=4, end=9, pixel_size=60)
startrow = 3
endColindex = 11
endrow = 3
sheetId = '0'
batch_requests = []
for i in range(len(colorsUsed)):
r, g, b = colorsUsed[i]
batch_requests.append({
"updateCells": {
"range": {
"sheetId": sheetId,
"startRowIndex": i + startrow,
"startColumnIndex": 1,
},
"rows": [
{
"values": [
{
"userEnteredFormat": {
"backgroundColor": {
"red": r / 255,
"green": g / 255,
"blue": b / 255,
"alpha": 0.4,
}
}
}
]
}
],
"fields": "userEnteredFormat.backgroundColor",
}
})
batch_requests.append({
"updateBorders": {
"range": {
"sheetId": sheetId,
"startRowIndex": 0,
"endRowIndex": len(SimilarAreaDictionary) + endrow,
"startColumnIndex": 0,
"endColumnIndex": endColindex
},
"top": {
"style": "SOLID",
"width": 2,
"color": {
"red": 0.0,
"green": 0.0,
"blue": 0.0
}
},
"bottom": {
"style": "SOLID",
"width": 2,
"color": {
"red": 0.0,
"green": 0.0,
"blue": 0.0
}
},
"left": {
"style": "SOLID",
"width": 2,
"color": {
"red": 0.0,
"green": 0.0,
"blue": 0.0
}
},
"right": {
"style": "SOLID",
"width": 2,
"color": {
"red": 0.0,
"green": 0.0,
"blue": 0.0
}
},
"innerHorizontal": {
"style": "SOLID",
"width": 2,
"color": {
"red": 0.0,
"green": 0.0,
"blue": 0.0
}
},
"innerVertical": {
"style": "SOLID",
"width": 2,
"color": {
"red": 0.0,
"green": 0.0,
"blue": 0.0
}
}
}
})
spreadsheet_service.spreadsheets().batchUpdate(spreadsheetId=spreadsheetId, body={'requests': batch_requests}).execute()
model_cell = worksheet.cell('A1')
model_cell.set_text_format('bold', True)
model_cell.set_horizontal_alignment(pygsheets.custom_types.HorizontalAlignment.CENTER)
model_cell.color = (213 / 255, 219 / 255, 255 / 255)
pygsheets.DataRange('A2', 'K2', worksheet=worksheet).apply_format(model_cell)
#########################
def legendGoogleSheets(SimilarAreaDictionary, path, pdfpath, spreadsheetId=0):
titles = gc.spreadsheet_titles()
if path in titles:
ws = gc.open(path)
global pdftitle
pdftitle=path
spreadsheetId = ws.id
else:
spreadsheetId = create_new_sheet(path)
ws=gc.open_by_key(spreadsheetId)
global worksheetw
worksheetw = ws.worksheet(0) #legend
update_sheet(spreadsheetId, SimilarAreaDictionary, pdfpath)
spreadsheet_url = f"https://docs.google.com/spreadsheets/d/{spreadsheetId}"
drive_service.permissions().update(transferOwnership=True, fileId=spreadsheetId, permissionId='11OfoB4Z6wOVII8mYmbnCbbqTQs7rYA65')
namepathArr = [path, spreadsheetId, ws.get_developer_metadata('path')[0].value]
return gc, spreadsheet_service, spreadsheetId, spreadsheet_url, namepathArr
#########################
def mapnametoLegend(McTName,colorsused,pdflink):
sectionKey = McTName.pop()
key=sectionKey[0]
section=sectionKey[1]
# spreadsheet_service,drive_service,gc=authorizeLegend()
spreadsheet_key =str(key) # Please set the Spreadsheet ID.
ws = gc.open_by_key(spreadsheet_key)
# guessednamesfinal=getguessnames(gc,ws)
sheetnames=[]
unit=''
# ws.add_worksheet("Summary") # Please set the new sheet name.
for i in ws._sheet_list:
# print(i)
sheetnames.append(i.title)
# print(i.index)
if 'XML Export Summary' in sheetnames:
worksheetS = ws.worksheet_by_title('XML Export Summary')
else:
ws.add_worksheet("XML Export Summary") # Please set the new sheet name.
global worksheetw
worksheetw = ws.worksheet(0) #legend
worksheetS = ws.worksheet_by_title('XML Export Summary')
summaryId= ws[1].id
worksheetS.clear()
countnames=0
row0=['MC_T Name','Qty','Unit']
worksheetS.update_row(1,row0)
allrows=[]
for i in range(len(McTName)):
allgbnames=''
item=''
# firstpart= re.split(r'[`\-=~!@#$%^&*()_+\[\]{};\'\\:"|<,./<>?]', McTName[i][0])
# print('kkk' ,McTName[i][2])
if McTName[i][2].startswith('Area'):
if section.startswith('1.0') or section.startswith('3.2') or section.startswith('3.3'):
rowvalue=5# column 5
ar=0
unit='m2'
if McTName[i][2].startswith('Perimeter'):
if section.startswith('1.0') or section.startswith('3.2') or section.startswith('3.3'):
rowvalue=7# column 7
ar=0
unit='m'
if McTName[i][2].startswith('Length'):
if section.startswith('1.0') or section.startswith('3.2') or section.startswith('3.3'):
rowvalue=9# column 7
ar=0
unit='m'
if McTName[i][2].startswith('Count'):
if section.startswith('1.0') or section.startswith('3.2') or section.startswith('3.3'):
rowvalue=3# column 7
ar=0
unit='Nr'
if isinstance(McTName[i][1], list):
guessednames=worksheetw.get_col(1, returnas='matrix', include_tailing_empty=False)
for m in McTName[i][1]:
if m:
if m.startswith('text1'):
name=m.removeprefix('text1')
allgbnames+= name +' + '
indices = [o for o, x in enumerate(guessednames) if x == name]
# print(indices)
for j in range(len(indices)):
# print('kjjjj',roww[j])
ar+=float(worksheetw.cell((indices[j]+1 ,rowvalue)).value)
else:
if section.startswith('3.2') or section.startswith('3.3'):
item+=m
else:
item+=m + ' ,'
# print(item)
if section.startswith('3.2') or section.startswith('3.3'):
n= McTName[i][0] + ' ( '+ allgbnames[:-2]+ ' ) '
else:
n= McTName[i][0] + ' ( '+ allgbnames[:-2] +' , ' + item[:-1] + ' ) '
else:
if McTName[i][1].startswith('text1'):
name=McTName[i][1].removeprefix('text1')
allgbnames+= name
roww=worksheetw.find(name)
for j in range(len(roww)):
# print('kjjjj',roww[j])
ar+=float(worksheetw.cell((roww[j].row ,rowvalue)).value)
n= McTName[i][0] + ' ( '+ allgbnames + ' ) '
rowi=[str(n),ar,unit]
allrows.append([rowi[0],unit])
worksheetS.update_row(i+2,rowi)
# worksheetS.adjust_column_width(start=1,end=4)
worksheetS.adjust_column_width(start=1,end=1, pixel_size=350)
worksheetS.adjust_column_width(start=2,end=2, pixel_size=100)
worksheetS.adjust_column_width(start=3,end=3)
guessednamesfinal=getguessnames(worksheetw,colorsused) #gb,color
mctname_guessedNames=label_MC_Tname(allrows) #mctname, gb1
mappedMct_colors=mctname_colors(guessednamesfinal,mctname_guessedNames) #mctname,gb1
adjustannotations(pdflink, mappedMct_colors)
xx=(worksheetS.cell( ( len(McTName) +1 ,3)) ).address.label
model_cell1 =worksheetS.cell('A2')
model_cell1.set_horizontal_alignment( pygsheets.custom_types.HorizontalAlignment.LEFT )
pygsheets.DataRange('A2', str(xx), worksheet=worksheetS).apply_format(model_cell1)
model_cell =worksheetS.cell('A1')
model_cell.set_text_format('bold', True)
model_cell.set_horizontal_alignment( pygsheets.custom_types.HorizontalAlignment.CENTER )
pygsheets.DataRange('A1','C1', worksheet=worksheetS).apply_format(model_cell)
body2={
"requests": [
{
"updateBorders": {
"range": {
"sheetId": str(summaryId),
"startRowIndex": 0,
"endRowIndex": len(McTName) +1 ,
"startColumnIndex": 0,
"endColumnIndex": 3
},
"top": {
"style": "SOLID",
"width": 2,
"color": {
"red": 0.0,
"green":0.0,
"blue":0.0
},
},
"bottom": {
"style": "SOLID",
"width": 2,
"color": {
"red": 0.0,
"green":0.0,
"blue":0.0
},
},
"left":{
"style": "SOLID",
"width":2,
"color": {
"red": 0.0,
"green":0.0,
"blue":0.0
},
},
"right":{
"style": "SOLID",
"width": 2,
"color": {
"red": 0.0,
"green":0.0,
"blue":0.0
},
},
"innerHorizontal":{
"style": "SOLID",
"width":2,
"color": {
"red": 0.0,
"green":0.0,
"blue":0.0
},
},
"innerVertical": {
"style": "SOLID",
"width": 2,
"color": {
"red": 0.0,
"green":0.0,
"blue":0.0
},
},
}
}
]
}
spreadsheet_service.spreadsheets().batchUpdate(spreadsheetId=spreadsheet_key, body=body2).execute()
return summaryId #,guessednamesfinal
# print(x,xarea)
#########################
def label_MC_Tname(mctname_names):
# print('mctname_names',mctname_names)
mctname_guessedNames=[]
# unit=mctname_names[1]
for row in mctname_names:
text=row[0]
unit=row[1]
# print(text,unit)
text_before_parenthesis = text.split('(')[0].strip()
# Step 2: Extract text inside the parentheses
inside_parentheses = re.search(r'\((.*?)\)', text)
if inside_parentheses:
inside_parentheses = inside_parentheses.group(1).strip()
if '+' in inside_parentheses:
# Split the content by '+', and strip any leading/trailing spaces
parts = [part.strip() for part in inside_parentheses.split('+')]
else:
# If no '+', just put the whole content as a single part
parts = [inside_parentheses]
mctname_guessedNames.append([text_before_parenthesis,parts , unit])
# print('mctname_guessedNames',mctname_guessedNames)
return mctname_guessedNames
#########################
def mctname_colors(color_dict, mctname_gb):
# print('color_dict', color_dict)
# print('mctname_gb', mctname_gb)
# Convert the color_dict array into a dictionary with trimmed keys for easier lookup
color_dict_map = {color[0].strip(): color[1] for color in color_dict}
# print('color_dict_map', color_dict_map)
# Result list to store the final output
result = []
# Processing the items
for item in mctname_gb:
name = item[0]
colors = item[1]
unit=item[2]
# print(name,colors)
# Get RGB values for the corresponding colors
color_values = []
for color in colors:
trimmed_color = color.strip() # Trim any leading/trailing spaces
if trimmed_color in color_dict_map:
color_values.append(color_dict_map[trimmed_color])
else:
# Handle missing references (e.g., append None or a default color)
color_values.append(None) # Or append a default color like (0, 0, 0)
# Join the name with the corresponding RGB colors
result.append([name, color_values,unit])
# Print the result
# print('result', result)
return result
#########################
def getguessnames(worksheetw,colorsused):
guessednamesfinal=[]
# print('colorsused',colorsused)
guessednames=worksheetw.get_col(1, returnas='matrix', include_tailing_empty=False)
# print(guessednames)
for i in range(len(guessednames[3:])):
item = guessednames[3:][i] # Name from the guessednames list
colorforitem = colorsused[i] # Get the corresponding color for the current item
if item not in guessednamesfinal:
guessednamesfinal.append([item, colorforitem])
# print('guessednamesfinal', guessednamesfinal)
return guessednamesfinal
#########################
def is_color_within_tolerance(color1, color2, tolerance):
# Ensure both colors are tuples of integers
color1 = tuple(map(int, color1))
color2 = tuple(map(int, color2))
return all(abs(c1 - c2) <= tolerance for c1, c2 in zip(color1, color2))
#########################
def deletefromlegend(deletedrows, SimilarAreaDictionarycopy, section, areaPermArr=[]):
items = []
# print('deletefromlegend',deletedrows)
idx = 0
if section.startswith('1.0') or section.startswith('3.2') or section.startswith('3.3'):
areaPermArr = ast.literal_eval(areaPermArr)
print(areaPermArr)
myDict = eval(SimilarAreaDictionarycopy)
SimilarAreaDictionarycopy = pd.DataFrame(myDict)
strings = deletedrows['content']
print('content',deletedrows)
colors = deletedrows['color']
indicies_toDelete=[]
# print(colors)
# Define your tolerance value
tolerance = 2 # Allowable tolerance for RGB differences
# print(SimilarAreaDictionarycopy)
color_list = list(SimilarAreaDictionarycopy['Color']) # Convert Index/Series to list
if section.startswith('1.0'):
color_list = [ast.literal_eval(color) for color in color_list]
for j in range(len(colors)):
# newitem=str(colors[j]).split('\n \n')
# input_str = " ".join(str(newitem).split())
color = tuple(colors[j]) # Ensure 'color' is in tuple format
found = False
for idx, existing_color in enumerate(color_list):
existing_color = tuple(existing_color) # Ensure it's a tuple for comparison
# print('eee',existing_color,color)
if is_color_within_tolerance(existing_color, color, tolerance):
print(f'Color {color} found close to {existing_color} at index {idx}')
found = True
# print('strings',strings[j])
# matchA = re.search(r"Area=(\d+\.\d+)", strings[j])
# matchP = re.search(r"Perimeter=(\d+\.\d+)", strings[j])
# else:
# matchL = re.search(r"(\d+\.\d+)\s*m(?![a-zA-Z])", strings[j])
comment = SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Comments')]
occ = SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Occurences')]
# Only subtract area if the area value is found
if "Area" in deletedrows['subject'][j]:
matchA = re.search(r"(\d+\.\d+)\s*sq\s*m",strings[j])
print('matchA')
# print(' SimilarAreaDictionaryArea', float(matchA.group(1)), SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Total Area')])
SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Total Area')] =SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Total Area')] - float(matchA.group(1))
# Update area occurrences
if pd.notna(comment) and 'Area' in str(comment):
matches = re.findall(r'\b\d+\b', str(comment))
area_occurrences = int(matches[0]) - 1
perimeter_occurrences = int(matches[1])
else:
area_occurrences = int(SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Occurences')]) - 1
perimeter_occurrences = SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Occurences')]
SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Comments')] = f'Area occurrences: {area_occurrences}, Perimeter occurrences: {perimeter_occurrences}'
if "Perimeter" in deletedrows['subject'][j]:
matchP = re.search(r"(\d+\.\d+)\s*m(?![a-zA-Z])", strings[j])
print('matchP')
SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Total Perimeter')] =SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Total Perimeter')] - float(matchP.group(1))# Replace 'Area' with the actual column name
if pd.notna(comment) and 'Perimeter' in str(comment):
matches = re.findall(r'\b\d+\b', str(comment))
area_occurrences = int(matches[0])
perimeter_occurrences = int(matches[1]) -1
else:
area_occurrences = int(SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Occurences')])
perimeter_occurrences = SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Occurences')]-1
# print(area_occurrences,perimeter_occurrences)
SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Comments')] = f'Area occurrences: {area_occurrences}, Perimeter occurrences: {perimeter_occurrences}'
else:
matchL = re.search(r"(\d+\.\d+)\s*m(?![a-zA-Z])", strings[j])
# Handle occurrences and row deletion
if area_occurrences==0 and perimeter_occurrences==0:
# if area_occurrences ==0 and perimeter_occurrences==0:
if str(idx) not in indicies_toDelete:
indicies_toDelete.append(str(idx))
# print(SimilarAreaDictionarycopy.index[idx],idx)
else:
SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Comments')] = f'Area occurrences: {area_occurrences}, Perimeter occurrences: {perimeter_occurrences}'
if area_occurrences > perimeter_occurrences:
SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Occurences')] = area_occurrences
elif perimeter_occurrences > area_occurrences:
SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Occurences')] = perimeter_occurrences
else:
SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Occurences')] = area_occurrences
if area_occurrences==1:
SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Area')]= SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Total Area')]
if perimeter_occurrences==1:
SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Perimeter')]= SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Total Perimeter')]
if area_occurrences==perimeter_occurrences:
if section.startswith('1.0'):
SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Total Length')] =SimilarAreaDictionarycopy.iloc[int(idx), SimilarAreaDictionarycopy.columns.get_loc('Total Length')] - float(matchL.group(1))# Replace 'Area' with the actual column name
break
if not found:
print(f'Color {color} not found within tolerance')
# print('indicies_toDelete',indicies_toDelete)
SimilarAreaDictionarycopy.drop(index=indicies_toDelete, axis=0, inplace=True)
# print('SimilarAreaDictionarycopy',SimilarAreaDictionarycopy)
return SimilarAreaDictionarycopy
#########################
def DoorsLegend(Dictionary,spreadsheetId):
print('id',spreadsheetId)
global worksheetw
worksheetw.clear()
top_header_format = [
{'mergeCells': { # legend and data created
'mergeType': 'MERGE_ROWS',
'range': {
'sheetId': '0',
'startRowIndex': 0,
'endRowIndex': 1,
'startColumnIndex': 0,
'endColumnIndex': 2
}
}}
]
print('here')
# spreadsheet_service.spreadsheets().batchUpdate(spreadsheetId=spreadsheetId, body={'requests': top_header_format}).execute()
worksheetw.cell((1, 1)).value = 'Legend and Data Created'
worksheetw.set_dataframe(start='A2', df=Dictionary)
print('here1')
body2={
"requests": [
{
"updateBorders": {
"range": {
"sheetId": str(0),
"startRowIndex": 0,
"endRowIndex": 4,
"startColumnIndex": 0,
"endColumnIndex": 2
},
"top": {
"style": "SOLID",
"width": 2,
"color": {
"red": 0.0,
"green":0.0,
"blue":0.0
},
},
"bottom": {
"style": "SOLID",
"width": 2,
"color": {
"red": 0.0,
"green":0.0,
"blue":0.0
},
},
"left":{
"style": "SOLID",
"width":2,
"color": {
"red": 0.0,
"green":0.0,
"blue":0.0
},
},
"right":{
"style": "SOLID",
"width": 2,
"color": {
"red": 0.0,
"green":0.0,
"blue":0.0
},
},
"innerHorizontal":{
"style": "SOLID",
"width":2,
"color": {
"red": 0.0,
"green":0.0,
"blue":0.0
},
},
"innerVertical": {
"style": "SOLID",
"width": 2,
"color": {
"red": 0.0,
"green":0.0,
"blue":0.0
},
},
}
}
]
}
print('here2')
# spreadsheet_service.spreadsheets().batchUpdate(spreadsheetId=spreadsheetId, body=body2).execute()
model_cell = worksheetw.cell('A1')
model_cell.set_text_format('bold', True)
model_cell.set_horizontal_alignment(pygsheets.custom_types.HorizontalAlignment.CENTER)
model_cell.color = (213 / 255, 219 / 255, 255 / 255)
pygsheets.DataRange('A2', 'B2', worksheet=worksheetw).apply_format(model_cell)
print('here3')
return Dictionary
#########################
def deletedoors(deletedrows,dictionary):
items=[]
# print('dletefromlegend2.8')
idx=0
myDict=eval(dictionary)
df_doors=pd.DataFrame(myDict)
strings=deletedrows['content']
print('strings',strings)
for item in strings:
newitem=str(item).split('\n \n')
if 'Single' in str(newitem):
current_value = df_doors.loc[df_doors['Type'] == 'Single Doors', 'Quantity'].values[0]
new_value = int(current_value) - 1
df_doors.loc[df_doors['Type'] == 'Single Doors', 'Quantity'] = str(new_value)
elif 'Double' in str(newitem):
current_value = df_doors.loc[df_doors['Type'] == 'Double Doors', 'Quantity'].values[0]
new_value = int(current_value) - 1
df_doors.loc[df_doors['Type'] == 'Double Doors', 'Quantity'] = str(new_value)
df_doors = df_doors[['Type', 'Quantity']]
print(df_doors)
return df_doors
#########################
def deletemarkups(list1, dbPath, path):
'''list1 : original markup pdf
list2 : deleted markup pdf
deletedrows : deleted markups - difference between both dfs
'''
myDict1 = eval(list1)
list1 = pd.DataFrame(myDict1)
dbxTeam = tsadropboxretrieval.ADR_Access_DropboxTeam('user')
md, res = dbxTeam.files_download(path=dbPath + path)
data = res.content
doc = fitz.open("pdf", data)
# Prepare a DataFrame for the annotations in the new PDF
list2 = pd.DataFrame(columns=['content', 'id', 'subject', 'color'])
for page in doc:
# Iterate through annotations on the page
for annot in page.annots():
# Get the color of the annotation
annot_color = annot.colors
if annot_color is not None:
# Check for fill or stroke color
stroke_color = annot_color.get('stroke')
fill_color = annot_color.get('fill')
v = 'stroke' if stroke_color else 'fill'
color = annot_color.get(v)
if color:
# Convert color to tuple and multiply by 255 to get RGB values
color_tuple = (int(color[0] * 255), int(color[1] * 255), int(color[2] * 255))
# Append annotation data to list2
list2.loc[len(list2)] = [annot.info['content'], annot.info['id'], annot.info['subject'], color_tuple]
# Ensure that colors are stored as tuples (which are hashable)
list1['color'] = list1['color'].apply(lambda x: tuple(x) if isinstance(x, list) else x)
# Find the deleted rows by checking the difference between original and current annotations
deletedrows = pd.concat([list1, list2]).drop_duplicates(keep=False)
# print(deletedrows, len(deletedrows))
flag = 0
if len(deletedrows) != 0:
flag = 1
deletedrows = deletedrows[['content', 'id', 'subject', 'color']]
# Drop rows where 'content' starts with 'Scale'
deletedrows = deletedrows.drop(deletedrows.index[deletedrows['content'].str.startswith('Scale')])
else:
flag = 0
return deletedrows
############################
def adjustannotations(pdflink, color_items):
# Load the input PDF
pdf_content = None
if pdflink and ('http' in pdflink or 'dropbox' in pdflink):
# Modify Dropbox link for direct download
# print('pdffff',pdflink)
if 'dl=0' in pdflink:
pdflink = pdflink.replace('dl=0', 'dl=1')
# Download the PDF content from the shareable link
response = requests.get(pdflink)
pdf_bytes_io = BytesIO(response.content) # Store the content in memory
# pdf_bytes_io = BytesIO(OutputPdfStage1)
reader = PdfReader(pdf_bytes_io)
writer = PdfWriter()
# Append all pages to the writer
writer.append_pages_from_reader(reader)
# Add metadata (optional)
metadata = reader.metadata
writer.add_metadata(metadata)
# Convert color_items array to a more accessible structure (a dictionary of colors)
color_dict = {}
for item in color_items:
label = item[0]
colors = item[1]
unit = item[2]
# print('UNIT', unit)
for color in colors:
color_dict[tuple(color)] = (label, unit) # Map RGB color to a tuple (label, unit)
# print(color_dict)
# Iterate over pages to check annotations and update label
for page_index, page in enumerate(writer.pages):
if "/Annots" in page:
annotations = page["/Annots"]
for annot_index, annot in enumerate(annotations):
obj = annot.get_object()
# Only proceed if the annotation has a color and is a valid markup (e.g., Polygon)
if "/C" in obj:
color = tuple(obj["/C"]) # Extract the RGB color (list of 3 values)
color = (int(round(color[0] * 255, 1)), int(round(color[1] * 255, 1)), int(round(color[2] * 255, 1)))
# If the color matches any item in color_dict, update the label
if color in color_dict:
label, unit = color_dict[color] # Retrieve both label and unit
# print(unit)
# Update annotation label (e.g., /Contents or /Subj)
if "/Contents" in obj:
if unit == 'm2' and "sq m" in obj["/Contents"]:
obj.update({
NameObject("/Label"): TextStringObject(f"{label}")
})
elif unit == 'm' and "m" in obj["/Contents"] and "sq" not in obj["/Contents"]: # Ensure it's not an area
obj.update({
NameObject("/Label"): TextStringObject(f"{label}")
})
# print(f"Updated Annotation: {obj}")
# Save the modified PDF
output_pdf_io = BytesIO()
writer.write(output_pdf_io)
output_pdf_io.seek(0)
# Save the content to a file (avoid using the same name for the variable and file object)
OutputPdfStage2=output_pdf_io.read()
doc2 =fitz.open('pdf',OutputPdfStage2)
dbPath='/TSA JOBS/ADR Test'+pdfpath0+'Measured Plan/'+pdftitle
# dburl=tsadropboxretrieval.uploadanyFile(doc=doc2,pdfname=pdftitle ,path=dbPath)
# print('omarpdf',dburl)
print("Annotations updated and saved")
dbxTeam= tsadropboxretrieval.ADR_Access_DropboxTeam('user')
try:
# Upload the new file and overwrite the existing one
dbxTeam.files_upload(doc2.write() ,dbPath, mode=dropbox.files.WriteMode('overwrite'))
# dbxTeam.files_upload(f.read(), dropbox_file_path, mode=dropbox.files.WriteMode('overwrite'))
print(f"File replaced successfully at")
except dropbox.exceptions.ApiError as e:
print(f"Error replacing the file: {e}")
# return dburl
def getallguessednames():
guessednamesfinal = []
# Retrieve column data from the worksheet
global worksheetw
guessednames = worksheetw.get_col(1, returnas='matrix', include_tailing_empty=False)
if len(guessednames[3:])>0:
# Skip the first three entries and filter out empty/whitespace strings
for item in guessednames[3:]:
if item.strip() and item not in guessednamesfinal: # Remove surrounding whitespace and check for uniqueness
guessednamesfinal.append(item)
print('guessednamesfinal:', guessednamesfinal)
return guessednamesfinal
else:
return 'None'