1
0
Fork 0
mirror of https://github.com/yweber/lodel2.git synced 2025-11-25 23:06:55 +01:00
lodel2_mirror/EditorialModel/randomem.py
2015-11-13 11:50:32 +01:00

192 lines
8.5 KiB
Python

#-*- coding: utf-8 -*-
## @package EditorialModel.randomem
#
# @warning BROKEN because there is no more fieldgroups
# Provide methods for random EM generation
import random
from EditorialModel.backend.dummy_backend import EmBackendDummy
from EditorialModel.model import Model
from EditorialModel.fields import EmField
from EditorialModel.types import EmType
from EditorialModel.classtypes import EmClassType
from Lodel.utils.mlstring import MlString
class RandomEm(object):
## @brief Instanciate a class allowing to generate random EM
# @see RandomEm::random_em()
def __init__(self, backend=None, **kwargs):
self.backend = backend
self.kwargs = kwargs
## @brief Return a random EM
# @return A random EM
def gen(self):
return self.random_em(self.backend, **self.kwargs)
@classmethod
## @brief Generate a random editorial model
#
# The random generator can be tuned with integer parameters
# that represent probability or maximum numbers of items.
# The probability (chances) works like 1/x chances to append
# with x the tunable parameter
# Tunable generator parameters :
# - classtype : Chances for a classtype to be empty (default 0)
# - nclass : Maximum number of classes per classtypes (default 5)
# - nofg : Chances for a classe to have no fieldgroup associated to it (default 10)
# - notype : Chances for a classe to have no type associated to it (default 5)
# - seltype : Chances for a type to select an optionnal field (default 2)
# - ntypesuperiors : Chances for a type to link with a superiors (default 3)
# - nofields : Chances for a fieldgroup to be empty (default 10)
# - nfields : Maximum number of field per fieldgroups (default 8)
# - rfields : Maximum number of relation_to_type attributes fields (default 5)
# - optfield : Chances for a field to be optionnal (default 2)
# @param backend : A backend to use with the new EM
# @param **kwargs dict : Provide tunable generation parameter
# @param cls
# @return A randomly generate EM
def random_em(cls, backend=None, **kwargs):
ed_mod = Model(EmBackendDummy if backend is None else backend)
chances = {
'classtype': 0, # a class in classtype
'nclass': 5, # max number of classes per classtype
'nofg': 10, # no fieldgroup in a class
'nfg': 5, # max number of fieldgroups per classes
'notype': 10, # no types in a class
'ntype': 8, # max number of types in a class
'seltype': 2, # chances to select an optional field
'ntypesuperiors': 2, # chances to link with a superior
'nofields': 10, # no fields in a fieldgroup
'nfields': 8, # max number of fields per fieldgroups
'nr2tfields': 1, # max number of rel2type fields per fieldgroups
'rfields': 5, # max number of attributes relation fields
'optfield': 2, # chances to be optionnal
}
for name, value in kwargs.items():
if name not in chances:
#warning
pass
else:
chances[name] = value
#classes creation
for classtype in EmClassType.getall():
if random.randint(0, chances['classtype']) == 0:
for _ in range(random.randint(1, chances['nclass'])):
cdats = cls._rnd_component_datas()
cdats['classtype'] = classtype['name']
ed_mod.create_component('EmClass', cdats)
for emclass in ed_mod.classes():
#fieldgroups creation
"""
if random.randint(0, chances['nofg']) != 0:
for _ in range(random.randint(1, chances['nfg'])):
fgdats = cls._rnd_component_datas()
fgdats['class_id'] = emclass.uid
ed_mod.create_component('EmFieldGroup', fgdats)
"""
#types creation
if random.randint(0, chances['notype']) != 0:
for _ in range(random.randint(1, chances['ntype'])):
tdats = cls._rnd_component_datas()
tdats['class_id'] = emclass.uid
ed_mod.create_component('EmType', tdats)
#random type hierarchy
for emtype in ed_mod.components(EmType):
possible = emtype.possible_superiors()
for nat in possible:
if len(possible[nat]) > 0 and random.randint(0, chances['ntypesuperiors']) == 0:
random.shuffle(possible[nat])
for i in range(random.randint(1, len(possible[nat]))):
emtype.add_superior(possible[nat][i], nat)
#fields creation
ft_l = [ftname for ftname in EmField.fieldtypes_list() if ftname != 'pk' and ftname != 'rel2type']
for emc in ed_mod.components('EmClass'):
if random.randint(0, chances['nofields']) != 0:
for _ in range(random.randint(1, chances['nfields'])):
field_type = ft_l[random.randint(0, len(ft_l) - 1)]
fdats = cls._rnd_component_datas()
fdats['fieldtype'] = field_type
fdats['class_id'] = emc.uid
if random.randint(0, chances['optfield']) == 0:
fdats['optional'] = True
ed_mod.create_component('EmField', fdats)
#rel2type creation (in case none where created before
for emc in ed_mod.components('EmClass'):
for _ in range(random.randint(0, chances['nr2tfields'])):
field_type = 'rel2type'
fdats = cls._rnd_component_datas()
fdats['fieldtype'] = field_type
fdats['class_id'] = emc.uid
emtypes = ed_mod.components(EmType)
fdats['rel_to_type_id'] = emtypes[random.randint(0, len(emtypes) - 1)].uid
if random.randint(0, chances['optfield']) == 0:
fdats['optional'] = True
ed_mod.create_component('EmField', fdats)
# relationnal fields creation
ft_l = [field_type for field_type in EmField.fieldtypes_list() if field_type != 'rel2type' and field_type != 'pk']
for emrelf in [f for f in ed_mod.components(EmField) if f.fieldtype == 'rel2type']:
for _ in range(0, chances['rfields']):
field_type = ft_l[random.randint(0, len(ft_l) - 1)]
fdats = cls._rnd_component_datas()
fdats['rel_field_id'] = emrelf.uid
fdats['fieldtype'] = field_type
fdats['class_id'] = emrelf.class_id
if random.randint(0, chances['optfield']) == 0:
fdats['optional'] = True
ed_mod.create_component('EmField', fdats)
#selection optionnal fields
for emtype in ed_mod.components(EmType):
selectable = [field for field in emtype.em_class.fields() if field.optional]
for field in selectable:
if random.randint(0, chances['seltype']) == 0:
emtype.select_field(field)
return ed_mod
@staticmethod
## @brief Generate a random string
# @warning dirty cache trick with globals()
# @return a randomly selected string
def _rnd_str(words_src='/usr/share/dict/words'):
if '_words' not in globals() or globals()['_words_fname'] != words_src:
globals()['_words_fname'] = words_src
with open(words_src, 'r') as fpw:
globals()['_words'] = [l.strip() for l in fpw]
words = globals()['_words']
return words[random.randint(0, len(words) - 1)]
@classmethod
## @brief Generate a random MlString
# @param nlng : Number of langs in the MlString
# @return a random MlString with nlng translations
# @todo use a dict to generated langages
def _rnd_mlstr(cls, nlng):
ret = MlString()
for _ in range(nlng):
ret.set(cls._rnd_str(), cls._rnd_str())
return ret
@classmethod
## @brief returns randomly generated datas for an EmComponent
# @return a dict with name, string and help_text
def _rnd_component_datas(cls):
mlstr_nlang = 2
ret = dict()
ret['name'] = cls._rnd_str()
ret['string'] = cls._rnd_mlstr(mlstr_nlang)
ret['help_text'] = cls._rnd_mlstr(mlstr_nlang)
return ret