Source code for pipeLion.assets.project

import datetime, time
from collections import OrderedDict
from pipeLion.assets.abstractGroup import AbstractGroup
from pipeLion.core.id import Id
from pipeLion.core.dataElement import DataElement
from pipeLion.connections import allConnections


[docs]class Project(AbstractGroup): """ The Project-class is derived by AbstractGroup. it is special as it has no children as it is the topmost element in the dataFlow. The project-Node holds a Store of all nodes connected to this project in the database. """ _type = 'Project' ## allAssets is the data-dictionary which holds all Nodes of a project sorted by baseId,Id and version allAssets = {} _additionalAssetDict = OrderedDict([ ('user', None), ('start_date' , datetime.datetime.today()), ('end_date' , datetime.datetime.today()), ('bid_days' , 0), ('connectedTo' , None), ('outputTypes' , None), ('inputTypes' , None), ('state' , 0), ('fps' , 25), ('stereo', False), ('mainView', ''), ('resolution' , '1920x1080'), ('miscFormats', None), ('producer' , None), ('pipelineTd' , None), ('objectives' , ''), ('logline' , ''), ('image' , ''), ('workOnWeekends', False), ('blocked_days', None), ('stafflist', None), ('description', ''), ('review', ''), ('tags', ''), ('referenceFiles', None), ]) def __init__(self, name, project='', id=None, producer=None, td = None): """ the constructor calls the initializeProject function to setup all the special functionalities of the project-nodes """ self.allAssets = {} if producer: self._additionalAssetDict['producer'] = producer.baseId() if td: self._additionalAssetDict['pipelineTd'] = td.baseId() or None super(Project, self).__init__(name, name, id) self.setInputTypes(['GroupConnection', 'EditConnection']) self.setOutput(['ProjectConnection']) self.initializeProject() self.setupFunctions() self.setupAdditionalGroupReimplementations() self.allAssets.update(self.findAssets()) self.connectAssets() if not self.blocked_days(): self.set_blocked_days([]) if not self.miscFormats(): self.set_miscFormats([]) if not self.stafflist(): self.set_stafflist([])
[docs] def additionalInitializeFromAssetDict(self, assetDict): """ this method is a reimplementment of DataElement to be able to set the possible connections correctly """ super(Project, self).additionalInitializeFromAssetDict(assetDict) self.set_producer(assetDict['producer']) self.set_pipelineTd(assetDict['pipelineTd'])
[docs] def initializeProject(self): """ this method checks for the existence of the project-table. If there is none, it will create one. if there is one it will load all assets in the allAssets instance variable by calling the findAssets method """ if not self.client.sendRequest('StandardServices', 'projectTableExists', {"name":self.name()}): self.client.sendRequest('StandardServices', 'insertTable', {'project':self.name(), 'type':'project'}) self.allAssets = OrderedDict() else: self.getProjectInfo() self.allAssets[self.baseId()] = OrderedDict([('ids', OrderedDict([])),('versions',OrderedDict([]))]) self.allAssets[self.baseId()]['ids'][self.id] = self self.allAssets[self.baseId()]['versions'][-1] = self self.allAssets[self.baseId()]['versions'][self.version()] = self
[docs] def getProjectInfo(self): """ this will add itself to the allAssets dictionary '""" nodeInfo = self.client.sendRequest('AssetServices', 'getProjectNodes', {"project":self.name()}) self.id = nodeInfo['id'] self.set_baseId(nodeInfo['baseId']) self.setSettingsFromDict(self, nodeInfo['data'])
[docs] def findAssets(self, all=True): """ this method will make a database request to get all Nodes within a project. in case the all-argument is truned off, it will only create the latest and connected nodes from the dataBase. it will return a dictionary which looks like this:: {'baseId': { 'versions': { 0:[node_version0] 1: [node_version1] -1: [pointer to 1] } 'ids' { Id1:[node_version1] Id2:[node_version0] } } } :param all: indicates if the nodes should be filtered :type all: bool :returns: dictionary of all Nodes, which looks like in the example above :rtype: dictionary """ if not all: request = 'getActiveAssetsFromProject' else: request = 'getAllAssetsFromProject' assetInfo = self.client.sendRequest('AssetServices', request, {"project":self.name()}) assets = {} for eachBaseId, eachVersionDict in assetInfo.iteritems(): eachBaseId = Id(eachBaseId) assets[eachBaseId] = OrderedDict([('ids', OrderedDict([])),('versions',OrderedDict([(-1,None)]))]) for eachVersion, eachAssetTuple in eachVersionDict.iteritems(): currentAsset = DataElement.fromAssetDict(eachAssetTuple[0], eachAssetTuple[-1]) if currentAsset.deleted(): if assets.has_key(currentAsset.baseId()): assets.pop(currentAsset.baseId()) break assets[eachBaseId]['ids'][currentAsset.id] = currentAsset assets[eachBaseId]['versions'][currentAsset.version()] = currentAsset if not assets[eachBaseId]['versions'][-1] \ or assets[eachBaseId]['versions'][-1].version() < currentAsset.version(): assets[eachBaseId]['versions'][-1] = currentAsset return assets
[docs] def getListOfAssetsObjects(self): """ this method will put all latest versions into a list of all Nodes :returns: list of all Nodes in the latest version :rtype: list of AbstractAsset """ allAssetsList = [] for eachBaseId in self.allAssets: allAssetsList.append(self.allAssets[eachBaseId]['versions'][-1]) return allAssetsList
[docs] def connectAssets(self): """ method is called by the initializeProject function and will setup all connections inbetween the loaded nodes """ for eachAsset in self.getListOfAssetsObjects(): for baseId in eachAsset.connectedTo(): eachAsset.connect(self.allAssets[baseId]['versions'][-1])
def addUnpublishedAsset(self, asset): self.allAssets[asset.baseId()] = { 'versions' : { asset.version() : asset, -1 : asset }, 'ids' : { asset.id : asset } } def removeAssetFromProject(self, asset): for eachDependentAsset in asset.getDependencies(): eachDependentAsset.disconnect(asset) eachDependentAsset.publish() for eachChild in self.children: asset.disconnect(eachChild) asset.set_deleted(True) self.allAssets.pop(asset.baseId()) asset.publish() self.publish()
[docs] def addBlockedDay(self, year, month, day): """ method will add a day to the blocked_days list, which will indicate the days at which this user is unavailable for project-work :param year: the year :type year: int :param month: the month :type month: int :param day: the day :type day: int """ allBlockedDays = self.blocked_days() allBlockedDays = list(set(allBlockedDays)|set([datetime.date(year=year, month=month, day=day)])) self.set_blocked_days(allBlockedDays)
[docs] def getBlockedDays(self): """ will return a list of datetime objects, with all blocked dates in it. if given a project, it will be taken to account, wether the projects supports weekend-work or not :returns: a list of datetime.date objects, indicating the days at which all users working on this project are blocked from work :rtype: list """ allBlockedDays = list(set(self.blocked_days())) if not self.workOnWeekends(): start = datetime.date(year=self.startDate().year, month=self.startDate().month, day=self.startDate().day) end = datetime.date(year=self.endDate().year, month=self.endDate().month, day=self.endDate().day) for i in xrange((end-start).days+1): day = start + datetime.timedelta(days=i) if day.weekday() >= 5: allBlockedDays.append(day) allBlockedDays = [datetime.date(year=each.year, month=each.month, day=each.day) for each in allBlockedDays] return allBlockedDays
def getFormatSpecification(self, format): for eachFormat, eachValue in self.miscFormats(): if eachFormat == format: return eachValue else: return None