Введение
В этой статье мы разберем как можно генерировать ссылки на модели которые будут использованы для массового добаления связей и фонового открытия моделей, а так же напишем отдельный скрипт который будет читать результат и выдавать окно для выбора.
Создание файлов
Опиши что я хочу:
- Хранить где-то ссылки на объекты в легко редактируемом формате (base_lst.txt)
- Читаем файл base_lst.txt и предлагаем какой объект на сервер хотим просканировать
- Иметь возможность быстро редактировать base_lst.txt
- Нужна функция которая будет проходится по всем папкам указанного пути в поиске .rvt
- Сохранение в txt файл списка адресов моделей
Необходимо обеспечить общедоступность папки в которую мы будем собирать файлы. Таким образом плагины использующие ссылки на модели будут работать у всех пользователей
Начало
Рассмотрим скрипт
1 - задаем кодировку
2-4 - необязательные строчки используемые pyrevit
7-10 - импорт нужных модулей
12 - создание экземпляра окошка в который будем печать тект
13 - метод который будет закрывать прочие окна pyrevit при запуске скрипта
14 - задаем размер окна
16 - записываем путь где будет файл base_lst.txt
Файл предварительно надо создать!
Этот файлик будет хранить в себе пути до объектов на сервер, каждая строчка новый адрес.
Если кто-то не знал на ревит сервер можно попасть через проводник. Появится похожая структура файлов которую мы видим если заходить через Revit Server Administrator, но только там не будет привычных нам моделей - они будут папками
Считываем base_lst.txt
Теперь опишем функцию которая будет открывать и читать содержимое файла base_lst.txt
Данная функция просто по строчно читает файл и декодировав записывает строки в список base_lst
Редактирование файла base_lst
Еще я бы хотел иметь возможность открывать файлик. Опишем и такую функцию
Поиск моделей
Самое интересное - функция для поиска моделей
36 - создаем пустой список
38 - создаем список из названий папок в которых смотреть не надо.
Поясню: во время работы над объектом часто приходится архивировать модели. Самый простой способ это сделать - отсоединить и пересохранить на сервере в характорой папке. Но так как название папки для архива может "плавать" я решил использовать список, перебрав в нем все возможные варианты.
39 - Встроенная функция os.walk() используется для рекурсивного обхода дерева каталогов, начиная с указанного корневого каталога (path). Она возвращает кортеж для каждого каталога, состоящий из трех элементов:
- Текущий каталог (строка): Это путь к каталогу, который обрабатывается в данный момент.
- Список подкаталогов (список строк): Это список имен подкаталогов в текущем каталоге.
- Список файлов (список строк): Это список имен файлов в текущем каталоге.
40 - проходимся по списку имен подкаталогов
41 - проверяем кончается ли он на ".rvt" (это те самые модели которые представлены как папки)
42 - склеиваем имя текущего каталога и имя подкаталога чтобы получалась ссылка на модель
43 - parent_path = os.path.dirname(model_path): Эта строка кода получает путь к родительскому каталогу модели. Функция os.path.dirname() возвращает путь к родительскому каталогу указанного пути.
44 - razdel = os.path.basename(parent_path): строка кода извлекает имя родительского каталога из parent_path с помощью функции os.path.basename(). Это имя каталога присваивается переменной razdel.
45 - проверяем имя папки на то не содержится ли она в списке исключений
46 - добавляем в ранее созданный список
47 - печатаем путь
49 - по итогу возвращаем сформированный список
Чистим ссылки
Интересная особенность: если посмотреть на путь к файлу через проводник тут появляются дополнительные папки типа \Revit Server 2021,\Projects и прочее. Но если мы посмотрим на то, как выглядит путь до модели через Revit, мы увидим что их нет:
Значит это нам не надо. Напишем функцию, которая будет брать полученый путь и чистить от ненужных подпапок:
не очень изящно, но работает
52-58 - Варианты того от чего следует очистить
59 - добавляем "rsn:" в начало и возвращаем чистый и красивый путь по модели на сервере.
Создание txt
Тут все понятно:
67 - указываем путь куда сохранять.
68 - os.path.join(path_txt, name_txt) объединяет путь к директории path_txt и имя файла name_txt, чтобы создать полный путь к файлу, который будет создан.
70-72 - открываем файл в режиме чтения и записываем в него пути которые мы получим из ранее описанной функци find_models. Так же для каждого пути запускаем очистку методом replace_link(link) и меняем кодировку encode('utf-8')
MAIN
Пришло время все запускать
Тут я все закоментировал в коде, но обращу внимание на:
81 - в pyRevit есть способ запуска кнопки через сочетание shift + click. Тут проверяется запустился ли он через шифт и если да, отрываем файл base_lst.txt через блокнот. Это даст нам возможность быстро добавить новый объект.
В противном случае скрипт сначала спросит какую из прочитанных из файла base_lst.txt ссылок надо просканировать
Потом напечатает результат поиска
и спросит
После нажатия "Да" создаст файл с красивыми рабочими ссылками
Если в ссылках останутся не нужные папки - редактируем replace_link(link)
Чтение txt файлов.
Опишем задачи функции:
- Прочитать по указанному пути все файлы
- Сформировать из имен файлов список
- Вывести пользователю список с возможность выбора
- Открыть выбранный файл
- Прочитать содержимое
- Вывести пользователю содержимое с возможностью выбора
- Вернуть результат выбора
Дабы не писать ее в каждый скрипт где она нужно воспользуемся фишкой pyRevit - если помесить скрипт в папку lib в директории вашего расширения, то можно импортировать его
Там написано что надо помещать в папку .panel
но я для удобства поместил чуть повыше - сразу в .extension\lib
Сама функция
Разберем что и где тут происходит:
90 - описываем что нам надо прочитать содержимое папки c помощью метода listdir модуля os.
Данный метод вернет нам список имен файлов, прохожусь по нему и убираю .txt просто для красоты итогового списка который вернет эта функция.
100 - указываю путь
101 - вызываю функцию указав путь
102, 103 - проверяю что список не пустой и вызываю окно выбора через SelectFromList.show
О нем можно почитать тут https://pyrevit.readthedocs.io/en/latest/pyrevit/forms.html
105,106 - проверив что был произведен выбор, склеиваем через join выбранный файл и путь у нему.
108,114 - процесс чтения txt файла и построчная запись в список lst_model_project
117 - отдаем список в уже знакомую нам форму SelectFromList, не забываем установить multiselect = True, что бы иметь возможно выбирать несколько элементов
Итог
Мы научились создавать txt файлы, обновлять и читать. Чтение вынесли в отдельный файл, так как часто будет им пользоваться.
Мне нравится такой подход и на данный момент считаю его оптимальным - появился новый объект:
- Указали ссылку на него
- Провели сканирование
- Сохранили результат