5.2. Пример добавления сообщения типа «Отчет».¶
Этот пример демонстритует, как можно устанавливать соединение с базой данных, создавать сообщения и прикладывать файлы без использования графического интерфейса Cerebro. Его можно использовать, например, для создания отчетов из Nuke, Maya и других программных продуктах, в которых возможно исполнение питоновских скриптов.
Пример находится в папке «py_cerebro/examples» серверного модуля.
py_cerebro/examples/report.py
# -*- coding: utf-8 -*-
"""
Пример добавления сообщения типа "Отчет".
Этот модуль демонстритует, как можно устанавливать соединение с базой данных,
создавать сообщения и прикладывать файлы без использования графического интерфейса Cerebro.
Его можно использовать, например, для создания отчетов из Nuke, Maya и других программных продуктах,
в которых возможно исполнение питоновских скриптов.
Модуль использует пакет py_cerebro (для Python 3.x), который входит в дистрибутив service-tools (http://cerebrohq.com/distribs/service-tools.zip).
Пакет py_cerebro содержит модули для установки соединения с базой данных
и для доступа к файловому хранилищу(Cargador).
Пакет py_cerebro использует сторонний пакет psycopg2 (http://initd.org/psycopg/)
для осущевстления доступа к базе данных PostgreSQL. Возможно вам придется дополнительно установить этот пакет.
Psycopg2 поставляется в дистрибутиве для всех операционных систем (папка py-site-packages). Также его можно
скачать с сайта разработчика (http://initd.org/psycopg/).
Модуль содержит функцию add_report_to_task для добавления сообщения с приложенным файлом.
Также, в этом модуле описана функция get_task_and_message_ids - пример получения идентификаторов задачи
и её сообщения типа "Постановка задачи" по локатору(пути) задачи.
Для добавления сообщения необходимо вызвать функцию add_report_to_task
и передать ей необходимые параметры.
"""
import fnmatch
import sys
import os
import subprocess
local_dir = os.path.realpath(__file__).replace('\\', '/').rsplit('/', 1)[0]
backend_dir = local_dir + '/..'
sys.path.append(backend_dir)
backend_dir = local_dir + '/../..'
sys.path.append(backend_dir)
from py_cerebro import dbtypes, database, cargador, cclib # в этом модуле описаны различные константы, такие как поля данных, флаги и т.п.
# Переменные, которые вам возможно придется изменить, чтобы преспособить сктипт для вашей сети
mirada_path = '//ss/front/cerebro/mirada.exe' # Путь, откуда запускать мираду для генерации эскизов.
#У вас этот параметр скорее всего будет иным.
#Следующие два параметра, хост и порт - это наш главный сервер с базой данных.
#У вас эти параметры могут быть иными, если вы используете свою базу данных
database_host = 'cerebrohq.com'
database_port = 45432
cargador_host = 'ss' # Cетевой адрес машины, где работает севрис каргадор.
# Может быть задано сетевое имя или IP адрес. 'ss' - это имя нашего сервера, у вас этот параметр скорее всего будет иным.
cargador_xmlrpc_port = 4040 # Порт 4040 - это порт для запросов по xmlrpc протоколу.
#У вас порт может быть иным, подробнее об этом смотрите в комментариях модуля cargador пакета py-backend.
cargador_http_port = 4080 # Порт 4080 - это порт для запросов по http протоколу.
#У вас порт может быть иным, подробнее об этом смотрите в комментариях модуля cargador пакета py-backend.
def add_report_to_task(task_url, db_user, db_password, text, work_time, file, file_as_link):
"""
Функция по добавлению нового сообщения.
Параметр task_url - тектовый локатор(путь) до задачи.
Формат локатора: '/Проект/Задача 1/Задача 2', то есть по сути путь до задачи.
Примечание: Имена задач регистрозависимы!
Параметры db_user и db_password - логин и пароль пользователя Cerebro, который создает отчет.
Параметр text - текс сообщения
Параметр work_time - затраченные часы
Параметр file - путь до файла, который должен быть приложен
Параметр file_as_link - способ добавления файла к сообщению:
True - файл добавляется как ссылка;
False - файл добавляется как вложение, то есть импортируется в файловое хранилище(Cargador).
Пример вызова функции:
::
import report
report.add_report_to_task('/Проект/Задача 1/Задача 2', 'user', 'password', 'Example report', 1.5, 'с:/temp/Test.file', False)
::
"""
try:
db = database.Database(database_host, database_port)
# Устанавливаем соединение с базой данных
if db.connect_from_cerebro_client() != 0: # пробуем установить соединение с помощью запущенного клиента Cerebro.
# Если не выходит, устанавливаем с помощью логина и пароля
db.connect(db_user, db_password)
# Получение идентификатора задачи и сообщения типа "Постановка задачи" по локатору задачи
task = db.task_by_url(task_url) # Получили ID задач
if len(task) == 0 or task[0] == None: # Проверяем существуют ли задачи с таким локатором
raise Exception('Задача не найдена')
messages = db.task_definition(task[0]) # Получили сообщения задачи
if len(messages) == 0: # Проверяем есть ли у задачи сообщения
raise Exception('Сообщение отсутствует')
parent_message = messages[dbtypes.MESSAGE_DATA_ID] # Получили ID сообщения
if parent_message == None or parent_message == 0:
raise Exception('Сообщение отсутствует')
"""
Параметры task и parent_message - это идентификаторы задачи и сообщения к которому добавляется новое сообщение.
"""
# Создание сообщения типа "Отчет"
new_message_id = db.add_report(task[0], parent_message, text, int(work_time*60))
"""
Выполняем запрос на добавление нового соообщения.
Последний параметр, затраченное время, задается в минутах
Результатом запроса является идентификатор нового сообщения
"""
# Приложение файла к отчету
if file != None and len(file) != 0 and os.path.exists(file): # проверяем, задан ли файл, который нужно приложить к отчету
# генерация эскизов для файла file
thumbnails = make_thumnails(file)
"""
Если файл является изображением или видео, то можно добавить для него уменшенные эскизы.
Можно добавить до 3-х эскизов (первый, средний, последний кадры).
Для генерации эскизов в этом примере мы будем использовать программу Mirada.
Она постовляется вместе с дистрибутивом Cerebro. Можно использовать и другие программы для генерации,
например, ffmpeg. Смотрите подробнее об этом в описании функции make_thumnails.
"""
# Создаем объект для добавления файла и/или эскизов в файловое хранилище (Cargador)
carga = cargador.Cargador(cargador_host, cargador_xmlrpc_port, cargador_http_port)
"""
Если файл прикладывается как ссылка, то сам файл не будет
"""
# Добовляем к отчету постановки задач файлы и, заодно, экспортируем их в хранилище
db.add_attachment(new_message_id, carga, file, thumbnails, '', file_as_link)
"""
Если файл прикладывается как ссылка, то сам файл не будет экспортироваться в хранилище,
но будут экспортированы эскизы.
Пустая строка - это комментарий к вложению. Можете его задать по желанию.
"""
except Exception as err:
print(err)
def make_thumnails(filename):
"""
Принимает на вход полный путь до файла видео или изображения и генерирует эскизы к ним
Возвращает список путей до файлов эскизов.
Генерация эскизов:
Если файл является изображением или видео, то можно добавить для него уменшенные эскизы.
Можно добавить до 3-х эскизов (первый, средний, последний кадры).
Для генерации эскизов можно использовать программу Mirada.
Она постовляется вместе с дистрибутивом Cerebro. Можно использовать и другие программы для генерации,
например, ffmpeg.
"""
#Пример генерации эскизов с помощью Mirada.
if os.path.exists(filename) == False or os.path.exists(mirada_path) == False:
return list()
gen_path = os.path.dirname(filename) # В качестве директории для генерации эскизов возьмем директорию добавляемого файла
# Запускаем мираду с необходимыми ключами
res_code = subprocess.call([mirada_path, filename, '-temp', gen_path, '-hide'])
#-temp - директория для генерации эскизов
#-hide - ключ запуска мирады в скрытом режиме (без загрузки графического интерфейса) для генерации табнейлов.
if res_code != 0:
raise Exception("Mirada returned bad exit-status.\n" + mirada_path)
#Ищем сгенерированные мирадой эскизы.
#Имени эскиза формируется из имени файла, даты и времени генерации - filename_yyyymmdd_hhmmss_thumb[number].jpg
#Например: test.mov_20120305_112354_thumb1.jpg - первый эскиз видео-файла test.mov
thumbnails = list()
for f in os.listdir(gen_path):
if fnmatch.fnmatch(f, os.path.basename(filename) + '_*_thumb?.jpg'):
thumbnails.append(gen_path + '/' + f)
thumbnails.sort()
"""
#Пример генерации эскизов с помощью ffmpeg.
#Для того, чтобы генерить эскизы с помощью ffmpeg, нужно заранее знать длительность видео,
#чтобы корректно получить средний и последний кадры.
#Возьмем к примеру ролик длительностью в 30 секунд.
thumbnails = list() # список файлов для эскизов
thumbnails.append(filename + '_thumb1.jpg')
thumbnails.append(filename + '_thumb2.jpg')
thumbnails.append(filename + '_thumb3.jpg')
subprocess.call(['ffmpeg', '-i', filename, '-s', '512x512', '-an', '-ss', '00:00:00', '-r', 1, '-vframes', 1, '-y', thumbnails[0]])
subprocess.call(['ffmpeg', '-i', filename, '-s', '512x512', '-an', '-ss', '15:00:00', '-r', 1, '-vframes', 1, '-y', thumbnails[1]])
subprocess.call(['ffmpeg', '-i', filename, '-s', '512x512', '-an', '-ss', '30:00:00', '-r', 1, '-vframes', 1, '-y', thumbnails[2]])
# Описание ключей вы можете посмотреть в документации к ffmpeg
"""
return thumbnails