This example shows how to establish database connections, create tasks, and ensure their interconnection without using the Cerebro graphical user interface. In addition, this module demonstrates how to create messages and attach files to them.
This example is in the “pycerebro/examples” directory of the server module.
pycerebro/examples/create_tasks.py
# -*- coding: utf-8 -*-
"""
Examples of Task Creation
This module demonstrates how to establish a connection to the database, create tasks, and link them together without using the Cerebro graphical interface. It also shows how to create messages and attach files to them.
The module uses the py_cerebro package (for Python 3.x), which is included in the service-tools distribution (http://cerebrohq.com/distribs/service-tools.zip). The py_cerebro package contains modules for connecting to the database and for accessing the file storage (Cargador). The py_cerebro package utilizes the third-party package psycopg2 (http://initd.org/psycopg/) to facilitate access to the PostgreSQL database. You may need to install this package separately. Psycopg2 is included in the distribution for all operating systems (in the py-site-packages folder). It can also be downloaded from the developer's website (http://initd.org/psycopg/).
The module contains the following functions:
create_and_link_tasks - Example of creating tasks and establishing connections between them
make_thumnails - generating thumbnails for video files and images
"""
import fnmatch
import sys
import os
import subprocess
import datetime
local_dir = os.path.realpath(__file__).replace('\\', '/').rsplit('/', 1)[0]
backend_dir = local_dir + '/../..'
sys.path.append(backend_dir)
import py_cerebro
from py_cerebro import dbtypes # This module describes various constants, such as data fields, flags, etc.
# Variables that you may need to change to adapt the script for your network
# The following two parameters, host and port, are our main server with the database.
# You may have different parameters if you are using your own database.
database_host = 'cerebrohq.com'
database_port = 45432
cargador_host = 'ss' # The network address of the machine where the Cargador service is running.
# МIt can be specified as a network name or IP address. 'ss' is the name of our server; you can have a different parameter.
cargador_xmlrpc_port = 4040 # Port 4040 is for requests via the XML-RPC protocol.
# Your port may be different; see comments in the cargador module of the py_cerebro package for details.
cargador_http_port = 4080 # Port 4080 is for requests via the HTTP protocol.
# Your port may be different; see comments in the cargador module of the py_cerebro package for more details.
project_name = 'Test project' # Project name for test task addition.
# You can choose any project name you like
mirada_path = '//ss/front/cerebro/mirada.exe' # Path where to launch Mirada for generating thumbnails from.
# This parameter will likely be different for you. See more details in the function.
def create_and_link_tasks(db_user, db_password):
"""
db_user и db_password this is login and password of the Cerebro user
In this example, we will create a task in the project and two subtasks.
We will set a start time for the task, schedule execution times for the subtasks, and link them together.
We will also create messages of the type "task assignment" for the subtasks and attach files to them. In this example, we will not write SQL queries ourselves but will use the functions of the database.Database class, which essentially serve as wrappers around SQL queries. For a description of all functions, refer to the database module in the py_cerebro package.
Example of function call:
::
import create_tasks
create_tasks.create_and_link_tasks('user', 'password')
::
"""
def find(f, seq):
# search for items in the list
for item in seq:
if f(item):
return item
try:
db = py_cerebro.database.Database(database_host, database_port)
# Establishing a database connection
if db.connect_from_cerebro_client() != 0: # trying to establish connection with a launched Cerebro client.
# If it doesn't work, set up with login and password
db.connect(db_user, db_password)
root_tasks = db.root_tasks() # Get a list of project root tasks.
# Looking for the required root task of the project to which we will add tasks.
root_task = find(lambda val: val[dbtypes.TASK_DATA_NAME] == project_name, root_tasks)
# Creating a task in project
new_task_id = db.add_task(root_task[dbtypes.TASK_DATA_ID], 'New Test Task')
"""
The add_task function takes two arguments:
- The identifier of the parent task, in this case, the ID of the project root task
- The name of the task. Please be aware that the task name has certain restrictions. For more details, refer to the description of the add_task function.
The result of the function is the identifier of the new task.
"""
# Setting the start time of the task to the current time
"""
The start time of the task is set in days from 01.01.2000 in UTC.
For more details, refer to the description of the task_set_start function.
"""
datetime_now = datetime.datetime.utcnow()
datetime_2000 = datetime.datetime(2000, 1, 1)
timedelta = datetime_now - datetime_2000
days = timedelta.total_seconds()/(24*60*60)
db.task_set_start(new_task_id, days)
# Create 2 subtasks for the new task
new_subtask_id_1 = db.add_task(new_task_id, 'New Test Subtask 1')
new_subtask_id_2 = db.add_task(new_task_id, 'New Test Subtask 2')
# Adding Task definition with attachments to subtasks
def_id_1 = db.add_definition(new_subtask_id_1, 'Do something 1')
def_id_2 = db.add_definition(new_subtask_id_2, 'Do something 2')
# In the second subtask, we create 5 more tasks.
# For convenience we create 5 copies of the first subtask
lst_for_copy = [(new_subtask_id_1, 'Subtask 1'),
(new_subtask_id_1, 'Subtask 2'),
(new_subtask_id_1, 'Subtask 3'),
(new_subtask_id_1, 'Subtask 4'),
(new_subtask_id_1, 'Subtask 5'),] # Create an array of type [(ID_copied_task, 'New Name'), ...]
new_tasks = db.copy_tasks(new_subtask_id_2, lst_for_copy) # Copy to subtask 2
filename1 = local_dir + '/test.png' # file for the first subtask
thumbnails1 = make_thumnails(filename1) # generating thumnails for filename1
filename2 = local_dir + '/test.mp4' # file for the second subtask
thumbnails2 = make_thumnails(filename2) # generating thumnails for filename2
# Create an object to add files to the file storage (Cargador)
carga = py_cerebro.cargador.Cargador(cargador_host, cargador_xmlrpc_port, cargador_http_port)
# Add files to Task definition messages and export them to storage
db.add_attachment(def_id_1, carga, filename1, thumbnails1, '', False)
db.add_attachment(def_id_2, carga, filename2, thumbnails2, '', False)
"""
The parameter carga is passed for exporting the file to the file storage. For more details, see the cargador module.
The last parameter indicates whether the file will be added as a link, without exporting it to storage (value True), or if it will be exported (value False).
For more details, see the description of the add_attachment function.
"""
# Remove the generated thumbnails since we have already exported them to storage.
for f in thumbnails1:
os.remove(f)
for f in thumbnails2:
os.remove(f)
# Set scheduled time on subtasks
db.task_set_planned_time(new_subtask_id_1, 12.5) # In the first subtask, we set 12 and a half hours.
db.task_set_planned_time(new_subtask_id_2, 30) # In the second subtask, we set 30 hours
# Linking subtasks
db.set_link_tasks(new_subtask_id_1, new_subtask_id_2)
"""
This link means that the second subtask starts when the first subtask is completed. """
except Exception as err:
print(err)
def make_thumnails(filename):
"""
It takes as input the full path to a video or image file and generates thumbnails for them.
:returns: a list of paths to the thumbnail files.
Example of the function call:
::
import create_tasks
filename = 'c:/temp/file.mov'
thumbnails = create_tasks.create_and_link_tasks(filename)
::
Thumbnail generation:
If the file is an image or video, reduced thumbnails can be added for it.
Up to 3 thumbnails can be added (first, middle, last frames).
The Mirada program can be used for generating thumbnails.
It is provided with the Cerebro distribution. Other programs can also be used for generation, such as ffmpeg.
"""
# Example of generating thumbnails using Mirada.
if os.path.exists(filename) == False or os.path.exists(mirada_path) == False:
return list()
gen_path = os.path.dirname(filename) # As a directory for generating thumbnails, we take the directory of the file to be added
# Start Mirada with the necessary keys
res_code = subprocess.call([mirada_path, filename, '-temp', gen_path, '-hide'])
#-temp - directory for generating thumbnails
#-hide - a key to launch Mirada in hidden mode (without loading GUI) to generate thumbnails.
if res_code != 0:
raise Exception("Mirada returned bad exit-status.\n" + mirada_path)
# Looking for thumbnails generated by Mirada.
# Thumbnail name is formed from file name, date and time of creation - filename_yyyymmdd_hhmmss_thumb[number].jpg
#For example: test.mov_20120305_112354_thumb1.jpg - the first thumbnail of video file 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()
"""
# Example of generating thumbnails using ffmpeg.
# In order to generate thumbnails using ffmpeg, you need to know the duration of the video in advance, so that you can correctly obtain the middle and last frames.
# Let's take a 30-second video as an example.
thumbnails = list() # a list of files for thumbnails
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]])
# Keys description you can see in ffmpeg documentation
"""
return thumbnails