Читаем Написание скриптов для Blender 2.49 полностью

   Blender.UnpackAll(Blender.UnpackModes.USE_ORIGINAL)

Функция GetPaths() из модуля Blender выдаёт список всех файлов, используемых .blend-файлом (за исключением самого этого .blend-файла). Мы передаем ей аргумент  absolute установленным в Истину, чтобы извлекать имена файлов с полным путём вместо относительных путей от текущего каталога для того, чтобы сравнить их должным образом со списком, произведённым функцией listfiles().

Снова мы также нормализуем эти имена файлов. Выделенная строка показывает, как мы извлекаем абсолютный путь текущего каталога, передавая условное обозначение для текущего каталога Блендера ( // ) в функцию expandpath():

   files = [os.path.normpath(f) for f in

             Blender.GetPaths(absolute=True)]

   currentdir = Blender.sys.expandpath('//')

Затем мы создаём объект ZipFile в режиме write (записи). Это отбросит любой существующий архив с тем же именем, и позволит нам добавлять файлы в архив. Полное имя архива строится соединением текущего каталога Блендера и имени, которое мы хотим использовать для архива. Использование функции join() из модуля os.path обеспечивает нам создание полного имени платформо-независимым образом. Мы установили аргумент debug (отладка) объекта ZipFile в значение 3, чтобы сообщать о чём-либо необычном на консоль при создании архива:

   zip = ZipFile(os.path.join(currentdir,zipname),'w')

   zip.debug = 3

В переменную removefiles (удаление файлов) записываются имена файлов, которые мы хотим удалить после того, как мы создали архив. Мы можем безопасно удалить файлы и каталоги только после того, как мы создали архив, иначе может оказаться, что мы ссылаемся на каталоги, которые больше не существуют.

Архив создаётся проходом цикла по списку всех файлов в текущем каталоге Блендера и сравниванием их со списком файлов, использованных нашим .blend-файлом. Любой файл с таким расширением, как например, .blend или .blend1 пропускается (выделено), как и сам архив. Файлы добавляются к ZIP-файлу использованием метода write(), который принимает в качестве параметра имя файла с путём относительно архива (и, следовательно, текущего каталога). Этот путь удобнее для распаковки архива в новом месте. Любые ссылки на файлы за пределами текущего дерева каталогов не затрагиваются функцией relpath(). Любой файл, который мы добавляем к архиву, помечается для удаления добавлением его к списку removefiles. Наконец, мы закрываем архив - важный шаг, поскольку, если его опустить, мы можем остаться с запорченным архивом:

   removefiles = []

   for f in listfiles(currentdir):

      if not (f in files

            or os.path.splitext(f)[1].startswith('.blend')

            or os.path.basename(f) == zipname):

         rf = os.path.relpath(f,currentdir)

         zip.write(rf)

         removefiles.append(f)

   zip.close()

Последней задачей будет удаление файлов, которые мы переместили в архив. Функция remove() из модуля Питона os выполнит это, но мы также хотим удалить любой каталог, который остался пустым после удаления файлов. Следовательно, для каждого файла, который мы удаляем, нам надо определить имя его каталога. Мы также удостоверяемся, этот каталог не указывает на текущий каталог, потому что мы хотим быть абсолютно уверены, что мы не удаляем его, так как это место, где находятся наши .blend-файлы. Хотя это маловероятный сценарий, что можно открыть .blend-файл в Блендере и удалить сам этот .blend файл, что могло бы оставить каталог пустым. Если мы удалим этот каталог, любое последующее (авто) сохранение должно потерпеть неудачу. Функция relpath() возвращает точку, если каталог, переданный как первый аргумент, указывает на тот же каталог, что и каталог, переданный как второй аргумент. (Функция  samefile() является более надежной и прямой, но не доступна в Windows.)

Если мы убедились, что мы не ссылаемся на текущий каталог, мы используем функцию removedirs(), чтобы удалить каталог. Если каталог не пуст, произойдёт ошибка с исключением OSError (то есть, файл, который мы удалили, был не последним файлом в каталоге), которую мы игнорируем. Функция removedirs() также удалит все родительские каталоги, ведущие к каталогу только тогда, когда они пустые, и это как раз то, что нам нужно:

   for f in removefiles:

      remove(f)

      d = os.path.dirname(f)

      if os.path.relpath(d,currentdir) != '.':

         try:

            removedirs(d)

         except OSError:

            pass

if __name__ == '__main__':

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных