class HideSchema(Schema): allow_extra_fields = True filter_extra_fields = True if_key_missing = None ChkHide = foreach.ForEach(ciocvalidators.IDValidator())
class PostSchema(Schema): allow_extra_fields = True filter_extra_fields = True if_key_missing = None pre_validators = [cull_skippable_items] quicksearch = foreach.ForEach(QuickSearchBaseSchema())
class Certificate(Schema): id = validators.Int() name = validators.String(min=3, max=30) username = validators.String(min=3, max=30) description = validators.String() groups = foreach.ForEach(validators.Int(), required=False, default=[]) expiration = validators.Int() expirated_at = validators.DateValidator() created_at = validators.DateValidator() updated_at = validators.DateValidator()
class NaicsExclusionBaseSchema(Schema): if_key_missing = None Exclusion_ID = Any(ciocvalidators.IDValidator(), validators.OneOf(["NEW"])) LangID = validators.Int(min=0, max=ciocvalidators.MAX_SMALL_INT, not_empty=True) Description = ciocvalidators.UnicodeString( max=255) # sometimes required as per RequireIfPredicate below Establishment = validators.Bool() UseCodes = foreach.ForEach(ciocvalidators.NaicsCode()) delete = validators.Bool() chained_validators = [ ciocvalidators.RequireIfPredicate(description_required, ["Description"]) ]
class DelegationCreateForm(DelegationNewForm): agent = foreach.ForEach(forms.ExistingUserName()) replay = validators.Int(if_empty=1, if_missing=1, not_empty=False)
class Chapman(object): """Usage: chapmand <config> [options] Options: -h --help show this help message and exit -c,--concurrency THREADS number of threads to run [default: 1] -d,--debug drop into a debugger on task errors? -n,--name NAME override the name of the worker """ settings_schema = fes.Schema( pre_validators=[fevd.NestedVariables()], name=fev.String(), queues=fef.ForEach(if_missing=['chapman']), path=fev.String(), sleep_ms=fev.Int()) def __init__(self, name, path, queues, sleep_ms): self.name = '{}-{}'.format(name, base64.urlsafe_b64encode(os.urandom(6))) self.path = path self.queues = queues self.sleep_ms = sleep_ms @classmethod def script(cls): args = docopt(cls.__doc__) config = args['<config>'] if '#' in config: config, section = config.split('#') else: section = 'chapman' _setup_logging(config) cp = ConfigParser() cp.read(config) settings = dict(cp.items(section)) app_section = settings.pop('app') app_context = bootstrap('{}#{}'.format(config, app_section)) settings = cls.settings_schema.to_python(settings) if args['--name']: settings['name'] = args['--name'] self = cls(**settings) self.run( app_context['app'], app_context['registry'], int(args['--concurrency']), bool(args['--debug'])) def run(self, app, registry, concurrency, debug): name = '{}:{}'.format(self.name, os.getpid()) log.info('Starting Chapman') log.info(' path: %s', self.path) log.info(' name: %s', name) log.info(' queues: %s', self.queues) log.info(' concurrency: %s', concurrency) log.info(' debug: %s', debug) log.info(' sleep_ms: %s', self.sleep_ms) w = worker.Worker( app=app, name=name, qnames=self.queues, chapman_path=self.path, registry=registry, num_threads=concurrency, sleep=self.sleep_ms / 1000.0, raise_errors=debug) w.start() w.run()
def save(self): request = self.request user = request.user chk_type = self.request.context.chk_type all_values = not self.request.dboptions.OtherMembersActive shared_values = not not ( all_values or not self.request.matched_route.name.endswith("_local")) SuperUserGlobal = self._check_security( chk_type, chk_type.Shared == "full" or shared_values) if shared_values and not SuperUserGlobal: self._security_failure() if chk_type.ShowAdd: extra_validators = { chk_type.ID: Any(ciocvalidators.IDValidator(), validators.OneOf(["NEW"])) } else: extra_validators = { chk_type.ID: ciocvalidators.IDValidator(not_empty=chk_type.CanDelete) } if chk_type.CodeTitle: if not chk_type.CodeValidator: extra_validators[chk_type.CodeField] = ciocvalidators.String( max=chk_type.CodeMaxLength) else: extra_validators[chk_type.CodeField] = chk_type.CodeValidator if chk_type.DisplayOrder: extra_validators["DisplayOrder"] = validators.Int(min=0, max=256, if_empty=0) if chk_type.ShowOnForm: extra_validators["ShowOnForm"] = validators.Bool() for field in chk_type.ExtraFields or []: extra_validators[field["field"]] = field["validator"] extra_name_validators = {} for field in chk_type.ExtraNameFields or []: extra_name_validators[field["field"]] = field["validator"] base_schema = make_checklist_base_schema(extra_name_validators, **extra_validators) schema_params = {"chkitem": foreach.ForEach(base_schema)} schema = PostSchema(**schema_params) model_state = request.model_state model_state.form.state.chk_type = chk_type model_state.schema = schema model_state.form.variable_decode = True domain, shown_cultures = viewbase.get_domain_and_show_cultures( request.params) if model_state.validate(): # valid. Save changes and redirect root = ET.Element("CHECKLIST") for i, chkitem in enumerate(model_state.form.data["chkitem"]): if should_skip_item(chk_type, chkitem): continue chk_el = ET.SubElement(root, "CHK") ET.SubElement(chk_el, "CNT").text = str(i) for key, value in chkitem.items(): if key == chk_type.ID and value == "NEW": value = -1 elif isinstance(value, bool): value = int(value) if key != "Descriptions": if value is not None: ET.SubElement(chk_el, key).text = str(value) continue descs = ET.SubElement(chk_el, "DESCS") for culture, data in value.items(): culture = culture.replace("_", "-") if culture not in shown_cultures: continue desc = ET.SubElement(descs, "DESC") ET.SubElement(desc, "Culture").text = culture for key, value in data.items(): if value: ET.SubElement(desc, key).text = value args = [ request.dboptions.MemberID, user.Mod, ET.tostring(root, encoding="unicode"), ] with request.connmgr.get_connection("admin") as conn: sql = chk_type.UpdateSQL(shared_values) log.debug("sql: %s", sql) log.debug("args: %s", args) cursor = conn.execute(sql, *args) result = cursor.fetchone() cursor.close() if not result.Return: self._go_to_route( request.matched_route.name, _query=( ( "InfoMsg", _("The record(s) were successfully updated.", request), ), ("ShowCultures", shown_cultures), ("chk", chk_type.FieldCode), ), ) ErrMsg = _("Unable to save: ") + result.ErrMsg else: ErrMsg = _("There were validation errors.") chkitems, chkusage = self._get_edit_info( chk_type, not all_values and not shared_values, not all_values and shared_values, not SuperUserGlobal, ) record_cultures = syslanguage.active_record_cultures() chkitems = variabledecode.variable_decode(request.POST)["chkitem"] model_state.form.data["chkitem"] = chkitems type_name = "" if chk_type.Shared == "partial" and not all_values: if shared_values: type_name = _("Shared", self.request) else: type_name = _("Local", self.request) title_template = _(chk_type.PageTitleTemplate, self.request) % { "type": type_name } title = (chk_type.CheckListName if request.viewdata.PrintMode else title_template.format(chk_type.CheckListName)) return self._create_response_namespace( title, title, dict( chkitems=chkitems, record_cultures=record_cultures, shown_cultures=shown_cultures, SuperUserGlobal=SuperUserGlobal, chkusage=chkusage, chk_type=chk_type, ErrMsg=ErrMsg, ), no_index=True, )
from datetime import datetime, timedelta from formencode import validators as fev from formencode import schema as fes from formencode import foreach as fef class DateTime(fev.FancyValidator): def _to_python(self, value, state=None): if '.' in value: iso, frac_s = value.split('.') else: iso, frac_s = value, '0' us = float('0.' + frac_s) * 1e6 ts = datetime.strptime(iso, '%Y-%m-%d %H:%M:%S') return ts + timedelta(microseconds=us) message_schema = fes.Schema(priority=fev.Int(if_empty=10, if_missing=10), delay=fev.Int(if_missing=0), timeout=fev.Int(if_missing=300), tags=fef.ForEach(fev.UnicodeString, convert_to_list=True, if_missing=[])) get_schema = fes.Schema(client=fev.UnicodeString(required=True), count=fev.Int(if_missing=1), timeout=fev.Int(if_missing=0)) retry_schema = fes.Schema(delay=fev.Int(if_empty=5, if_missing=5))
def save(self): request = self.request user = request.user list_type = self.request.context.list_type self._check_security(list_type, True) extra_validators = {} if list_type.ID: extra_validators = { list_type.ID or "OldValue": Any(list_type.id_validator, validators.OneOf(["NEW"])) } extra_validators[list_type.NameField] = validators.UnicodeString( max=list_type.NameFieldMaxLength) for field in list_type.ExtraFields or []: extra_validators[field["field"]] = field["validator"] base_schema = ListBaseSchema(**extra_validators) schema_params = {"listitem": foreach.ForEach(base_schema)} schema = PostSchema(**schema_params) model_state = request.model_state model_state.schema = schema model_state.form.variable_decode = True if model_state.validate(): # valid. Save changes and redirect root = ET.Element("CHECKLIST") for listitem in model_state.form.data["listitem"]: if list_type.ID and not listitem.get(list_type.ID): continue if not listitem.get(list_type.NameField): continue if list_type.CanDelete and listitem.get("delete"): continue list_el = ET.SubElement(root, "CHK") for key, value in listitem.items(): if key == list_type.ID and value == "NEW": value = -1 elif isinstance(value, bool): value = int(value) if value is not None: ET.SubElement(list_el, key).text = str(value) if list_type.HasModified: args = [user.Mod, ET.tostring(root, encoding="unicode")] else: args = [ET.tostring(root, encoding="unicode")] with request.connmgr.get_connection("admin") as conn: sql = """ DECLARE @RC int, @ErrMsg nvarchar(500) EXEC @RC = sp_{}_u {}, @ErrMsg OUTPUT SELECT @RC AS [Return], @ErrMsg AS ErrMsg""".format( list_type.Table, ",".join("?" * len(args)), ) cursor = conn.execute(sql, *args) result = cursor.fetchone() cursor.close() if not result.Return: self._go_to_route( request.matched_route.name, _query=( ( "InfoMsg", _("The record(s) were successfully updated.", request), ), ("list", list_type.FieldCode), ), ) ErrMsg = _("Unable to save: ") + result.ErrMsg else: ErrMsg = _("There were validation errors.") listitems = self._get_edit_info(list_type) record_cultures = syslanguage.active_record_cultures() listitems = variabledecode.variable_decode(request.POST)["listitem"] model_state.form.data["listitem"] = listitems title_template = _(list_type.PageTitleTemplate, self.request) title = (list_type.ListName if request.viewdata.PrintMode else title_template.format(list_type.ListName)) return self._create_response_namespace( title, title, dict( listitems=listitems, record_cultures=record_cultures, SuperUserGlobal=request.context.SuperUserGlobal, list_type=list_type, ErrMsg=ErrMsg, ), no_index=True, )
class Character(Base, JSONAPIMixin): """The :class:`~webrpg.components.character.Character` represents a single character and its attributes, using a given rule-set. It has the following attributes: "attr", "rule_set", "game", "user".""" __tablename__ = 'characters' id = Column(Integer, primary_key=True) user_id = Column(Integer, ForeignKey('users.id', name='characters_user_id_fk')) game_id = Column(Integer, ForeignKey('games.id', name='characters_game_id_fk')) attr = Column(UnicodeText) rule_set = Column(Unicode(255)) user = relationship('User') game = relationship('Game') __create_schema__ = JSONAPISchema( 'characters', attribute_schema=DynamicSchema({ 'rule_set': validators.OneOf(['dnd5e', 'dnd5em', 'eote'], not_empty=True) }), relationship_schema=DynamicSchema({ 'game': { 'data': { 'type': validators.OneOf(['games'], not_empty=True), 'id': validators.Number } }, 'user': { 'data': { 'type': validators.OneOf(['users'], not_empty=True), 'id': validators.Number } } })) __update_schema__ = JSONAPISchema('characters', attribute_schema=DynamicSchema({ 'stats': foreach.ForEach(DictValidator()) })) __json_attributes__ = ['rule_set', 'stats'] __json_relationships__ = ['user', 'game'] __json_computed__ = ['title'] def title(self, request): """Computed attribute that extracts the correct title attribute for this :class:`~webrpg.components.character.Character`.""" if self.attr: attrs = json.loads(self.attr) if 'title' in RULE_SETS[self.rule_set] and RULE_SETS[ self.rule_set]['title'] in attrs: return attrs[RULE_SETS[self.rule_set]['title']] return 'Unnamed' @property def stats(self): """The stats property contains a ``list`` of ``dict`` that represent the attributes defined by the rule set and their values. Loads stored values from the "attr" attribute.""" attrs = json.loads(self.attr) if self.attr else {} rule_set = deepcopy(RULE_SETS[self.rule_set]) if self.rule_set else {} stats = [] if 'stats' in rule_set: for source_table in rule_set['stats']: table_id = source_table['id'] stat_table = { 'id': table_id, 'title': source_table['title'], 'rows': [] } if 'columns' in source_table: stat_table['columns'] = deepcopy(source_table['columns']) for source_row in source_table['rows']: multirow = 'multirow' in source_row and source_row[ 'multirow'] if multirow: if '%s.__rowids' % table_id in attrs: rowids = attrs['%s.__rowids' % table_id] rowids.append(max(rowids) + 1) else: rowids = [0] else: rowids = [None] for rowid in rowids: # Calculate base attribute values stat_row = {'columns': []} if 'title' in source_row: stat_row['title'] = source_row['title'] if multirow: stat_row['multirow'] = rowid for source_column in source_row['columns']: column_id = '%s.%s' % (source_table['id'], source_column['id']) if multirow: column_id = column_id % rowid stat_column = { 'id': column_id, 'data_type': source_column['data_type'], 'editable': source_column['editable'] } if 'options' in source_column: stat_column['options'] = source_column[ 'options'] if 'formula' in source_column: # Handle calculated fields if multirow: formula = source_column['formula'] % { 'rowid': rowid } else: formula = source_column['formula'] tokens = add_variables(tokenise(formula), attrs) total = calculate(infix_to_postfix(tokens)) stat_column['value'] = total attrs[column_id] = total else: if column_id in attrs: stat_column['value'] = attrs[column_id] else: stat_column['value'] = '' stat_row['columns'].append(stat_column) for source_column, stat_column in zip( source_row['columns'], stat_row['columns']): # Calculate column-level actions if 'action' in source_column: stat_column['action'] = { 'title': source_column['title'] if 'title' in source_column else '', 'target': 'setChatMessage', 'content': '' } if 'title' in source_column['action']: if multirow: stat_column['action'][ 'title'] = ' '.join([ t[1] for t in process_unary( add_variables( tokenise( source_column[ 'action'] ['title'] % {'rowid': rowid}), attrs)) ]) else: stat_column['action'][ 'title'] = ' '.join([ t[1] for t in process_unary( add_variables( tokenise(source_column[ 'action']['title'] ), attrs)) ]) if 'target' in source_column['action']: stat_column['action'][ 'target'] = source_column['action'][ 'target'] if 'content' in source_column['action']: content = source_column['action'][ 'content'] if multirow: content = content % {'rowid': rowid} if 'calculate' in source_column[ 'action'] and source_column[ 'action']['calculate']: # If "calculate" is set, run full calculation calc_match = re.search( re.compile('\$([^$]*)\$'), content) while calc_match: if calc_match.group( 0).strip() == '': break content = re.sub( re.compile('\$([^$]*)\$'), str( calculate( infix_to_postfix( add_variables( tokenise( calc_match. group(1)), attrs)))), content, count=1) calc_match = re.search( re.compile('\$([^$]*)\$'), content) stat_row['action']['content'] = content else: # Otherwise just replace variables stat_column['action'][ 'content'] = ' '.join([ t[1] for t in process_unary( add_variables( tokenise(content), attrs)) ]) if 'action' in source_row: # Calculate row-level actions stat_row['action'] = { 'title': source_row['title'] if 'title' in source_row else '', 'target': 'setChatMessage', 'content': '' } if 'title' in source_row['action']: stat_row['action']['title'] = ' '.join([ t[1] for t in process_unary( add_variables( tokenise(source_row['action'] ['title']), attrs)) ]) if 'target' in source_row['action']: stat_row['action']['target'] = source_row[ 'action']['target'] if 'content' in source_row['action']: content = source_row['action']['content'] if 'calculate' in source_row[ 'action'] and source_row['action'][ 'calculate']: # If "calculate" is set, run full calculation calc_match = re.search( re.compile('\$([^$]*)\$'), content) while calc_match: if calc_match.group(0).strip() == '': break content = re.sub( re.compile('\$([^$]*)\$'), str( calculate( infix_to_postfix( add_variables( tokenise( calc_match. group(1)), attrs)))), content, count=1) calc_match = re.search( re.compile('\$([^$]*)\$'), content) stat_row['action']['content'] = content else: # Otherwise just replace variables stat_row['action']['content'] = ' '.join([ t[1] for t in process_unary( add_variables( tokenise(content), attrs)) ]) stat_table['rows'].append(stat_row) stats.append(stat_table) return stats @stats.setter def stats(self, data): """Updates the stored "attr" stats for this :class:`~webrpg.components.character.Character`.""" attrs = {} for table in data: rowids = [] for row in table['rows']: multirow = 'multirow' in row has_value = False for column in row['columns']: if 'editable' in column and column['editable']: if 'value' in column: if column['value']: attrs[column['id']] = column['value'] has_value = True if multirow and has_value: rowids.append(row['multirow']) if rowids: attrs['%s.__rowids' % table['id']] = rowids self.attr = json.dumps(attrs) def allow(self, user, action): if user and self.user_id == user.id: return True else: return self.game.has_role(user, 'owner')