def update(self, **kwargs): """Update contents of this review. Returns: New revision of this review. """ license_id = kwargs.pop('license_id', None) if license_id is not None: if not self.is_draft: # If trying to convert published review into draft. raise BadRequest(lazy_gettext("Changing license of a published review is not allowed.")) self.license_id = license_id language = kwargs.pop('language', None) if language is not None: self.language = language is_draft = kwargs.pop('is_draft', None) if is_draft is not None: # This should be done after all changes that depend on review being a draft. if not self.is_draft and is_draft: # If trying to convert published review into draft. raise BadRequest(lazy_gettext("Converting published reviews back to drafts is not allowed.")) self.is_draft = is_draft new_revision = Revision.create(self.id, kwargs.pop('text')) cache.invalidate_namespace(Review.CACHE_NAMESPACE) if kwargs: # FIXME: Revision creation and other changes need to be rolled back # there, but there's a `commit` in Revision.create. raise TypeError('Unexpected **kwargs: %r' % kwargs) return new_revision
def create(self, data): if 'username' not in data: raise ValidationError({'username': [lazy_gettext('Please set username')]}) if data.get('password') and data.get('password_hash'): raise ValidationError({'password': [lazy_gettext('Please set only password or password hash')]}) errors = {} if data.get('password') and current_app.config['CHECK_PASSWORDS_SECURITY'] and not self.is_password_good(data['password'], extra=(data['username'],)): errors['password'] = [lazy_gettext('Password is too bad, please change it')] errors.update(self._check_existence(data['username'], data['email'])) if errors: raise ValidationError(errors) user = self._model()( username=data['username'], email=data.get('email') or '', is_active=bool(data.get('is_active', True)), ban_reason=data.get('ban_reason') or '', is_staff=bool(data.get('is_staff', False)), is_superuser=bool(data.get('is_superuser', False)), date_joined=data.get('date_joined', datetime.utcnow()), activated_at=data.get('activated_at', None), session_token=utils_random.random_string(32), password=data.get('password_hash') or '', ) user.flush() # for user.id if data.get('password'): user.bl.set_password(data['password']) return user
def authenticate_by_username(self, data, remote_addr=None): raw_data = data data = Validator(LOGIN).validated(data) user = None # Сначала достаём пользователя из базы # (без чувствительности к регистру) user = self.get_by_username(data.get('username')) # Пресекаем перебор пароля капчей (по IP и по юзеру) if remote_addr: if current_app.captcha and self.need_captcha_for_auth(remote_addr, user.id if user else None): current_app.captcha.check_or_raise(raw_data) self.track_auth(remote_addr, user.id if user else None) # Проверяем пароль if not user or not user.bl.check_password(data['password']): if remote_addr and current_app.config['AUTH_LOG']: if not user: current_app.logger.info('%s tried to log in, but account not found (ID: N/A, IP: %s)', data.get('username', '?'), remote_addr) else: current_app.logger.info('%s tried to log in with incorrect password (ID: %s, IP: %s)', user.username, user.id, remote_addr) raise ValidationError({'username': [lazy_gettext('Please enter a correct username and password.')]}) # Проверяем бан if not user.is_active: if remote_addr and current_app.config['AUTH_LOG']: current_app.logger.info('%s tried to log in, but account is disabled (ID: %s, IP: %s)', user.username, user.id, remote_addr) raise ValidationError({'username': [user.ban_reason or lazy_gettext('Account is disabled')]}) # Если дошли сюда, значит всё хорошо if remote_addr and current_app.config['AUTH_LOG']: current_app.logger.info('%s logged in (ID: %s, IP: %s)', user.username, user.id, remote_addr) return user
def update(self, author, data): from mini_fiction.models import AdminLog data = Validator(STATIC_PAGE).validated(data, update=True) staticpage = self.model if not author.is_superuser and (staticpage.is_template or data.get('is_template')): raise ValidationError({'is_template': [lazy_gettext('Access denied')]}) if ('name' in data and data['name'] != staticpage.name) or ('lang' in data and data['lang'] != staticpage.lang): raise ValidationError({ 'name': [lazy_gettext('Cannot change primary key')], 'lang': [lazy_gettext('Cannot change primary key')], }) if data.get('is_template', staticpage.is_template) and 'content' in data: self.check_renderability(author, data.get('name', staticpage.name), data['content']) changed_fields = set() for key, value in data.items(): if getattr(staticpage, key) != value: setattr(staticpage, key, value) changed_fields |= {key,} if changed_fields: AdminLog.bl.create( user=author, obj=staticpage, action=AdminLog.CHANGE, fields=sorted(changed_fields), ) return staticpage
def mappings(mbid=None): """Get mappings to Spotify for a specified MusicBrainz ID. Returns: List containing Spotify URIs that are mapped to specified MBID. """ if _base_url is None: flash.warn(lazy_gettext(_UNAVAILABLE_MSG)) return [] data = cache.get(mbid, _CACHE_NAMESPACE) if not data: try: session = requests.Session() session.mount(_base_url, HTTPAdapter(max_retries=2)) resp = session.post( url=_base_url + 'mapping', headers={'Content-Type': 'application/json'}, data=json.dumps({'mbid': mbid}), ) resp.raise_for_status() data = resp.json().get('mappings') except RequestException: flash.warn(lazy_gettext("Spotify mapping server is unavailable. You will not see an embedded player.")) return [] cache.set(key=mbid, namespace=_CACHE_NAMESPACE, val=data) return data
def create(self, author, data): from mini_fiction.models import AdminLog data = Validator(CHARACTER).validated(data) errors = {} exist_character = self.model.get(name=data['name']) if exist_character: errors['name'] = [lazy_gettext('Character already exists')] from mini_fiction.models import CharacterGroup group = CharacterGroup.get(id=data['group']) if not group: errors['group'] = [lazy_gettext('Group not found')] if errors: raise ValidationError(errors) picture = self.validate_and_get_picture_data(data.pop('picture')) character = self.model(picture='pending', sha256sum='pending', **data) character.flush() character.bl.set_picture_data(picture) AdminLog.bl.create(user=author, obj=character, action=AdminLog.ADDITION) return character
def my_profile(): ''' Show user their profile, let them edit it ''' form = UserForm(obj=current_user) if request.method == 'GET': return render_template('my-profile.html', form=form) elif request.method == 'POST': #userProfile = json.loads(request.form.get('me')) #session['user-profile'] = userProfile #db.updateCoreProfile(userProfile) #flash('Your profile has been saved. <br/>You may also want to <a' # 'href="/my-expertise">tell us what you know</a>.') #session['has_created_profile'] = True form.populate_obj(current_user) if form.validate(): db.session.add(current_user) db.session.commit() flash(lazy_gettext('Your profile has been saved. <br/>You may also want to <a' 'href="/my-expertise">tell us what you know</a>.')) else: flash(lazy_gettext(u'Could not save, please correct errors below: {}'.format( form.errors))) return render_template('my-profile.html', form=form)
def _check_existence(self, username, email): errors = {} if self.model.select(lambda x: x.username.lower() == username.lower()): errors['username'] = [lazy_gettext('User already exists')] if email and self.is_email_busy(email): errors['email'] = [lazy_gettext('Email address is already in use')] return errors
def update(self, author, data): from mini_fiction.models import AdminLog data = Validator(CHARACTER_FOR_UPDATE).validated(data, update=True) character = self.model errors = {} if 'name' in data: from mini_fiction.models import Character exist_character = Character.get(name=data['name']) if exist_character and exist_character.id != character.id: errors['name'] = [lazy_gettext('Character already exists')] if 'group' in data: from mini_fiction.models import CharacterGroup group = CharacterGroup.get(id=data['group']) if not group: errors['group'] = [lazy_gettext('Group not found')] else: group = None if errors: raise ValidationError(errors) changed_fields = set() if data.get('picture'): picture = self.validate_and_get_picture_data(data['picture']) else: picture = None for key, value in data.items(): if key == 'picture': if picture is not None: self.set_picture_data(picture) changed_fields |= {'picture',} elif key == 'group': if character.group.id != value: setattr(character, key, value) changed_fields |= {key,} elif getattr(character, key) != value: setattr(character, key, value) changed_fields |= {key,} if changed_fields: AdminLog.bl.create( user=author, obj=character, action=AdminLog.CHANGE, fields=sorted(changed_fields), ) return character
def delete(self, author): from mini_fiction.models import AdminLog staticpage = self.model if staticpage.name in ('help', 'terms', 'robots.txt') and staticpage.lang == 'none': raise ValidationError({'is_template': [lazy_gettext('This is system page, you cannot delete it')]}) if staticpage.is_template and not author.is_superuser: raise ValidationError({'is_template': [lazy_gettext('Access denied')]}) AdminLog.bl.create(user=author, obj=staticpage, action=AdminLog.DELETION) staticpage.delete()
def validate_and_get_picture_data(self, picture): fp = picture.stream header = fp.read(4) if header != b'\x89PNG': raise ValidationError({'picture': [lazy_gettext('PNG only')]}) data = header + fp.read(16384 - 4 + 1) # 16 KiB + 1 byte for validation if len(data) > 16384: raise ValidationError({'picture': [ lazy_gettext('Maximum picture size is {maxsize} KiB').format(maxsize=16) ]}) return data
def validate(self): """This does not show up immediately, but it's good for now. """ valid = True if not Form.validate(self): valid = False if not (self.email.data or self.phone.data): self.email.errors.append(lazy_gettext("Email or phone required.")) self.phone.errors.append(lazy_gettext("Email or phone required.")) valid = False return valid
def validate(self): if not super(RecoverPasswordForm, self).validate(): return False user = User.query.filter(User.email == self.email.data).first() if user and user.enabled: return True elif user and not user.enabled: flash(lazy_gettext('Account not confirmed.'), 'danger') return False else: flash(lazy_gettext('Invalid email.'), 'danger') return False
def validate(self): validated = super(ProfileForm, self).validate() if self.password.data != self.password_conf.data: message = lazy_gettext("Passwords aren't the same.") self.password.errors.append(message) self.password_conf.errors.append(message) validated = False if self.nickname.data != User.make_valid_nickname(self.nickname.data): self.nickname.errors.append(lazy_gettext('This nickname has ' 'invalid characters. Please use letters, numbers, dots and' ' underscores only.')) validated = False return validated
def create(self, user, data): from mini_fiction.models import Tag, AdminLog if not user or not user.is_staff: raise ValueError('Not authorized') data = Validator(TAG).validated(data) errors = {} bad_reason = self.validate_tag_name(data['name']) if bad_reason: errors['name'] = [bad_reason] iname = normalize_tag(data['name']) if not bad_reason and Tag.get(iname=iname): errors['name'] = [lazy_gettext('Tag already exists')] canonical_tag = None if data.get('is_alias_for'): canonical_tag = Tag.get(iname=normalize_tag(data['is_alias_for'])) if not canonical_tag: errors['is_alias_for'] = [lazy_gettext('Tag not found')] if errors: raise ValidationError(errors) tag = Tag( name=data['name'], iname=iname, category=data.get('category'), color=data.get('color') or '', description=data.get('description') or '', is_main_tag=data.get('is_main_tag', False), created_by=user, is_alias_for=None, reason_to_blacklist='', ) tag.flush() AdminLog.bl.create(user=user, obj=tag, action=AdminLog.ADDITION) if data.get('reason_to_blacklist'): tag.bl.set_blacklist(user, data['reason_to_blacklist']) elif canonical_tag: tag.bl.make_alias_for(user, canonical_tag, hidden=data.get('is_hidden_alias', False)) return tag
def update(self, author, data): from mini_fiction.models import AdminLog data = Validator(CHARACTER_GROUP).validated(data, update=True) group = self.model if 'name' in data: from mini_fiction.models import CharacterGroup exist_group = CharacterGroup.get(name=data['name']) if exist_group and exist_group.id != group.id: raise ValidationError({'name': [lazy_gettext('Group already exists')]}) changed_fields = set() for key, value in data.items(): if getattr(group, key) != value: setattr(group, key, value) changed_fields |= {key,} if changed_fields: AdminLog.bl.create( user=author, obj=group, action=AdminLog.CHANGE, fields=sorted(changed_fields), ) return group
def update(self, author, data): from mini_fiction.models import AdminLog data = Validator(CATEGORY).validated(data, update=True) category = self.model if 'name' in data: from mini_fiction.models import Category exist_category = Category.get(name=data['name']) if exist_category and exist_category.id != category.id: raise ValidationError({'name': [lazy_gettext('Category already exists')]}) changed_fields = set() for key, value in data.items(): if getattr(category, key) != value: setattr(category, key, value) changed_fields |= {key,} if changed_fields: AdminLog.bl.create( user=author, obj=category, action=AdminLog.CHANGE, fields=sorted(changed_fields), ) return category
def get_blacklisted_tags(self, tags): """Принимает множество строк и возвращает словарь запрещённых тегов с описанием причины запрета. Если ничего не запрещено, словарь пуст. """ from mini_fiction.models import Tag result = {} inames = [] # Проверяем корректность синтаксиса for x in tags: reason = self.validate_tag_name(x) if reason is not None: result[x] = reason inames.append(None) else: iname = normalize_tag(x) if not iname: result[x] = lazy_gettext('Empty tag') inames.append(iname) # Проверяем чёрный список в базе данных inames_for_search = [x for x in inames if x] if inames_for_search: bl_tags = {t.iname: t for t in orm.select( x for x in Tag if x.iname in inames_for_search and x.is_blacklisted )} for x, iname in zip(tags, inames): if iname in bl_tags: result[x] = bl_tags[iname].reason_to_blacklist return result
def _get_choices(self): ''' Customization of Country field to allow selection of `None`. ''' choices = self._get_choices_old() choices.insert(0, ('ZZ', lazy_gettext('Choose your country'),)) return choices
def login(): """Presents the login form and processes responses from that form. When a POST request is recieved, this function passes control to the appropriate :py:meth:`login <evesrp.auth.AuthMethod.login>` method. """ # forms is a list of tuples. The tuples are # (AuthMethod instance, AuthForm instance) forms = [] for auth_method in current_app.auth_methods: prefix = auth_method.safe_name form = auth_method.form() forms.append((auth_method, form(prefix=prefix))) if request.method == 'POST': # Find the form that was submitted. The unique prefix for each form # means only one form.submit is going to be valid. for auth_tuple in forms: if auth_tuple[1].submit.data: auth_method, form = auth_tuple break else: abort(400) if form.validate(): return auth_method.login(form) return render_template('login.html', forms=forms, title=lazy_gettext(u'Log In'))
def _get_choices(self): """ Customization of Country field to allow selection of `None`. """ choices = self._get_choices_old() choices.insert(0, ("ZZ", lazy_gettext("Choose your country"))) return choices
def check_password_strength( password, min_len=8, max_len=15, uppercase=True, lowercase=True, numeric=True, special=True, message=""): """Check password strength, return True if passed. Otherwise return False with exact failure message. """ required_chars = [] if uppercase: required_chars.append(r'[A-Z]') if lowercase: required_chars.append(r'[a-z]') if numeric: required_chars.append(r'[0-9]') if special: required_chars.append(r'[!@$%^&*#]') pwd_len = len(password) if pwd_len < min_len or pwd_len > max_len: message = lazy_gettext( u'Password must be between {0} and {1} characters' .format(min_len, max_len)) return False, message valid = all(re.search(ch, password) for ch in required_chars) if not valid: return False, message else: return True, None
def __call__(self, form, field): try: if field.data: r = requests.get(field.data) if r.status_code != 200: raise ValidationError(self.message) except requests.exceptions.ConnectionError: raise ValidationError(lazy_gettext(u"Connection error"))
def validate(self): validated = super(UserForm, self).validate() if self.nickname.data != User.make_valid_nickname(self.nickname.data): self.nickname.errors.append(lazy_gettext( 'This nickname has invalid characters. ' 'Please use letters, numbers, dots and underscores only.')) validated = False return validated
def recent_users(): ''' Most recent users. ''' users = User.query_in_deployment().order_by(desc(User.created_at)).limit(10).all() return render_template('search-results.html', **{'title': lazy_gettext('Our most recent members'), 'results': users, 'query': ''})
def test_lazy_gettext(self): app = flask.Flask(__name__) b = babel.Babel(app, default_locale='de_DE') yes = lazy_gettext(u'Yes') with app.test_request_context(): assert text_type(yes) == 'Ja' app.config['BABEL_DEFAULT_LOCALE'] = 'en_US' with app.test_request_context(): assert text_type(yes) == 'Yes'
def delete(self, author): from mini_fiction.models import AdminLog htmlblock = self.model if htmlblock.is_template and not author.is_superuser: raise ValidationError({'is_template': [lazy_gettext('Access denied')]}) later(self.clear_cache, htmlblock.name) AdminLog.bl.create(user=author, obj=htmlblock, action=AdminLog.DELETION) htmlblock.delete()
def validate_name(form, field): ''' This defines an inline validator to check that the project name is unique. The naming is important - it must start with the word validate be followed by an underscore and then the name of the field. ''' num_same_names = db.session.query(db.func.count()).filter(Project.name==field.data).filter(Project.id<>session.get('project_id', -1)).scalar() if num_same_names > 0: raise ValidationError(lazy_gettext('Name already used. Maybe a writer should try to be more original?'))
def test_lazy_gettext(self): app = flask.Flask(__name__) babel.Babel(app, default_locale='de_DE') yes = lazy_gettext(u'Yes') with app.test_request_context(): assert text_type(yes) == 'Ja' assert yes.__html__() == 'Ja' app.config['BABEL_DEFAULT_LOCALE'] = 'en_US' with app.test_request_context(): assert text_type(yes) == 'Yes' assert yes.__html__() == 'Yes' hello = lazy_gettext(u'Hello %(name)s!') app.config['BABEL_DEFAULT_LOCALE'] = 'de_DE' with app.test_request_context(): assert hello % {'name': 'Peter'} == 'Hallo Peter!' app.config['BABEL_DEFAULT_LOCALE'] = 'en_US' with app.test_request_context(): assert hello % {'name': 'Peter'} == 'Hello Peter!'
def validate_tag_name(self, name): iname = normalize_tag(name) if not iname: return lazy_gettext('Empty tag') for regex, reason in current_app.config['TAGS_BLACKLIST_REGEX'].items(): if re.search(regex, iname, flags=re.IGNORECASE): return reason return None
'types': ['on_off'], 'measurements': [6] }, 7: { 'name': 'Channel 8', 'types': ['on_off'], 'measurements': [7] } } # Output information OUTPUT_INFORMATION = { 'output_name_unique': 'PCF8574', 'output_name': "{} PCF8574 (8 Channels)".format(lazy_gettext('On/Off')), 'output_library': 'smbus2', 'measurements_dict': measurements_dict, 'channels_dict': channels_dict, 'output_types': ['on_off'], 'url_manufacturer': 'https://www.ti.com/product/PCF8574', 'url_datasheet': 'https://www.ti.com/lit/ds/symlink/pcf8574.pdf', 'url_product_purchase': 'https://www.amazon.com/gp/product/B07JGSNWFF', 'message': 'Controls the 8 channels of the PCF8574.',
def get(self): form = self.form() form.to_user.data = request.args.get("to_user") return render_template("message_form.html", form=form, title=lazy_gettext("Compose Message"))
class ConnectionForm(DynamicForm): conn_id = StringField( lazy_gettext('Conn Id'), widget=BS3TextFieldWidget()) conn_type = SelectField( lazy_gettext('Conn Type'), choices=Connection._types, widget=Select2Widget()) host = StringField( lazy_gettext('Host'), widget=BS3TextFieldWidget()) schema = StringField( lazy_gettext('Schema'), widget=BS3TextFieldWidget()) login = StringField( lazy_gettext('Login'), widget=BS3TextFieldWidget()) password = PasswordField( lazy_gettext('Password'), widget=BS3PasswordFieldWidget()) port = IntegerField( lazy_gettext('Port'), validators=[validators.Optional()], widget=BS3TextFieldWidget()) extra = TextAreaField( lazy_gettext('Extra'), widget=BS3TextAreaFieldWidget()) # Used to customized the form, the forms elements get rendered # and results are stored in the extra field as json. All of these # need to be prefixed with extra__ and then the conn_type ___ as in # extra__{conn_type}__name. You can also hide form elements and rename # others from the connection_form.js file extra__jdbc__drv_path = StringField( lazy_gettext('Driver Path'), widget=BS3TextFieldWidget()) extra__jdbc__drv_clsname = StringField( lazy_gettext('Driver Class'), widget=BS3TextFieldWidget()) extra__google_cloud_platform__project = StringField( lazy_gettext('Project Id'), widget=BS3TextFieldWidget()) extra__google_cloud_platform__key_path = StringField( lazy_gettext('Keyfile Path'), widget=BS3TextFieldWidget()) extra__google_cloud_platform__keyfile_dict = PasswordField( lazy_gettext('Keyfile JSON'), widget=BS3PasswordFieldWidget()) extra__google_cloud_platform__scope = StringField( lazy_gettext('Scopes (comma separated)'), widget=BS3TextFieldWidget())
class InputAdd(FlaskForm): input_type = SelectField( choices=DEVICES, validators=[DataRequired()] ) input_add = SubmitField(lazy_gettext('Add Input'))
'interfaces': ['1WIRE'], 'custom_options': [{ 'id': 'library', 'type': 'select', 'default_value': 'w1thermsensor', 'options_select': [('w1thermsensor', 'w1thermsensor'), ('ow_shell', 'ow-shell')], 'required': True, 'constraints_pass': constraints_pass_measure_range, 'name': lazy_gettext('Library'), 'phrase': lazy_gettext('Select the library used to communicate') }] } class InputModule(AbstractInput): """ A sensor support class that monitors the DS18S20's temperature """ def __init__(self, input_dev, testing=False): super(InputModule, self).__init__() self.setup_logger(testing=testing, name=__name__, input_dev=input_dev) if not testing: from w1thermsensor import W1ThermSensor
('pip-pypi', 'adafruit_extended_bus', 'adafruit-extended-bus==1.0.1'), ('pip-pypi', 'adafruit_framebuf', 'adafruit-circuitpython-framebuf'), ('pip-pypi', 'adafruit_ssd1306', 'Adafruit-Circuitpython-SSD1306')], 'custom_options': [{ 'id': 'period', 'type': 'float', 'default_value': 10, 'required': True, 'constraints_pass': constraints_pass_positive_value, 'name': lazy_gettext('Period (seconds)'), 'phrase': lazy_gettext('The duration (seconds) between measurements or actions') }, { 'id': 'number_line_sets', 'type': 'integer', 'default_value': 1, 'required': True, 'constraints_pass': constraints_pass_positive_value, 'name': 'Number of Line Sets', 'phrase': 'How many sets of lines to cycle on the LCD' }, { 'id': 'spi_device', 'type': 'integer', 'default_value': 0, 'required': True,
from utils import get_news, get_speakers EVENT = gettext('PyCon SK 2020 | 27 - 29 March 2020 | Bratislava, Slovakia') DOMAIN = 'https://2020.pycon.sk' API_DOMAIN = 'https://api.pycon.sk' LANGS = ('en', 'sk') TIME_FORMAT = '%Y-%m-%dT%H:%M:%S+00:00' app = Flask(__name__, static_url_path='/static') # pylint: disable=invalid-name app.config['BABEL_DEFAULT_LOCALE'] = 'sk' app.jinja_options = {'extensions': ['jinja2.ext.with_', 'jinja2.ext.i18n']} babel = Babel(app) # pylint: disable=invalid-name CATEGORIES = { 'conference': lazy_gettext('Conference'), 'media': lazy_gettext('Media'), 'speakers': lazy_gettext('Speakers'), } SPEAKERS = get_speakers() NEWS = get_news() @app.route('/sitemap.xml') def sitemap(): excluded = {'static', 'sitemap'} pages = [] for lang in LANGS: for rule in app.url_map.iter_rules():
class CustomErrorHandler(cerberus.errors.BasicErrorHandler): messages = cerberus.errors.BasicErrorHandler.messages.copy() messages.update({ 0x02: lazy_gettext("Required field"), 0x03: lazy_gettext("Unknown field"), 0x04: lazy_gettext("Field '{0}' is required"), 0x05: lazy_gettext("Depends on these values: {constraint}"), 0x06: lazy_gettext("{0} must not be present with '{field}'"), 0x21: lazy_gettext("'{0}' is not a document, must be a dict"), 0x22: lazy_gettext("Field should not be empty"), 0x23: lazy_gettext("Field should not be empty"), 0x24: lazy_gettext("Must be of {constraint} type"), 0x26: lazy_gettext("Length of list should be {constraint}, it is {0}"), 0x27: lazy_gettext("Min length is {constraint}"), 0x28: lazy_gettext("Max length is {constraint}"), 0x41: lazy_gettext("Value does not match regex '{constraint}'"), 0x42: lazy_gettext("Min value is {constraint}"), 0x43: lazy_gettext("Max value is {constraint}"), 0x44: lazy_gettext("Unallowed value {value}"), 0x45: lazy_gettext("Unallowed values {0}"), 0x46: lazy_gettext("Unallowed value {value}"), 0x47: lazy_gettext("Unallowed values {0}"), 0x61: lazy_gettext("Field '{field}' cannot be coerced: {0}"), 0x62: lazy_gettext("Field '{field}' cannot be renamed: {0}"), 0x63: lazy_gettext("Field is read-only"), 0x64: lazy_gettext("Default value for '{field}' cannot be set: {0}"), 0x81: lazy_gettext("Mapping doesn't validate subschema: {0}"), 0x82: lazy_gettext("One or more sequence-items don't validate: {0}"), 0x83: lazy_gettext("One or more properties of a mapping don't validate: {0}"), 0x84: lazy_gettext("One or more values in a mapping don't validate: {0}"), 0x85: lazy_gettext("One or more sequence-items don't validate: {0}"), 0x91: lazy_gettext("One or more definitions validate"), 0x92: lazy_gettext("None or more than one rule validate"), 0x93: lazy_gettext("No definitions validate"), 0x94: lazy_gettext("One or more definitions don't validate"), 0x4127: lazy_gettext("Min length is {constraint}"), 0x4128: lazy_gettext("Max length is {constraint}"), 0x4141: lazy_gettext("Value does not match regex '{0}'"), }) def __init__(self, tree=None, custom_messages=None): super().__init__(tree) self.custom_messages = custom_messages or {} def _format_message(self, field, error): # Собираем аргументы для форматирования сообщения об ошибке fmt_args = error.info fmt_kwargs = {'constraint': error.constraint, 'field': field, 'value': error.value} custom_msg = None # Пробегаемся по кастомным сообщениям согласно пути к правилу в schema_path # (для кастомных правил schema_path пуст, если не использовать # ErrorDefinition, поэтому он тут используется, хоть и плохо # документирован в Cerberus) tmp = self.custom_messages for i, x in enumerate(error.schema_path): try: # Шажок tmp = tmp[x] except KeyError: # Шажок не удался, упёрлись # Если мы достигли места назначения (правила, выдавшего ошибку), # то берём его универсальное сообщение об ошибке if i == len(error.schema_path) - 1 and 'any' in tmp: custom_msg = tmp['any'] break # Если в цикле выше не упёрлись, то в tmp будет или сообщение об ошибке, # или, если не дошагали, словарь-кусок схемы if custom_msg is None: if isinstance(tmp, dict): # Если сообщения нет, возвращаем родное сообщение return super()._format_message(field, error) custom_msg = tmp # Сообщение может быть функцией, чтобы генерировать его динамически if callable(custom_msg): custom_msg = custom_msg() # Форматируем. Обёрнуто в str() ради всяких lazy_gettext return str(custom_msg).format(*fmt_args, **fmt_kwargs)
# NOTE: Be sure to wrap any new partner descriptions with lazy_gettext() # so that the text can be translated. See the existing partner descriptions # as examples. # NOTE: Quote marks in this text need to be replaced with the html code: " # More fancy, left and right quotes may be used: “ and ” PARTNERS = [ { "name": "servishero", "url": "https://servishero.com/", "desc": lazy_gettext( "ServisHero is building their services marketplace that empowers workers in developing countries on Origin Protocol." ) }, { "name": "canya", "url": "https://canya.io/", "desc": lazy_gettext( "CanYa is building a blockchain-powered “marketplace of services” with Origin Protocol for the gig economy and freelancing." ) }, { "name": "beetoken",
('pip-pypi', 'anyleaf', 'anyleaf==0.1.8.1')], 'interfaces': ['I2C'], 'i2c_location': ['0x48', '0x49'], 'i2c_address_editable': False, 'custom_options': [ { 'id': 'temperature_comp_meas', 'type': 'select_measurement', 'default_value': '', 'options_select': ['Input', 'Function', 'Math'], 'name': lazy_gettext('Temperature Compensation Measurement'), 'phrase': lazy_gettext('Select a measurement for temperature compensation') }, { 'id': 'max_age', 'type': 'integer', 'default_value': 120, 'required': True, 'constraints_pass': constraints_pass_positive_value, 'name':
class BaseInterface(object): """ Base class for all data model interfaces. Sub class it to implement your own interface for some data engine. """ obj = None filter_converter_class = None """ when sub classing override with your own custom filter converter """ """ Messages to display on CRUD Events """ add_row_message = lazy_gettext('Added Row') edit_row_message = lazy_gettext('Changed Row') delete_row_message = lazy_gettext('Deleted Row') delete_integrity_error_message = lazy_gettext( 'Associated data exists, please delete them first') add_integrity_error_message = lazy_gettext( 'Integrity error, probably unique constraint') edit_integrity_error_message = lazy_gettext( 'Integrity error, probably unique constraint') general_error_message = lazy_gettext('General Error') """ Tuple with message and text with severity type ex: ("Added Row", "info") """ message = () def __init__(self, obj): self.obj = obj def _get_attr_value(self, item, col): if not hasattr(item, col): # it's an inner obj attr try: return reduce(getattr, col.split('.'), item) except Exception as e: return '' if hasattr(getattr(item, col), '__call__'): # its a function return getattr(item, col)() else: # its an attribute return getattr(item, col) def get_filters(self, search_columns=None): search_columns = search_columns or [] return Filters(self.filter_converter_class, self, search_columns) def get_values_item(self, item, show_columns): return [self._get_attr_value(item, col) for col in show_columns] def _get_values(self, lst, list_columns): """ Get Values: formats values for list template. returns [{'col_name':'col_value',....},{'col_name':'col_value',....}] :param lst: The list of item objects from query :param list_columns: The list of columns to include """ retlst = [] for item in lst: retdict = {} for col in list_columns: retdict[col] = self._get_attr_value(item, col) retlst.append(retdict) return retlst def get_values(self, lst, list_columns): """ Get Values: formats values for list template. returns [{'col_name':'col_value',....},{'col_name':'col_value',....}] :param lst: The list of item objects from query :param list_columns: The list of columns to include """ for item in lst: retdict = {} for col in list_columns: retdict[col] = self._get_attr_value(item, col) yield retdict def get_values_json(self, lst, list_columns): """ Converts list of objects from query to JSON """ result = [] for item in self.get_values(lst, list_columns): for key, value in list(item.items()): if isinstance(value, datetime.datetime) or isinstance( value, datetime.date): value = value.isoformat() item[key] = value if isinstance(value, list): item[key] = [str(v) for v in value] result.append(item) return result """ Returns the models class name useful for auto title on views """ @property def model_name(self): return self.obj.__class__.__name__ """ Next methods must be overridden """ def query(self, filters=None, order_column='', order_direction='', page=None, page_size=None): pass def is_image(self, col_name): return False def is_file(self, col_name): return False def is_gridfs_file(self, col_name): return False def is_gridfs_image(self, col_name): return False def is_string(self, col_name): return False def is_text(self, col_name): return False def is_integer(self, col_name): return False def is_numeric(self, col_name): return False def is_float(self, col_name): return False def is_boolean(self, col_name): return False def is_date(self, col_name): return False def is_datetime(self, col_name): return False def is_relation(self, prop): return False def is_relation_col(self, col): return False def is_relation_many_to_one(self, prop): return False def is_relation_many_to_many(self, prop): return False def is_relation_one_to_one(self, prop): return False def is_relation_one_to_many(self, prop): return False def is_nullable(self, col_name): return True def is_unique(self, col_name): return False def is_pk(self, col_name): return False def is_fk(self, col_name): return False def get_max_length(self, col_name): return -1 def get_min_length(self, col_name): return -1 """ ----------------------------------------- FUNCTIONS FOR CRUD OPERATIONS ----------------------------------------- """ def add(self, item): """ Adds object """ raise NotImplementedError def edit(self, item): """ Edit (change) object """ raise NotImplementedError def delete(self, item): """ Deletes object """ raise NotImplementedError def get_col_default(self, col_name): pass def get_keys(self, lst): """ return a list of pk values from object list """ pk_name = self.get_pk_name() return [getattr(item, pk_name) for item in lst] def get_pk_name(self): """ Returns the primary key name """ raise NotImplementedError def get_pk_value(self, item): return getattr(item, self.get_pk_name()) def get(self, pk, filter=None): """ return the record from key, you can optionally pass filters if pk exits on the db but filters exclude it it will return none. """ pass def get_related_model(self, prop): raise NotImplementedError def get_related_interface(self, col_name): """ Returns a BaseInterface for the related model of column name. :param col_name: Column name with relation :return: BaseInterface """ raise NotImplementedError def get_related_obj(self, col_name, value): raise NotImplementedError def get_related_fk(self, model): raise NotImplementedError def get_columns_list(self): """ Returns a list of all the columns names """ return [] def get_user_columns_list(self): """ Returns a list of user viewable columns names """ return self.get_columns_list() def get_search_columns_list(self): """ Returns a list of searchable columns names """ return [] def get_order_columns_list(self, list_columns=None): """ Returns a list of order columns names """ return [] def get_relation_fk(self, prop): pass
'generate_page_variables': generate_page_variables, 'widget_width': 6, 'widget_height': 5, 'custom_options': [ { 'id': 'measurement', 'type': 'select_measurement', 'default_value': '', 'options_select': [ 'Input', 'Math', 'PID' ], 'name': lazy_gettext('Measurement'), 'phrase': lazy_gettext('Select a measurement to display') }, { 'id': 'max_measure_age', 'type': 'integer', 'default_value': 120, 'required': True, 'constraints_pass': constraints_pass_positive_value, 'name': lazy_gettext('Measurement Max Age'), 'phrase': lazy_gettext('The maximum age (seconds) of the measurement') }, { 'id': 'refresh_seconds', 'type': 'float', 'default_value': 30.0,
"This function stores the first available measurement. This is useful if you have multiple sensors that you want to serve as backups in case one stops working, you can set them up in the order of importance. This function will check if a measurement exits, starting with the first measurement. If it doesn't, the next is checked, until a measurement is found. Once a measurement is found, it is stored in the database with the user-set measurement and unit. The output of this function can be used as an input throughout Mycodo. If you need more than 3 measurements to be checked, you can string multiple Redundancy Functions by creating a second Function and setting the first Function's output as the second Function's input.", 'options_enabled': ['measurements_select_measurement_unit', 'custom_options'], 'custom_options': [{ 'id': 'period', 'type': 'float', 'default_value': 60, 'required': True, 'constraints_pass': constraints_pass_positive_value, 'name': lazy_gettext('Period (seconds)'), 'phrase': lazy_gettext('The duration (seconds) between measurements or actions') }, { 'id': 'select_measurement_a', 'type': 'select_measurement', 'default_value': '', 'options_select': ['Input', 'Math', 'Function'], 'name': 'Measurement A', 'phrase': 'Measurement to replace a' }, { 'id': 'measurement_a_max_age', 'type': 'integer', 'default_value':
'measurement': 'duration_time', 'unit': 's' } } channels_dict = { 0: { 'types': ['on_off'], 'measurements': [0] } } # Output information OUTPUT_INFORMATION = { 'output_name_unique': 'wired', 'output_name': "{} GPIO".format(lazy_gettext('On/Off')), 'output_library': 'RPi.GPIO', 'measurements_dict': measurements_dict, 'channels_dict': channels_dict, 'execute_at_modification': execute_at_modification, 'output_types': ['on_off'], 'message': 'The specified GPIO pin will be set HIGH (3.3 volts) or LOW (0 volts) when turned ' 'on or off, depending on the On State option.', 'options_enabled': [ 'button_on', 'button_send_duration' ], 'options_disabled': ['interface'],
class Mapping(db.Model, DatedModel): """A mapping to load entities from a table""" __tablename__ = "mapping" FAILED = "failed" SUCCESS = "success" PENDING = "pending" STATUS = { SUCCESS: lazy_gettext("success"), FAILED: lazy_gettext("failed"), PENDING: lazy_gettext("pending"), } id = db.Column(db.Integer, primary_key=True) query = db.Column("query", JSONB) role_id = db.Column(db.Integer, db.ForeignKey("role.id"), index=True) role = db.relationship(Role, backref=db.backref("mappings", lazy="dynamic")) # noqa collection_id = db.Column(db.Integer, db.ForeignKey("collection.id"), index=True) collection = db.relationship(Collection, backref=db.backref("mappings", lazy="dynamic")) entityset_id = db.Column(db.String(ENTITY_ID_LEN), db.ForeignKey("entityset.id"), nullable=True) entityset = db.relationship(EntitySet, backref=db.backref("mappings", lazy="dynamic")) table_id = db.Column(db.String(ENTITY_ID_LEN), index=True) disabled = db.Column(db.Boolean, nullable=True) last_run_status = db.Column(db.Unicode, nullable=True) last_run_err_msg = db.Column(db.Unicode, nullable=True) def get_proxy_context(self): """Metadata to be added to each generated entity.""" return { "created_at": iso_text(self.created_at), "updated_at": iso_text(self.updated_at), "role_id": self.role_id, "mutable": True, } def update(self, query=None, table_id=None, entityset_id=None): self.updated_at = datetime.utcnow() if query: self.query = query if table_id: self.table_id = table_id self.entityset_id = entityset_id db.session.add(self) def set_status(self, status, error=None): self.last_run_status = status self.last_run_err_msg = error db.session.add(self) def to_dict(self): data = self.to_dict_dates() status = self.STATUS.get(self.last_run_status) data.update({ "id": stringify(self.id), "query": dict(self.query), "role_id": stringify(self.role_id), "collection_id": stringify(self.collection_id), "entityset_id": stringify(self.entityset_id), "table_id": self.table_id, "last_run_status": status, "last_run_err_msg": self.last_run_err_msg, }) return data @classmethod def by_collection(cls, collection_id, table_id=None): q = cls.all().filter(cls.collection_id == collection_id) if table_id is not None: q = q.filter(cls.table_id == table_id) return q @classmethod def delete_by_collection(cls, collection_id): pq = db.session.query(cls) pq = pq.filter(cls.collection_id == collection_id) pq.delete(synchronize_session=False) @classmethod def delete_by_table(cls, entity_id): pq = db.session.query(cls) pq = pq.filter(cls.table_id == entity_id) pq.delete(synchronize_session=False) @classmethod def create(cls, query, table_id, collection, role_id, entityset_id=None): mapping = cls() mapping.role_id = role_id mapping.collection_id = collection.id mapping.update(query, table_id, entityset_id) return mapping def __repr__(self): return "<Mapping(%r, %r)>" % (self.id, self.table_id)
}, 2: { 'measurement': 'specific_enthalpy', 'unit': 'kJ_kg' }, 3: { 'measurement': 'specific_volume', 'unit': 'm3_kg' } } FUNCTION_INFORMATION = { 'function_name_unique': 'HUMIDITY_BULB', 'function_name': "{} ({})".format(lazy_gettext('Humidity'), lazy_gettext('Wet/Dry-Bulb')), 'measurements_dict': measurements_dict, 'message': 'This function calculates the humidity based on wet and dry bulb temperature measurements.', 'options_enabled': ['measurements_select', 'custom_options'], 'custom_options': [{ 'id': 'period', 'type': 'float', 'default_value': 60, 'required': True, 'constraints_pass':
class ConnectionForm(DynamicForm): conn_id = StringField(lazy_gettext('Conn Id'), widget=BS3TextFieldWidget()) conn_type = SelectField(lazy_gettext('Conn Type'), choices=Connection._types, widget=Select2Widget()) host = StringField(lazy_gettext('Host'), widget=BS3TextFieldWidget()) schema = StringField(lazy_gettext('Schema'), widget=BS3TextFieldWidget()) login = StringField(lazy_gettext('Login'), widget=BS3TextFieldWidget()) password = PasswordField(lazy_gettext('Password'), widget=BS3PasswordFieldWidget()) port = IntegerField(lazy_gettext('Port'), validators=[validators.Optional()], widget=BS3TextFieldWidget()) extra = TextAreaField(lazy_gettext('Extra'), widget=BS3TextAreaFieldWidget()) # Used to customized the form, the forms elements get rendered # and results are stored in the extra field as json. All of these # need to be prefixed with extra__ and then the conn_type ___ as in # extra__{conn_type}__name. You can also hide form elements and rename # others from the connection_form.js file extra__jdbc__drv_path = StringField(lazy_gettext('Driver Path'), widget=BS3TextFieldWidget()) extra__jdbc__drv_clsname = StringField(lazy_gettext('Driver Class'), widget=BS3TextFieldWidget()) extra__google_cloud_platform__project = StringField( lazy_gettext('Project Id'), widget=BS3TextFieldWidget()) extra__google_cloud_platform__key_path = StringField( lazy_gettext('Keyfile Path'), widget=BS3TextFieldWidget()) extra__google_cloud_platform__keyfile_dict = PasswordField( lazy_gettext('Keyfile JSON'), widget=BS3PasswordFieldWidget()) extra__google_cloud_platform__scope = StringField( lazy_gettext('Scopes (comma separated)'), widget=BS3TextFieldWidget()) extra__google_cloud_platform__num_retries = IntegerField( lazy_gettext('Number of Retries'), validators=[validators.NumberRange(min=0)], widget=BS3TextFieldWidget(), default=5) extra__grpc__auth_type = StringField(lazy_gettext('Grpc Auth Type'), widget=BS3TextFieldWidget()) extra__grpc__credential_pem_file = StringField( lazy_gettext('Credential Keyfile Path'), widget=BS3TextFieldWidget()) extra__grpc__scopes = StringField(lazy_gettext('Scopes (comma separated)'), widget=BS3TextFieldWidget()) extra__yandexcloud__service_account_json = PasswordField( lazy_gettext('Service account auth JSON'), widget=BS3PasswordFieldWidget(), description='Service account auth JSON. Looks like ' '{"id", "...", "service_account_id": "...", "private_key": "..."}. ' 'Will be used instead of OAuth token and SA JSON file path field if specified.', ) extra__yandexcloud__service_account_json_path = StringField( lazy_gettext('Service account auth JSON file path'), widget=BS3TextFieldWidget(), description= 'Service account auth JSON file path. File content looks like ' '{"id", "...", "service_account_id": "...", "private_key": "..."}. ' 'Will be used instead of OAuth token if specified.', ) extra__yandexcloud__oauth = PasswordField( lazy_gettext('OAuth Token'), widget=BS3PasswordFieldWidget(), description= 'User account OAuth token. Either this or service account JSON must be specified.', ) extra__yandexcloud__folder_id = StringField( lazy_gettext('Default folder ID'), widget=BS3TextFieldWidget(), description= 'Optional. This folder will be used to create all new clusters and nodes by default', ) extra__yandexcloud__public_ssh_key = StringField( lazy_gettext('Public SSH key'), widget=BS3TextFieldWidget(), description= 'Optional. This key will be placed to all created Compute nodes' 'to let you have a root shell there', )
class InstallNotice(FlaskForm): acknowledge = SubmitField(lazy_gettext('I Understand'))
'resulting value as the selected measurement and unit.', 'options_enabled': ['measurements_select_measurement_unit', 'custom_options'], 'custom_options': [{ 'id': 'period', 'type': 'float', 'default_value': 60, 'required': True, 'constraints_pass': constraints_pass_positive_value, 'name': lazy_gettext('Period (seconds)'), 'phrase': lazy_gettext('The duration (seconds) between measurements or actions') }, { 'id': 'select_measurement', 'type': 'select_measurement', 'default_value': '', 'options_select': ['Input', 'Function'], 'name': 'Measurement', 'phrase': 'Measurement to replace "x" in the equation' }, { 'id': 'measurement_max_age', 'type': 'integer', 'default_value':
measurements_dict, 'url_manufacturer': 'https://sonoff.tech/product/wifi-diy-smart-switches/th10-th16', 'measurements_use_same_timestamp': False, 'message': "This Input module allows the use of any temperature/huidity sensor with the TH10/TH16. Changing the Sensor Name option changes the key that's queried from the returned dictionary of measurements. If you would like to use this module with a version of this device that uses the AM2301, change Sensor Name to AM2301.", 'options_enabled': ['measurements_select', 'period', 'pre_output'], 'options_disabled': ['interface'], 'dependencies_module': [('pip-pypi', 'requests', 'requests==2.25.1')], 'custom_options': [{ 'id': 'ip_address', 'type': 'text', 'default_value': '192.168.0.100', 'required': True, 'name': lazy_gettext('IP Address'), 'phrase': 'The IP address of the device' }, { 'id': 'sensor_name', 'type': 'text', 'default_value': 'SI7021', 'required': True, 'name': lazy_gettext('Sensor Name'), 'phrase': 'The name of the sensor connected to the device (specific key name in the returned dictionary)' }]
from flask_babel import lazy_gettext from pages import AppMenu, AppLink from pages.lockdown.traffic import display_traffic from pages.lockdown.mobility_report import display_mobility from pages.lockdown.brussels import display_brussels from pages.lockdown.tomtom import display_tomtom from pages.lockdown.facebook import display_facebook, callback_fb from pages.lockdown.facebook_eu import callback_fb_countries_eu, display_facebook_eu from pages.lockdown.facebook_lux import callback_fb_countries,callback_fb_lux, display_facebook_lux def call_back_fb_eu(app): callback_fb_countries_eu(app) def call_back_fb_lux(app): facebook_lux.callback_fb_countries(app) facebook_lux.callback_fb_lux(app) lockdown_menu = AppMenu(lazy_gettext("Lockdown Impact"), "/lockdown", [ AppLink(lazy_gettext("Mobility Reports"), lazy_gettext("Mobility Report"), "/mobility-reports", display_mobility), AppLink(lazy_gettext("Google-Map Traffic"), lazy_gettext("Google Map Internet Traffic EU"), "/google-map", display_traffic), AppLink(lazy_gettext("TomTom Traffic Data"), lazy_gettext("TomTom Traffic Data"), "/tomtom", display_tomtom), AppLink(lazy_gettext("Brussels"), lazy_gettext("Brussels"), "/brussels", display_brussels), AppLink(lazy_gettext("Facebook"), lazy_gettext("Facebook"), "/facebook", display_facebook, callback_fn=callback_fb), AppLink(lazy_gettext("Facebook-lux"), lazy_gettext("Facebook-lux"), "/facebook_lux", display_facebook_lux, callback_fn=call_back_fb_lux,invisible=True), AppLink(lazy_gettext("Facebook-eu"), lazy_gettext("Facebook-eu"), "/facebook_eu", display_facebook_eu, callback_fn=call_back_fb_eu, invisible=True), ])
'enable_channel_unit_select': True, 'interfaces': ['Mycodo'], 'cmd_command': 'shuf -i 50-70 -n 1', 'custom_options': [{ 'id': 'command_timeout', 'type': 'integer', 'default_value': 60, 'required': True, 'name': lazy_gettext('Command Timeout'), 'phrase': lazy_gettext( 'How long to wait for the command to finish before killing the process.' ) }, { 'id': 'execute_as_user', 'type': 'text', 'default_value': 'pi', 'required': True, 'name': lazy_gettext('User'),
class Conditional(FlaskForm): conditional_id = StringField('Conditional ID', widget=widgets.HiddenInput()) conditional_type = StringField('Conditional Type', widget=widgets.HiddenInput()) input_id = StringField('Input ID', widget=widgets.HiddenInput()) quantity = IntegerField(lazy_gettext('Quantity')) name = StringField(lazy_gettext('Name')) # Output conditional options unique_id_1 = StringField(lazy_gettext('If ID 1')) unique_id_2 = StringField(lazy_gettext('If ID 2')) output_state = StringField(lazy_gettext('If State')) output_duration = DecimalField(lazy_gettext('If Duration (seconds)')) output_duty_cycle = DecimalField(lazy_gettext('If Duty Cycle (%)')) # Input conditional options measurement = StringField(lazy_gettext('If Measurement')) direction = StringField(lazy_gettext('If State')) setpoint = DecimalField(lazy_gettext('If Value')) period = DecimalField(lazy_gettext('Period (seconds)')) refractory_period = DecimalField( lazy_gettext('Refractory Period (seconds)')) max_age = IntegerField(lazy_gettext('Max Age (seconds)')) # Edge detection edge_detected = StringField(lazy_gettext('If Edge Detected')) # Sunrise/sunset rise_or_set = StringField(lazy_gettext('Rise or Set')) latitude = DecimalField(lazy_gettext('Latitude (decimal)')) longitude = DecimalField(lazy_gettext('Longitude (decimal)')) zenith = DecimalField(lazy_gettext('Zenith')) date_offset_days = IntegerField(lazy_gettext('Date Offset (days)')) time_offset_minutes = IntegerField(lazy_gettext('Time Offset (minutes)')) # Timer timer_start_offset = IntegerField(lazy_gettext('Start Offset (seconds)')) timer_start_time = StringField(lazy_gettext('Start Time (HH:MM)')) timer_end_time = StringField(lazy_gettext('End Time (HH:MM)')) # Method trigger_actions_at_period = BooleanField( lazy_gettext('Trigger Every Period')) trigger_actions_at_start = BooleanField( lazy_gettext('Trigger when Activated')) add_cond = SubmitField(lazy_gettext('Add Conditional')) save_cond = SubmitField(lazy_gettext('Save')) delete_cond = SubmitField(lazy_gettext('Delete')) activate_cond = SubmitField(lazy_gettext('Activate')) deactivate_cond = SubmitField(lazy_gettext('Deactivate')) order_up_cond = SubmitField(lazy_gettext('Up')) order_down_cond = SubmitField(lazy_gettext('Down'))
T_INTEGER, T_CHOICE, T_REAL, T_COLOR, T_STRING, T_LIST) from sagenb.misc.misc import SAGENB_ROOT, get_languages from flask_babel import lazy_gettext defaults = { 'max_history_length': 1000, 'default_system': 'sage', 'autosave_interval': 60 * 60, # 1 hour in seconds 'default_pretty_print': False, 'next_worksheet_id_number': -1, # not yet initialized 'language': 'default' } defaults_descriptions = { 'language': { DESC: lazy_gettext('Language'), GROUP: lazy_gettext('Appearance'), TYPE: T_CHOICE, CHOICES: ['default'] + get_languages(), }, } def UserConfiguration_from_basic(basic): c = UserConfiguration() c.confs = copy.copy(basic) return c class UserConfiguration(Configuration): def defaults(self):
class ForgotPassword(FlaskForm): username = StringField( TRANSLATIONS['user']['title'], render_kw={"placeholder": TRANSLATIONS['user']['title']}) submit = SubmitField(lazy_gettext('Submit'))
:param miles: Miles value in string :return: Kilometers value in string """ miles_to_km_rate = Decimal(1.852) miles_list = miles.split("-") kilometers = [ unit_base.format_converted((Decimal(m) * miles_to_km_rate), precision=1) for m in miles_list ] return "-".join(kilometers), KILOMETER_SYMBOL def nautical_miles_to_metric(item, **kwargs): """Converts distance values from nautical miles to metric""" regex = r"(\d+-?,?\.?\d*)((\s*)|(-))((nmi)|([nN]autical [mM]iles?))\b" return unit_base.do_conversion(item, convert, unit_base.format_output, regex, match_index=0, value_index=1) name = "nautical_miles_to_metric" label = lazy_gettext("Length nautical miles to kilometres") callback = nautical_miles_to_metric access_type = "frontend" action_type = "interactive" group = lazy_gettext("length")
'/dev/ttyAMA0', 'uart_baud_rate': 9600, 'custom_options': [{ 'id': 'max_age', 'type': 'integer', 'default_value': 120, 'required': True, 'constraints_pass': constraints_pass_positive_value, 'name': lazy_gettext('Calibration Max Age'), 'phrase': lazy_gettext( 'The Max Age (seconds) of the Input/Math to use for calibration') }] } class InputModule(AbstractInput): """A sensor support class that monitors the Atlas Scientific sensor DO""" def __init__(self, input_dev, testing=False): super(InputModule, self).__init__(input_dev, testing=testing, name=__name__) self.atlas_sensor_ftdi = None self.atlas_sensor_uart = None
def decorated(*args, **kwargs): if not current_user.is_admin(): raise Unauthorized( lazy_gettext( 'You must be an administrator to view this page.')) return f(*args, **kwargs)
'generate_page_variables': generate_page_variables, 'widget_width': 4, 'widget_height': 5, 'custom_options': [{ 'id': 'measurement', 'type': 'select_measurement', 'default_value': '', 'options_select': ['Input', 'Math', 'Function', 'PID'], 'name': lazy_gettext('Measurement'), 'phrase': lazy_gettext('Select a measurement to display') }, { 'id': 'max_measure_age', 'type': 'integer', 'default_value': 120, 'required': True, 'constraints_pass': constraints_pass_positive_value, 'name': lazy_gettext('{} {}'.format(lazy_gettext('Measurement'),
class InputMod(FlaskForm): input_id = StringField('Input ID', widget=widgets.HiddenInput()) name = StringField( lazy_gettext('Name'), validators=[DataRequired()] ) period = DecimalField( lazy_gettext('Period (seconds)'), validators=[DataRequired(), validators.NumberRange( min=5.0, max=86400.0 )] ) location = StringField(lazy_gettext('Location')) # Access input (GPIO, I2C address, etc.) device_loc = StringField(lazy_gettext('Device Location')) # Second device location type i2c_bus = IntegerField(lazy_gettext('I<sup>2</sup>C Bus')) baud_rate = IntegerField(lazy_gettext('Baud Rate')) power_output_id = StringField(lazy_gettext('Power Output')) # For powering input calibrate_sensor_measure = StringField(lazy_gettext('Calibration Measurement')) resolution = IntegerField(lazy_gettext('Resolution')) resolution_2 = IntegerField(lazy_gettext('Resolution')) sensitivity = IntegerField(lazy_gettext('Sensitivity')) convert_to_unit = StringField(lazy_gettext('Unit')) # Server options host = StringField(lazy_gettext('Host')) port = IntegerField(lazy_gettext('Port')) times_check = IntegerField(lazy_gettext('Times to Check')) deadline = IntegerField(lazy_gettext('Deadline (seconds)')) # Linux Command cmd_command = StringField(lazy_gettext('Command')) cmd_measurement = StringField(lazy_gettext('Measurement')) cmd_measurement_units = StringField(lazy_gettext('Unit')) # MAX chip options thermocouple_type = StringField(lazy_gettext('RTD Probe Type')) ref_ohm = IntegerField(lazy_gettext('Reference Resistance (Ohm)')) # SPI Communication pin_clock = IntegerField(lazy_gettext('Clock Pin')) pin_cs = IntegerField(lazy_gettext('CS Pin')) pin_mosi = IntegerField(lazy_gettext('MOSI Pin')) pin_miso = IntegerField(lazy_gettext('MISO Pin')) # Bluetooth Communication bt_adapter = StringField(lazy_gettext('BT Adapter')) # ADC adc_channel = IntegerField(lazy_gettext('Channel')) adc_gain = IntegerField(lazy_gettext('Gain')) adc_resolution = IntegerField(lazy_gettext('Resolution')) adc_measurement = StringField(lazy_gettext('Measurement')) adc_measurement_units = StringField(lazy_gettext('Measurement Units')) adc_volts_min = DecimalField(lazy_gettext('Volts Min')) adc_volts_max = DecimalField(lazy_gettext('Volts Max')) adc_units_min = DecimalField(lazy_gettext('Units Min')) adc_units_max = DecimalField(lazy_gettext('Units Max')) adc_inverse_unit_scale = BooleanField(lazy_gettext('Inverse Unit Scale')) switch_edge = StringField(lazy_gettext('Edge')) switch_bounce_time = IntegerField(lazy_gettext('Bounce Time (ms)')) switch_reset_period = IntegerField(lazy_gettext('Reset Period')) # Pre-Output pre_output_id = StringField(lazy_gettext('Pre Output')) pre_output_duration = DecimalField( lazy_gettext('Pre Out Duration'), validators=[validators.NumberRange( min=0, max=86400 )] ) pre_output_during_measure = BooleanField(lazy_gettext('Pre During Measure')) # RPM/Signal weighting = DecimalField(lazy_gettext('Weighting')) rpm_pulses_per_rev = DecimalField(lazy_gettext('Pulses Per Rev')) sample_time = DecimalField(lazy_gettext('Sample Time (seconds)')) # SHT options sht_voltage = StringField(lazy_gettext('Voltage')) input_mod = SubmitField(lazy_gettext('Save')) input_delete = SubmitField(lazy_gettext('Delete')) input_activate = SubmitField(lazy_gettext('Activate')) input_deactivate = SubmitField(lazy_gettext('Deactivate')) input_order_up = SubmitField(lazy_gettext('Up')) input_order_down = SubmitField(lazy_gettext('Down'))