|  | """ | 
					
						
						|  | معالج ملفات DWG | 
					
						
						|  | """ | 
					
						
						|  |  | 
					
						
						|  | import os | 
					
						
						|  | import re | 
					
						
						|  | import subprocess | 
					
						
						|  | import shutil | 
					
						
						|  | import tempfile | 
					
						
						|  | import traceback | 
					
						
						|  | import pandas as pd | 
					
						
						|  | from pathlib import Path | 
					
						
						|  | import config | 
					
						
						|  | from utils.helpers import create_directory_if_not_exists | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | class DWGHandler: | 
					
						
						|  | """معالج ملفات DWG (AutoCAD)""" | 
					
						
						|  |  | 
					
						
						|  | def __init__(self, converter_path=None): | 
					
						
						|  | """ | 
					
						
						|  | تهيئة معالج ملفات DWG | 
					
						
						|  |  | 
					
						
						|  | المعلمات: | 
					
						
						|  | converter_path: مسار برنامج تحويل DWG (اختياري) | 
					
						
						|  | """ | 
					
						
						|  |  | 
					
						
						|  | self.converter_path = converter_path | 
					
						
						|  |  | 
					
						
						|  | if not self.converter_path: | 
					
						
						|  |  | 
					
						
						|  | if hasattr(config, 'DWG_CONVERTER_PATH') and config.DWG_CONVERTER_PATH: | 
					
						
						|  | self.converter_path = config.DWG_CONVERTER_PATH | 
					
						
						|  | else: | 
					
						
						|  |  | 
					
						
						|  | possible_paths = [ | 
					
						
						|  | r"C:\Program Files\Autodesk\AutoCAD 2022\accoreconsole.exe", | 
					
						
						|  | r"C:\Program Files\Autodesk\AutoCAD 2021\accoreconsole.exe", | 
					
						
						|  | r"C:\Program Files\Autodesk\AutoCAD 2020\accoreconsole.exe", | 
					
						
						|  | r"C:\Program Files\ODA\ODAFileConverter\ODAFileConverter.exe" | 
					
						
						|  | ] | 
					
						
						|  |  | 
					
						
						|  | for path in possible_paths: | 
					
						
						|  | if os.path.exists(path): | 
					
						
						|  | self.converter_path = path | 
					
						
						|  | break | 
					
						
						|  |  | 
					
						
						|  | def convert_to_pdf(self, dwg_path, output_path=None): | 
					
						
						|  | """ | 
					
						
						|  | تحويل ملف DWG إلى PDF | 
					
						
						|  |  | 
					
						
						|  | المعلمات: | 
					
						
						|  | dwg_path: مسار ملف DWG | 
					
						
						|  | output_path: مسار ملف الإخراج (اختياري) | 
					
						
						|  |  | 
					
						
						|  | الإرجاع: | 
					
						
						|  | مسار ملف PDF الناتج | 
					
						
						|  | """ | 
					
						
						|  | try: | 
					
						
						|  |  | 
					
						
						|  | if not os.path.exists(dwg_path): | 
					
						
						|  | raise FileNotFoundError(f"ملف DWG غير موجود: {dwg_path}") | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | if not self.converter_path or not os.path.exists(self.converter_path): | 
					
						
						|  | raise FileNotFoundError("لم يتم العثور على برنامج تحويل DWG") | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | if not output_path: | 
					
						
						|  | output_path = os.path.splitext(dwg_path)[0] + ".pdf" | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | output_dir = os.path.dirname(output_path) | 
					
						
						|  | create_directory_if_not_exists(output_dir) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | if "accoreconsole.exe" in self.converter_path.lower(): | 
					
						
						|  |  | 
					
						
						|  | script_content = f""" | 
					
						
						|  | /i "{dwg_path}" | 
					
						
						|  | /e | 
					
						
						|  | /o "{output_path}" | 
					
						
						|  | """ | 
					
						
						|  | script_path = tempfile.mktemp(suffix=".scr") | 
					
						
						|  | with open(script_path, "w") as f: | 
					
						
						|  | f.write(script_content) | 
					
						
						|  |  | 
					
						
						|  | cmd = [self.converter_path, "/s", script_path] | 
					
						
						|  | result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | 
					
						
						|  |  | 
					
						
						|  | os.unlink(script_path) | 
					
						
						|  |  | 
					
						
						|  | if result.returncode != 0: | 
					
						
						|  | raise RuntimeError(f"فشل في تحويل ملف DWG: {result.stderr}") | 
					
						
						|  |  | 
					
						
						|  | elif "odafileconverter.exe" in self.converter_path.lower(): | 
					
						
						|  |  | 
					
						
						|  | input_dir = os.path.dirname(dwg_path) | 
					
						
						|  | output_dir = os.path.dirname(output_path) | 
					
						
						|  | input_filename = os.path.basename(dwg_path) | 
					
						
						|  | output_format = "PDF" | 
					
						
						|  |  | 
					
						
						|  | cmd = [ | 
					
						
						|  | self.converter_path, | 
					
						
						|  | input_dir, | 
					
						
						|  | output_dir, | 
					
						
						|  | "DWG", | 
					
						
						|  | output_format, | 
					
						
						|  | "1", | 
					
						
						|  | "1", | 
					
						
						|  | input_filename | 
					
						
						|  | ] | 
					
						
						|  |  | 
					
						
						|  | result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | 
					
						
						|  |  | 
					
						
						|  | if result.returncode != 0: | 
					
						
						|  | raise RuntimeError(f"فشل في تحويل ملف DWG: {result.stderr}") | 
					
						
						|  |  | 
					
						
						|  | else: | 
					
						
						|  | raise NotImplementedError(f"برنامج التحويل غير مدعوم: {self.converter_path}") | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | if not os.path.exists(output_path): | 
					
						
						|  | raise FileNotFoundError(f"لم يتم إنشاء ملف PDF: {output_path}") | 
					
						
						|  |  | 
					
						
						|  | return output_path | 
					
						
						|  |  | 
					
						
						|  | except Exception as e: | 
					
						
						|  | error_msg = f"خطأ في تحويل ملف DWG إلى PDF: {str(e)}" | 
					
						
						|  | print(error_msg) | 
					
						
						|  | traceback.print_exc() | 
					
						
						|  | raise Exception(error_msg) | 
					
						
						|  |  | 
					
						
						|  | def extract_quantities(self, dwg_path): | 
					
						
						|  | """ | 
					
						
						|  | استخراج الكميات من ملف DWG | 
					
						
						|  |  | 
					
						
						|  | المعلمات: | 
					
						
						|  | dwg_path: مسار ملف DWG | 
					
						
						|  |  | 
					
						
						|  | الإرجاع: | 
					
						
						|  | DataFrame يحتوي على الكميات المستخرجة | 
					
						
						|  | """ | 
					
						
						|  | try: | 
					
						
						|  |  | 
					
						
						|  | pdf_path = self.convert_to_pdf(dwg_path) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | from utils.pdf_handler import extract_quantities_from_pdf | 
					
						
						|  | return extract_quantities_from_pdf(pdf_path) | 
					
						
						|  |  | 
					
						
						|  | except Exception as e: | 
					
						
						|  | error_msg = f"خطأ في استخراج الكميات من ملف DWG: {str(e)}" | 
					
						
						|  | print(error_msg) | 
					
						
						|  | traceback.print_exc() | 
					
						
						|  | raise Exception(error_msg) | 
					
						
						|  |  | 
					
						
						|  | def extract_text(self, dwg_path): | 
					
						
						|  | """ | 
					
						
						|  | استخراج النص من ملف DWG | 
					
						
						|  |  | 
					
						
						|  | المعلمات: | 
					
						
						|  | dwg_path: مسار ملف DWG | 
					
						
						|  |  | 
					
						
						|  | الإرجاع: | 
					
						
						|  | النص المستخرج من ملف DWG | 
					
						
						|  | """ | 
					
						
						|  | try: | 
					
						
						|  |  | 
					
						
						|  | pdf_path = self.convert_to_pdf(dwg_path) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | from utils.pdf_handler import extract_text_from_pdf | 
					
						
						|  | return extract_text_from_pdf(pdf_path) | 
					
						
						|  |  | 
					
						
						|  | except Exception as e: | 
					
						
						|  | error_msg = f"خطأ في استخراج النص من ملف DWG: {str(e)}" | 
					
						
						|  | print(error_msg) | 
					
						
						|  | traceback.print_exc() | 
					
						
						|  | raise Exception(error_msg) | 
					
						
						|  |  | 
					
						
						|  | def get_dwg_info(self, dwg_path): | 
					
						
						|  | """ | 
					
						
						|  | الحصول على معلومات ملف DWG | 
					
						
						|  |  | 
					
						
						|  | المعلمات: | 
					
						
						|  | dwg_path: مسار ملف DWG | 
					
						
						|  |  | 
					
						
						|  | الإرجاع: | 
					
						
						|  | قاموس يحتوي على معلومات الملف | 
					
						
						|  | """ | 
					
						
						|  | try: | 
					
						
						|  |  | 
					
						
						|  | if not os.path.exists(dwg_path): | 
					
						
						|  | raise FileNotFoundError(f"ملف DWG غير موجود: {dwg_path}") | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | file_info = { | 
					
						
						|  | 'filename': os.path.basename(dwg_path), | 
					
						
						|  | 'path': dwg_path, | 
					
						
						|  | 'size': os.path.getsize(dwg_path), | 
					
						
						|  | 'modified_date': os.path.getmtime(dwg_path) | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | return file_info | 
					
						
						|  |  | 
					
						
						|  | except Exception as e: | 
					
						
						|  | error_msg = f"خطأ في الحصول على معلومات ملف DWG: {str(e)}" | 
					
						
						|  | print(error_msg) | 
					
						
						|  | traceback.print_exc() | 
					
						
						|  | raise Exception(error_msg) | 
					
						
						|  |  | 
					
						
						|  | def is_converter_available(self): | 
					
						
						|  | """ | 
					
						
						|  | التحقق من توفر برنامج تحويل DWG | 
					
						
						|  |  | 
					
						
						|  | الإرجاع: | 
					
						
						|  | True إذا كان برنامج التحويل متوفرًا، False خلاف ذلك | 
					
						
						|  | """ | 
					
						
						|  | return self.converter_path is not None and os.path.exists(self.converter_path) |