# -*- coding: UTF-8 -*-
""" @file erecord_vpz/models_mixins.py
..
Copyright (C) 2014-2016 INRA http://www.inra.fr \n\n
This file is part of erecord - Record platform web development \n\n
License : see LICENSE file. Authors : see AUTHORS file.
@include LICENSE @include AUTHORS
"""
""" @package erecord_vpz.models_mixins
mixins for erecord_vpz model
see erecord_vpz
"""
import os
import json
import datetime
from erecord_cmn.configs.config import REPOSITORIES_HOME
from erecord_cmn.utils.vle import get_vlepath_pkg_name
from erecord_cmn.configs.config import REQUESTS_HOME_APP_VPZ
from erecord_cmn.utils.vle import get_rep_pkgname_list
from erecord_cmn.utils.vle import get_rep_pkgs_path
from erecord_vpz.models_mixins.workspace import RunhomeWorkspaceMixin
from erecord_vpz.models_mixins.workspace import DatahomeWorkspaceMixin
from erecord_vpz.models_mixins.workspace import ReporthomeWorkspaceMixin
from erecord_vpz.models_mixins.workspace import VlehomeWorkspaceMixin
from erecord_vpz.models_mixins.workspace import WorkspaceMixin
import shutil
from erecord_cmn.utils.dir_and_file import make_csv_file
from erecord_cmn.utils.dir_and_file import create_dirs_if_absent
from erecord_cmn.utils.dir_and_file import delete_path_if_present
from erecord_cmn.utils.dir_and_file import clean_dir
from erecord_cmn.utils.dir_and_file import get_available_pathname
from erecord_cmn.configs.config import ACTIVITY_LIFETIME
from erecord_cmn.utils.erecord_package import vle_run_vpz
from erecord_cmn.utils.logger import get_logger
LOGGER = get_logger(__name__) # should be passed as a parameter of methods ?
# Some mixins for the erecord_vpz models
[docs]class VpzPathMixin(object):
"""additional methods for VpzPath """
[docs] def for_vpzact_creation(self):
""" Prepares the creation of a VpzAct from a VpzPath """
res = None
e = get_vlepath_pkg_name(vpzpath=self.vpzpath,
limit=REPOSITORIES_HOME)
if e is None :
msg = "unavailable vpzpath '"+self.vpzpath+"'"
raise Exception(msg)
(vlepath,pkgname,vpzname) = e
v = vle_identify(vlepath)
if v is None :
msg = "unavailable vle version configuration for '"+vlepath+"'"
raise Exception(msg)
(vleversion, vle_usr_path) = v
now = datetime.datetime.now()
text = "Vpz activity (VpzAct) created from VpzPath. "
text = text+ "VpzPath id : " + str(self.id) + ", "
text = text+ "vpzpath : " + self.vpzpath + ". "
text = text+ "vle version : " + vleversion + ". "
text = text+ "vle usr path : " + vle_usr_path + ". "
text = text+ "Time:" + str(now) + "."
res = { 'vlepath':vlepath,
'pkgname': pkgname,
'vpzname': vpzname,
'vleversion': vleversion,
'vleusrpath': vle_usr_path,
'textorigin': text, }
return res
[docs]class AttachedToVpzActMixin(object):
"""additional methods for a model attached to a VpzAct """
[docs] @classmethod
def create(cls, vpzact, **kwargs):
"""create the object attached to vpzact """
obj = cls(vpzact=vpzact, **kwargs)
return obj
[docs]class VpzOriginMixin(object):
"""additional methods for VpzOrigin """
[docs] def set_undefined_value_text(self):
self.text = "undefined"
[docs] def is_undefined_value_text(self):
return self.text == "undefined"
[docs]class VpzWorkspaceMixin(RunhomeWorkspaceMixin, DatahomeWorkspaceMixin,
ReporthomeWorkspaceMixin, VlehomeWorkspaceMixin, WorkspaceMixin):
"""additional methods for VpzWorkspace """
[docs] def define_and_build(self, as_vlehome=False, as_reporthome=False,
as_datahome=False, as_runhome=False):
""" Defines and builds a VpzWorkspace
Chooses/defines fields values (homepath, vlehome, reporthome, datahome,
runhome) and creates the required directories (at least homepath).
A workspace may concern vlehome, reporthome, datahome, runhome. Those
subdirectories will there be created or not depending on as_vlehome,
as_reporthome, as_datahome, as_runhome.
"""
self.homepath = self.get_undefined_value()
self.vlehome = self.get_undefined_value()
self.reporthome = self.get_undefined_value()
self.datahome = self.get_undefined_value()
self.runhome = self.get_undefined_value()
homepath = get_available_pathname(rootpath=REQUESTS_HOME_APP_VPZ,
rootname="user_")
(deletion_done, creation_done) = clean_dir(dirpath=homepath)
if deletion_done :
LOGGER.error(u"%s has been deleted before to be recreated, whereas it was supposed not to exist", homepath)
self.homepath = homepath
self.datahome = self.init_datahome(LOGGER=LOGGER,
as_datahome=as_datahome)
self.reporthome = self.init_reporthome(LOGGER=LOGGER,
as_reporthome=as_reporthome)
self.runhome = self.init_runhome(LOGGER=LOGGER,
as_runhome=as_runhome)
self.vlehome = self.init_vlehome(LOGGER=LOGGER, as_vlehome=as_vlehome)
[docs] def get_homepath(self):
return self.homepath
[docs] def clean_workspace(self):
clean_dir(dirpath=self.homepath)
[docs] def clear_workspace(self):
delete_path_if_present(path=self.homepath)
[docs] def clear_dirs(self):
self.clear_vlehome()
self.clear_reporthome()
self.clear_datahome()
self.clear_runhome()
self.clear_workspace()
[docs]class VpzActMixin(object):
"""additional methods for VpzAct """
[docs] def get_ordered_vlepackage_list(self):
"""builds and returns an ordered list about the vpzact vle package \
and its dependency packages.
The list elements are, for each vle package :
(package name, package path name), where the vpzact vle package (ie \
named pkgname) is the first one.
Since the real dependency packages of the vpzact vle package are not \
clearly known, all the other vle packages of the vpzact models \
repository (ie corresponding with path vlepath) are considered as \
potential dependency packages.
"""
pkgname_list = get_rep_pkgname_list(rep_path=self.vlepath,
vle_version=self.vleversion)
if self.pkgname in pkgname_list :
pkgname_list.remove(self.pkgname)
pkgname_list.insert(0, self.pkgname)
pkgs_path = get_rep_pkgs_path(rep_path=self.vlepath,
vle_version=self.vleversion)
vlepackage_list = [(pkgname, os.path.join(pkgs_path, pkgname))
for pkgname in pkgname_list]
return vlepackage_list
[docs] def is_old(self):
"""vpzact is old if created_at 'older' than ACTIVITY_LIFETIME """
d = self.created_at + datetime.timedelta(days=ACTIVITY_LIFETIME)
now = datetime.datetime.now()
if d.toordinal() < now.toordinal() :
return True
else :
return False
[docs]class VpzOutputMixin(object):
"""additional methods for VpzOutput """
[docs] def run(self, plan, restype):
"""Runs the simulation relative to self.vpzact to define self.res
The simulation running method depends on plan ('single' or 'linear') \
and restype ('dataframe' or 'matrix').
Uses json result based on run_vpz simulator of erecord package
"""
#print "VpzOutputMixin, run : plan ", plan, " restype ", restype
self.res = None # default
res = None
vlehome_path = self.vpzact.vpzworkspace.get_vlehome()
runvle_path = self.vpzact.vpzworkspace.define_and_build_runhome_subdirectory(rootname="run_")
vle_version = self.vpzact.vleversion
vle_usr_path = self.vpzact.vleusrpath
pkgname = self.vpzact.pkgname
vpzname = self.vpzact.vpzname
jres = vle_run_vpz(runvle_path=runvle_path, vlehome_path=vlehome_path,
vle_version=vle_version, vle_usr_path=vle_usr_path,
pkgname=pkgname, vpzname=vpzname,
plan=plan, restype=restype)
keys = jres.keys()
if "plan" in keys :
plan = jres["plan"]
if "restype" in keys :
restype = jres["restype"]
if "res" in keys :
res = jres["res"]
if type(res) is str : # error case
msg = "Simulation running error ... " + res
raise Exception(msg)
# empty cases
if res is None : # single case
res = dict()
if type(res) is list : # linear case
if res == [None] :
res = list()
self.res = res
self.plan = plan
self.restype = restype
#print "run"
#print "RESULT type(self.res) : ", type(self.res)
[docs] @classmethod
def build_output_outname(cls, oname):
"""Builds and returns the outname value of an output data from its
oname value.
This method is used to interpret the res content of VpzOutput in \
relation with the VleOut denominations (vname, oname, selection_name).
oname is the oname value of the output data as a VleOut.
outname comes from the result produced by a vle simulation (cf res \
of VpzOutput).
Identity method since oname equals outname.
"""
return oname
[docs] @classmethod
def build_output_oname(cls, outname):
"""Builds and returns the oname value of an output data from its
outname value.
This method is used to interpret the res content of VpzOutput in \
relation with the VleOut denominations (vname, oname, selection_name).
oname is the oname value of the output data as a VleOut.
outname comes from the result produced by a vle simulation (cf res \
of VpzOutput).
Identity method since oname equals outname.
"""
return outname
[docs] @classmethod
def UNUSED__build_output_outname(cls, oname):
"""Builds and returns the outname value of an output data from its
oname value.
This method is used to interpret the res content of VpzOutput in \
relation with the VleOut denominations (vname, oname, selection_name).
oname is the oname value of the output data as a VleOut.
outname comes from the result produced by a vle simulation (cf res \
of VpzOutput). outname looks like oname but is quite different (cf \
':' instead of ',')
"""
outname = oname[::-1].replace(',',':',1)[::-1]
return outname
[docs] @classmethod
def UNUSED__build_output_oname(cls, outname):
"""Builds and returns the oname value of an output data from its
outname value.
This method is used to interpret the res content of VpzOutput in \
relation with the VleOut denominations (vname, oname, selection_name).
oname is the oname value of the output data as a VleOut.
outname comes from the result produced by a vle simulation (cf res \
of VpzOutput). outname looks like oname but is quite different (cf \
':' instead of ',')
"""
oname = outname[::-1].replace(':',',',1)[::-1]
return oname
[docs] def print_res(self):
print "--- self.res : "
if (self.plan=='single') and (self.restype=='dataframe'):
for viewname,viewvalue in self.res.iteritems() :
print viewname, " : "
for outname,outvalue in viewvalue.iteritems() :
print " ", outname, " : ", outvalue
elif (self.plan=='linear') and (self.restype=='dataframe'):
for m,mv in enumerate(list(self.res)) :
print "(", m, ") :"
for viewname,viewvalue in mv.iteritems() :
print viewname, " : "
for outname,outvalue in viewvalue.iteritems() :
print " ", outname, " : ", outvalue
if (self.plan=='single') and (self.restype=='matrix'):
for viewname,viewvalue in self.res.iteritems() :
print viewname, " : "
#print viewvalue
for out in viewvalue :
print " ", out
if (self.plan=='linear') and (self.restype=='matrix'):
for m,mv in enumerate(list(self.res)) :
print "(", m, ") :"
for viewname,viewvalue in mv.iteritems() :
print viewname, " : "
#print viewvalue
for out in viewvalue :
print " ", out
print "---"