import gradio as gr from zipfile import ZipFile, BadZipFile import tempfile import os import re import pandas as pd import collections import json import glob from io import BytesIO # Padrões de IA ai_patterns = [ "PIC*", "PersonalImageClassifier*", "Look*", "LookExtension*", "ChatBot", "ImageBot", "TMIC","TeachableMachine*", "TeachableMachineImageClassifier*", "SpeechRecognizer*", "FaceExtension*","Pose*","Posenet","PosenetExtension", "Eliza*", "Alexa*" ] # Padrões para cada categoria drawing_and_animation_patterns = ["Ball", "Canvas", "ImageSprite"] maps_patterns = ["Map", "Marker", "Circle", "FeatureCollection", "LineString", "Navigation","Polygon", "Retangle" ] sensors_patterns = ["AccelerometerSensor", "BarcodeScanner", "Barometer", "Clock", "GyroscopeSensor", "Hygrometer", "LightSensor", "LocationSensor", "MagneticFieldSensor", "NearField","OrientationSensor", "ProximitySensor","Thermometer", "Pedometer"] social_patterns = ["ContactPicker", "EmailPicker", "PhoneCall", "PhoneNumberPicker", "Texting", "Twitter"] storage_patterns = ["File", "CloudDB", "DataFile", "Spreadsheet", "FusiontablesControl", "TinyDB", "TinyWebDB"] connectivity_patterns = ["BluetoothClient", "ActivityStarter", "Serial", "BluetoothServer", "Web"] def extract_components_using_regex(scm_content): pattern = r'"\$Type":"(.*?)"' components = re.findall(pattern, scm_content) if 'roboflow' in scm_content.lower(): components.append("Using Roboflow") return components def extract_category_components(components, patterns): category_components = [] for component in components: for pattern in patterns: if component.startswith(pattern): category_components.append(component) return category_components def extract_extensions_from_aia(file_path: str): extensions = [] with ZipFile(file_path, 'r') as zip_ref: for file_path in zip_ref.namelist(): if file_path.endswith('components.json') and 'assets/external_comps/' in file_path: with zip_ref.open(file_path) as file: components_json_content = file.read().decode('utf-8', errors='ignore') components_data = json.loads(components_json_content) for component in components_data: extension_type = component.get("type", "") if extension_type: extensions.append(extension_type) return extensions def count_events_in_bky_file(bky_content): # Counting the number of occurrences of the "component_event" blocks return bky_content.count(' 1 else "N/A" # Extracting app name and version using regular expressions for line in project_properties_lines: app_name_match = re.match(r'aname=(.*)', line) if app_name_match: app_name = app_name_match.group(1) app_version_match = re.match(r'versionname=(.*)', line) if app_version_match: app_version = app_version_match.group(1) # Complementary method for extracting the app name from .scm files if app_name == "N/A": print("O campo App Name não foi encontrado em project.properties. Tentando encontrar em arquivos .scm...") app_name = extract_app_name_from_scm_files(temp_dir) print(f"Nome do App encontrado nos arquivos .scm: {app_name}") # ... return { 'timestamp': timestamp, 'app_name': app_name, 'app_version': app_version, 'authURL': authURL } def extract_ai_components(components): ai_components = [] for component in components: for pattern in ai_patterns: if '*' in pattern and component.startswith(pattern[:-1]): ai_components.append(component) elif component == pattern: ai_components.append(component) if "roboflow" in ' '.join(components).lower(): ai_components.append("Using Roboflow") return ai_components def extract_media_files(file_path: str): media_files = [] with ZipFile(file_path, 'r') as zip_ref: for file_path in zip_ref.namelist(): if 'assets/' in file_path and not file_path.endswith('/'): media_files.append(os.path.basename(file_path)) return media_files def list_components_in_aia_file(file_path): results_df = pd.DataFrame(columns=[ 'aia_file', 'project_info', 'components', 'IA components', 'screens', 'operators', 'variables', 'events', 'extensions', 'Media', 'Drawing and Animation', 'Maps', 'Sensors', 'Social', 'Storage', 'Connectivity']) # ... pd.set_option('display.max_colwidth', None) file_name = os.path.basename(file_path) # ... restante do código ... components_list = [] number_of_screens = 0 operators_count = 0 variables_count = 0 events_count = 0 # Adicione esta variável para contar os eventos # Extrair arquivos de mídia media_files = extract_media_files(file_path) media_summary = ', '.join(media_files) # Extracting project information project_info = extract_project_info_from_properties(file_path) project_info_str = f"Timestamp: {project_info['timestamp']}, App Name: {project_info['app_name']}, Version: {project_info['app_version']}, AuthURL: {project_info['authURL']}" with tempfile.TemporaryDirectory() as temp_dir: with ZipFile(file_path, 'r') as zip_ref: zip_ref.extractall(temp_dir) scm_files = glob.glob(temp_dir + '/src/appinventor/*/*/*.scm') bky_files = glob.glob(temp_dir + '/src/appinventor/*/*/*.bky') # Esta linha define bky_files number_of_screens = len(scm_files) for scm_file in scm_files: with open(scm_file, 'r', encoding='utf-8', errors='ignore') as file: content = file.read() components = extract_components_using_regex(content) components_list.extend(components) operators_count += len(re.findall(r'[+\-*/<>!=&|]', content)) variables_count += len(re.findall(r'"\$Name":"(.*?)"', content)) # Extração dos componentes de cada categoria drawing_and_animation_summary = ', '.join(extract_category_components(components_list, drawing_and_animation_patterns)) maps_summary = ', '.join(extract_category_components(components_list, maps_patterns)) sensors_summary = ', '.join(extract_category_components(components_list, sensors_patterns)) social_summary = ', '.join(extract_category_components(components_list, social_patterns)) storage_summary = ', '.join(extract_category_components(components_list, storage_patterns)) connectivity_summary = ', '.join(extract_category_components(components_list, connectivity_patterns)) # Adicione este bloco para contar os eventos nos arquivos .bky # Extracting extensions from .bky files extensions_list = [] extensions_list = extract_extensions_from_aia(file_path) for bky_file in bky_files: with open(bky_file, 'r', encoding='utf-8', errors='ignore') as file: bky_content = file.read() events_count += count_events_in_bky_file(bky_content) #extensions_list.extend(extract_extensions_from_bky(bky_content)) # Creating a summary of the extracted extensions extensions_summary = ', '.join(list(set(extensions_list))) components_count = collections.Counter(components_list) components_summary = [f'{comp} ({count} x)' if count > 1 else comp for comp, count in components_count.items()] ai_components_summary = extract_ai_components(components_list) results_df = results_df.append({ 'aia_file': file_name, 'project_info': project_info_str, 'components': ', '.join(components_summary), 'IA components': ', '.join(ai_components_summary), 'screens': number_of_screens, 'operators': operators_count, 'variables': variables_count, 'events': events_count, 'extensions': extensions_summary, 'Media': media_summary, 'Drawing and Animation': drawing_and_animation_summary, 'Maps': maps_summary, 'Sensors': sensors_summary, 'Social': social_summary, 'Storage': storage_summary, 'Connectivity': connectivity_summary }, ignore_index=True) return results_df # Define a altura máxima para o output e habilite a rolagem # Adicione a variável de estilo CSS ao início do seu código, fora da função analyze_aia output_style = """ """ # Esta será a função que a interface do Gradio irá chamar def analyze_aia(uploaded_file): try: # Obtendo o caminho do arquivo a partir do objeto uploaded_file file_path = uploaded_file.name if hasattr(uploaded_file, 'name') else None if file_path and os.path.exists(file_path): with ZipFile(file_path, 'r') as zip_ref: with tempfile.TemporaryDirectory() as temp_dir: zip_ref.extractall(temp_dir) results_df = list_components_in_aia_file(file_path) # Inclua o estilo CSS na resposta HTML html_result = results_df.to_html(escape=False, classes="output-html") return output_style + f'
{html_result}
' else: return output_style + "Não foi possível localizar o arquivo .aia." except BadZipFile: return output_style + "Falha ao abrir o arquivo .aia como um arquivo zip. Ele pode estar corrompido ou não é um arquivo .aia válido." except Exception as e: return output_style + f"Erro ao processar o arquivo: {str(e)}" iface = gr.Interface( fn=analyze_aia, inputs=gr.File(), outputs=gr.HTML(), title="AIA-Scope", description="Upload an .aia file to analyze its components.", live=False # Isso garante que o botão Submit seja necessário ) if __name__ == "__main__": iface.launch(debug=True)