#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
**operations.py**
**Platform:**
Windows, Linux, Mac Os X.
**Description:**
This module defines Application Database operations objects.
**Others:**
"""
#**********************************************************************************************************************
#*** External imports.
#**********************************************************************************************************************
import os
import re
#**********************************************************************************************************************
#*** Internal imports.
#**********************************************************************************************************************
import foundations.common
import foundations.exceptions
import foundations.strings
import sibl_gui.components.core.database.exceptions
from sibl_gui.components.core.database.types import Collection
from sibl_gui.components.core.database.types import IblSet
from sibl_gui.components.core.database.types import Template
#**********************************************************************************************************************
#*** Module attributes.
#**********************************************************************************************************************
__author__ = "Thomas Mansencal"
__copyright__ = "Copyright (C) 2008 - 2013 - Thomas Mansencal"
__license__ = "GPL V3.0 - http://www.gnu.org/licenses/"
__maintainer__ = "Thomas Mansencal"
__email__ = "thomas.mansencal@gmail.com"
__status__ = "Production"
__all__ = ["LOGGER",
"DATABASE_EXCEPTIONS",
"DEFAULT_SESSION_MAKER",
"DEFAULT_SESSION",
"createSession",
"getSession",
"commit",
"addItem",
"addStandardItem",
"removeItem",
"removeStandardItem",
"updateItemContent",
"updateItemLocation",
"filterItems",
"itemExists",
"getIblSets",
"filterIblSets",
"iblSetExists",
"addIblSet",
"removeIblSet",
"updateIblSetContent",
"updateIblSetLocation",
"checkIblSetsTableIntegrity",
"getCollections",
"filterCollections",
"getCollectionsByType",
"collectionExists",
"addCollection",
"removeCollection",
"getCollectionsIblSets",
"getCollectionIblSetsCount",
"getCollectionTemplatesCount",
"getTemplates",
"filterTemplates",
"templateExists",
"addTemplate",
"removeTemplate",
"updateTemplateContent",
"updateTemplateLocation",
"checkTemplatesTableIntegrity"]
LOGGER = foundations.verbose.installLogger()
DATABASE_EXCEPTIONS = {
sibl_gui.components.core.database.exceptions.MissingIblSetFileError : "Ibl Set's file is missing!",
sibl_gui.components.core.database.exceptions.MissingIblSetIconError : "Ibl Set's icon is missing!",
sibl_gui.components.core.database.exceptions.MissingIblSetPreviewImageError : "Ibl Set's preview image is missing!",
sibl_gui.components.core.database.exceptions.MissingIblSetBackgroundImageError : "Ibl Set's background image is missing!",
sibl_gui.components.core.database.exceptions.MissingIblSetLightingImageError : "Ibl Set's lighting image is missing!",
sibl_gui.components.core.database.exceptions.MissingIblSetReflectionImageError : "Ibl Set's reflection image is missing!",
sibl_gui.components.core.database.exceptions.MissingTemplateFileError : "Template file is missing!",
sibl_gui.components.core.database.exceptions.MissingTemplateHelpFileError : "Template help file is missing!"}
DEFAULT_SESSION_MAKER = None
DEFAULT_SESSION = None
#**********************************************************************************************************************
#*** Module classes and definitions.
#**********************************************************************************************************************
[docs]def createSession():
"""
This definition creates a default session.
:return: Database session. ( Session )
"""
return DEFAULT_SESSION_MAKER()
[docs]def getSession(session=None):
"""
This definition returns either given session or the default one.
:param session: Database session. ( Session )
:return: Database session. ( Session )
"""
if session is not None:
return session
if DEFAULT_SESSION is not None:
return DEFAULT_SESSION
else:
LOGGER.warning("!> {0} | Default session is not set, creating one!".format(__name__))
[docs]def query(*args, **kwargs):
"""
This definition queries given session or the default one.
:param \*args: Arguments. ( \* )
:param \*\*kwargs: Keywords arguments. ( \*\* )
:return: Query result. ( Object )
"""
return getSession(kwargs.get("session")).query(*args, **kwargs)
#*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(sibl_gui.components.core.database.exceptions.DatabaseOperationError)
[docs]def commit(session=None):
"""
This definition commits changes to the Database.
:param session: Database session. ( Session )
:return: Database commit success. ( Boolean )
"""
session = getSession(session)
try:
session.commit()
return True
except Exception as error:
session.rollback()
raise sibl_gui.components.core.database.exceptions.DatabaseOperationError(
"{0} | Database commit error: '{1}'".format(__name__, error))
[docs]def addItem(item, session=None):
"""
This definition adds an item to the Database.
:param item: Item to add. ( Database object )
:param session: Database session. ( Session )
:return: Database commit success. ( Boolean )
"""
LOGGER.debug("> Adding: '{0}' item to the Database.".format(item))
session = getSession(session)
session.add(item)
return commit(session)
[docs]def addStandardItem(type, name, path, collection, session=None):
"""
This definition adds a new standard item to the Database.
:param type: Item type. ( Object )
:param name: Item name. ( String )
:param path: Item path. ( String )
:param collection: Collection id. ( String )
:param session: Database session. ( Session )
:return: Database commit success. ( Boolean )
"""
LOGGER.debug("> Adding: '{0}' '{1}' to the Database.".format(name, type.__name__))
session = getSession(session)
if not filterItems(query(type), "^{0}$".format(re.escape(path)), "path"):
osStats = ",".join((foundations.strings.encode(stat) for stat in os.stat(path)))
databaseItem = type(name=name, path=path, collection=collection, osStats=osStats)
if databaseItem.setContent():
return addItem(databaseItem, session)
else:
LOGGER.warning("!> {0} | '{1}' '{2}' path already exists in Database!".format(__name__, path, type.__name__))
return False
[docs]def removeItem(item, session=None):
"""
This definition removes an item from the Database.
:param item: Item to remove. ( Database object )
:param session: Database session. ( Session )
:return: Database commit success. ( Boolean )
"""
LOGGER.debug("> Removing: '{0}' item from the Database.".format(item))
session = getSession(session)
session.delete(item)
return commit(session)
[docs]def removeStandardItem(type, identity, session=None):
"""
This definition removes a standard item from the Database.
:param type: Item type. ( Object )
:param identity: Item id. ( String )
:param session: Database session. ( Session )
:return: Database commit success. ( Boolean )
"""
LOGGER.debug("> Removing item type '{0}' with id '{1}' from the Database.".format(type.__name__, identity))
item = session.query(type).filter_by(id=identity).one()
return removeItem(item, getSession(session))
[docs]def updateItemContent(item, session=None):
"""
This definition update an item content.
:param item: Item to set content. ( IblSet )
:param session: Database session. ( Session )
:return: Database commit success. ( Boolean )
"""
LOGGER.debug("> Updating '{0}' '{1}' content.".format(item.name, item.__class__.__name__))
item.osStats = ",".join(map(foundations.strings.encode, os.stat(item.path)))
if item.setContent():
return commit(getSession(session))
else:
LOGGER.warning("!> {0} | '{1}' '{2}' content update failed!".format(__name__,
item.name,
item.__class__.__name__))
return False
[docs]def updateItemLocation(item, path, session=None):
"""
This definition updates an item location.
:param item: Item to update. ( Object )
:param path: Item path. ( Path )
:param session: Database session. ( Session )
:return: Database commit success. ( Boolean )
"""
LOGGER.debug("> Updating '{0}' '{1}' location.".format(item, item.__class__.__name__))
session = getSession(session)
if not filterItems(query(item.__class__), "^{0}$".format(re.escape(path)), "path"):
item.path = path
return updateItemContent(item, session)
else:
LOGGER.warning("!> {0} | '{1}' '{2}' path already exists in Database!".format(__name__,
path,
item.__class__.__name__))
return False
[docs]def filterItems(items, pattern, field, flags=0):
"""
This definition filters items from the Database.
:param items: Database items. ( List )
:param pattern: Filtering pattern. ( String )
:param field: Database field to search into. ( String )
:param flags: Flags passed to the regex engine. ( Integer )
:return: Filtered items. ( List )
"""
return [item for item in items if re.search(pattern, foundations.strings.encode(item.__dict__[field]), flags)]
[docs]def itemExists(items, pattern, field, flags=0):
"""
This definition returns if given item exists in the Database.
:param items: Database items. ( List )
:param pattern: Filtering pattern. ( String )
:param field: Database field to search into. ( String )
:param flags: Flags passed to the regex engine. ( Integer )
:return: Filtered items. ( List )
"""
return filterItems(items, pattern, field, flags) and True or False
[docs]def getIblSets(session=None):
"""
This definition returns the Ibl Sets from the Database.
:param session: Database session. ( Session )
:return: Database Ibl Sets. ( List )
"""
return getSession(session).query(IblSet)
[docs]def filterIblSets(pattern, field, flags=0, session=None):
"""
This definition filters the sets from the Database.
:param pattern: Filtering pattern. ( String )
:param field: Database field to search into. ( String )
:param flags: Flags passed to the regex engine. ( Integer )
:param session: Database session. ( Session )
:return: Filtered Ibl Sets. ( List )
"""
return filterItems(getIblSets(getSession(session)), pattern, field, flags)
[docs]def iblSetExists(path, session=None):
"""
This method returns if given Ibl Set exists in the Database.
:param name: Ibl Set path. ( String )
:param session: Database session. ( Session )
:return: Ibl Set exists. ( Boolean )
"""
return filterIblSets("^{0}$".format(re.escape(path)), "path", session=getSession(session)) and True or False
[docs]def addIblSet(name, path, collection, session=None):
"""
This definition adds a new Ibl Set to the Database.
:param name: Ibl Set name. ( String )
:param path: Ibl Set path. ( String )
:param collection: Collection id. ( String )
:param session: Database session. ( Session )
:return: Database commit success. ( Boolean )
"""
return addStandardItem(IblSet, name, path, collection, getSession(session))
[docs]def removeIblSet(identity, session=None):
"""
This definition removes an Ibl Set from the Database.
:param identity: Ibl Set id. ( String )
:param session: Database session. ( Session )
:return: Database commit success. ( Boolean )
"""
return removeStandardItem(IblSet, identity, getSession(session))
[docs]def updateIblSetContent(iblSet, session=None):
"""
This definition update an Ibl Set content.
:param iblSet: Ibl Set to set content. ( IblSet )
:param session: Database session. ( Session )
:return: Database commit success. ( Boolean )
"""
return updateItemContent(iblSet, getSession(session))
[docs]def updateIblSetLocation(iblSet, path, session=None):
"""
This definition updates an Ibl Set location.
:param iblSet: Ibl Set to update. ( IblSet )
:param path: Ibl Set path. ( Path )
:param session: Database session. ( Session )
:return: Database commit success. ( Boolean )
"""
return updateItemLocation(iblSet, path, getSession(session))
[docs]def checkIblSetsTableIntegrity(session=None):
"""
This definition checks sets table integrity.
:param session: Database session. ( Session )
:return: Ibl Sets table erroneous items. ( Dictionary )
"""
LOGGER.debug("> Checking 'Sets' Database table integrity.")
session = getSession(session)
erroneousIblSets = {}
if getIblSets(session):
for iblSet in getIblSets(session):
exceptions = []
if not foundations.common.pathExists(iblSet.path):
exceptions.append(sibl_gui.components.core.database.exceptions.MissingIblSetFileError)
if not foundations.common.pathExists(iblSet.icon):
exceptions.append(sibl_gui.components.core.database.exceptions.MissingIblSetIconError)
if iblSet.previewImage and not foundations.common.pathExists(os.path.join(os.path.dirname(iblSet.path),
iblSet.previewImage)):
exceptions.append(sibl_gui.components.core.database.exceptions.MissingIblSetPreviewImageError)
if iblSet.backgroundImage and not foundations.common.pathExists(os.path.join(os.path.dirname(iblSet.path),
iblSet.backgroundImage)):
exceptions.append(sibl_gui.components.core.database.exceptions.MissingIblSetBackgroundImageError)
if iblSet.lightingImage and not foundations.common.pathExists(os.path.join(os.path.dirname(iblSet.path),
iblSet.lightingImage)):
exceptions.append(sibl_gui.components.core.database.exceptions.MissingIblSetLightingImageError)
if iblSet.reflectionImage and not foundations.common.pathExists(os.path.join(os.path.dirname(iblSet.path),
iblSet.reflectionImage)):
exceptions.append(sibl_gui.components.core.database.exceptions.MissingIblSetReflectionImageError)
if exceptions:
erroneousIblSets[iblSet] = exceptions
return erroneousIblSets
[docs]def getCollections(session=None):
"""
This definition returns the Collections from the Database.
:param session: Database session. ( Session )
:return: Database Collections. ( List )
"""
return getSession(session).query(Collection)
[docs]def filterCollections(pattern, field, flags=0, session=None):
"""
This definition filters the Collections from the Database.
:param pattern: Filtering pattern. ( String )
:param field: Database field to search into. ( String )
:param flags: Flags passed to the regex engine. ( Integer )
:param session: Database session. ( Session )
:return: Filtered Collections. ( List )
"""
return filterItems(getCollections(getSession(session)), pattern, field, flags)
[docs]def getCollectionsByType(type, session=None):
"""
This method returns Collections of given type.
:param type: Type name. ( String )
:param session: Database session. ( Session )
:return: Ibl Sets Collections. ( List )
"""
return [collection for collection in filterCollections(type, "type", session=getSession(session))]
[docs]def filterCollectionsByType(type, pattern, field, flags=0, session=None):
"""
This definition filters the Ibl Sets Collections from the Database.
:param type: Type name. ( String )
:param pattern: Filtering pattern. ( String )
:param field: Database field to search into. ( String )
:param flags: Flags passed to the regex engine. ( Integer )
:param session: Database session. ( Session )
:return: Filtered Collections. ( List )
"""
return list(set(getCollectionsByType(type, session)).intersection(
filterCollections("{0}".format(pattern), field, flags, getSession(session))))
[docs]def filterIblSetsCollections(pattern, field, flags=0, session=None):
"""
This definition filters the Ibl Sets Collections from the Database.
:param pattern: Filtering pattern. ( String )
:param field: Database field to search into. ( String )
:param flags: Flags passed to the regex engine. ( Integer )
:param session: Database session. ( Session )
:return: Filtered Collections. ( List )
"""
return filterCollectionsByType("IblSets", pattern, field, flags, getSession(session))
[docs]def filterTemplatesCollections(pattern, field, flags=0, session=None):
"""
This definition filters the Templates Collections from the Database.
:param pattern: Filtering pattern. ( String )
:param field: Database field to search into. ( String )
:param flags: Flags passed to the regex engine. ( Integer )
:param session: Database session. ( Session )
:return: Filtered Collections. ( List )
"""
return filterCollectionsByType("Templates", pattern, field, flags, getSession(session))
[docs]def collectionExists(name, session=None):
"""
This method returns if the Collection exists in the Database.
:param name: Collection name. ( String )
:param session: Database session. ( Session )
:return: Collection exists. ( Boolean )
"""
return filterCollections("^{0}$".format(name), "name", session=getSession(session)) and True or False
[docs]def addCollection(collection, type, comment, session=None):
"""
This definition adds a Collection to the Database.
:param collection: Collection name. ( String )
:param type: Collection type. ( String )
:param comment: Collection comment. ( String )
:param session: Database session. ( Session )
:return: Database commit success. ( Boolean )
"""
LOGGER.debug("> Adding: '{0}' Collection of type '{1}' to the Database.".format(collection, type))
session = getSession(session)
if not filterCollections("^{0}$".format(collection), "name", session=session):
databaseItem = Collection(name=collection, type=type, comment=comment)
return addItem(databaseItem, session)
else:
LOGGER.warning("!> {0} | '{1}' Collection already exists in Database!".format(__name__, collection))
return False
[docs]def removeCollection(identity, session=None):
"""
This definition removes a Collection from the Database.
:param identity: Collection id. ( String )
:param session: Database session. ( Session )
:return: Database commit success. ( Boolean )
"""
return removeStandardItem(Collection, identity, getSession(session))
[docs]def getCollectionsIblSets(identities, session=None):
"""
This definition returns Ibl Sets from Collections ids
:param identities: Collections ids. ( List )
:param session: Database session. ( Session )
:return: Ibl Sets list. ( List )
"""
iblSets = []
for identity in identities:
collectionSets = filterIblSets("^{0}$".format(identity), "collection", session=getSession(session))
if collectionSets:
for iblSet in collectionSets:
iblSets.append(iblSet)
return iblSets
[docs]def getCollectionIblSetsCount(collection, session=None):
"""
This method returns given Collection Ibl Sets count.
:param collection: Collection. ( Collection )
:param session: Database session. ( Session )
:return: Collection Ibl Sets count. ( Integer )
"""
return getSession(session).query(IblSet).filter_by(collection=collection.id).count()
[docs]def getCollectionTemplatesCount(collection, session=None):
"""
This method returns given Collection Tempates count.
:param collection: Collection. ( Collection )
:param session: Database session. ( Session )
:return: Collection Templates count. ( Integer )
"""
return getSession(session).query(Template).filter_by(collection=collection.id).count()
[docs]def getTemplates(session=None):
"""
This definition returns the Templates from the Database.
:param session: Database session. ( Session )
:return: Database Templates. ( List )
"""
return getSession(session).query(Template)
[docs]def filterTemplates(pattern, field, flags=0, session=None):
"""
This definition filters the Templates from the Database.
:param pattern: Filtering pattern. ( String )
:param field: Database field to search into. ( String )
:param flags: Flags passed to the regex engine. ( Integer )
:param session: Database session. ( Session )
:return: Filtered Templates. ( List )
"""
return filterItems(getTemplates(getSession(session)), pattern, field, flags)
[docs]def templateExists(path, session=None):
"""
This method returns if given Template exists in the Database.
:param name: Template path. ( String )
:param session: Database session. ( Session )
:return: Template exists. ( Boolean )
"""
return filterTemplates("^{0}$".format(re.escape(path)), "path", session=getSession(session)) and True or False
[docs]def addTemplate(name, path, collection, session=None):
"""
This definition adds a new Template to the Database.
:param name: Template name. ( String )
:param path: Template path. ( String )
:param collection: Collection id. ( String )
:param session: Database session. ( Session )
:return: Database commit success. ( Boolean )
"""
return addStandardItem(Template, name, path, collection, getSession(session))
[docs]def removeTemplate(identity, session=None):
"""
This definition removes a Template from the Database.
:param identity: Template id. ( String )
:param session: Database session. ( Session )
:return: Database commit success. ( Boolean )
"""
return removeStandardItem(Template, identity, getSession(session))
[docs]def updateTemplateContent(template, session=None):
"""
This definition update a Template content.
:param template: Template to Template content. ( Template )
:param session: Database session. ( Session )
:return: Database commit success. ( Boolean )
"""
return updateItemContent(template, getSession(session))
[docs]def updateTemplateLocation(template, path, session=None):
"""
This definition updates a Template location.
:param template: Template to update. ( Template )
:param path: Template path. ( Path )
:param session: Database session. ( Session )
:return: Database commit success. ( Boolean )
"""
return updateItemLocation(template, path, getSession(session))
[docs]def checkTemplatesTableIntegrity(session=None):
"""
This definition checks Templates table integrity.
:param session: Database session. ( Session )
:return: Templates table erroneous items. ( Dictionary )
"""
LOGGER.debug("> Checking 'Templates' Database table integrity.")
session = getSession(session)
erroneousTemplates = {}
if getTemplates(session):
for template in getTemplates(session):
exceptions = []
if not foundations.common.pathExists(template.path):
exceptions.append(sibl_gui.components.core.database.exceptions.MissingTemplateFileError)
if not foundations.common.pathExists(template.helpFile):
exceptions.append(sibl_gui.components.core.database.exceptions.MissingTemplateHelpFileError)
if exceptions:
erroneousTemplates[template] = exceptions
return erroneousTemplates