def formfield_from_modelfield(field): field_type = field.__class__.__name__.lower() opts = { 'validators': [] } default = getattr(field, 'default', odis.EMPTY) if field_type == 'relfield': opts['queryset'] = field.model.obj.all() if is_coll_field(field): opts['validators'].append(validators.optional()) elif default != odis.EMPTY or getattr(field, 'nil', False): opts['validators'].append(validators.optional()) else: opts['validators'].append(validators.required()) if default != odis.EMPTY: opts['default'] = default if getattr(field, 'choices', False): opts['choices'] = field.choices opts['label'] = field.verbose_name or field.name if 'choices' in opts: form_field = fields.SelectField #opts['coerce'] = field.to_python else: form_field = fields_table[field_type] return form_field(**opts)
def test_optional(self): self.assertEqual(optional()(self.form, DummyField("foobar", raw_data=["foobar"])), None) self.assertRaises(StopValidation, optional(), self.form, DummyField("", raw_data=[""])) self.assertRaises(StopValidation, optional(), self.form, DummyField(" ", raw_data=[" "])) self.assertEqual(optional().field_flags, ("optional",)) f = DummyField("", ["Invalid Integer Value"], raw_data=[""]) self.assertEqual(len(f.errors), 1) self.assertRaises(StopValidation, optional(), self.form, f) self.assertEqual(len(f.errors), 0)
def test_optional(self): self.assertEqual(optional()(self.form, DummyField('foobar', raw_data=['foobar'])), None) self.assertRaises(StopValidation, optional(), self.form, DummyField('', raw_data=[''])) self.assertRaises(StopValidation, optional(), self.form, DummyField(' ', raw_data=[' '])) self.assertEqual(optional().field_flags, ('optional', )) f = DummyField('', ['Invalid Integer Value'], raw_data=['']) self.assertEqual(len(f.errors), 1) self.assertRaises(StopValidation, optional(), self.form, f) self.assertEqual(len(f.errors), 0)
def build_questionnaire(form, data=None): fields = {'groups': []} fields['participant'] = StringField( u'Participant', filters=[partial(filter_participants, form)], validators=[validators.required()]) for group in form.groups: groupspec = (group.name, []) for field in group.fields: # if the field has options, create a list of choices if field.options: choices = [(v, k) for k, v in field.options.iteritems()] if field.allows_multiple_values: fields[field.name] = IntegerSplitterField( field.name, choices=choices, description=field.description, validators=[validators.optional()], ) else: fields[field.name] = SelectField( field.name, choices=choices, coerce=int, description=field.description, validators=[validators.optional()], widget=widgets.TextInput() ) else: if form.form_type == 'CHECKLIST': fields[field.name] = IntegerField( field.name, description=field.description, validators=[ validators.optional(), validators.NumberRange(min=field.min_value, max=field.max_value)] ) else: fields[field.name] = IntegerField( field.name, description=field.description, validators=[validators.optional()] ) fields['groups'].append(groupspec) form_class = type('QuestionnaireForm', (BaseQuestionnaireForm,), fields) return form_class(data)
def load_filters(cls, filters): '''Load Filter Fields Init a filter form using filter settings arguments: filters: a dict list with information to form a filter with format for each item: 0. id: unique english name for field 1. name: always same as the colums name to be filtered 2. type: using following types - str: this type will only be used for search - float: this type will only be filtered with a min and max val - date: this type will only be filtered with an earliest date and a latest date throw a INVALID_FILTER_FORMAT error when filters not obey this rule ''' must_keys = ('id', 'name', 'type') # check if filters' format is correct for item in filters: for mk in must_keys: if mk not in item.keys(): raise AppError('INVALID_FILTER_FORMAT') # init the filter for item in filters: if item['type'] == 'str': setattr(cls, item['id'], TextField(item['name'])) if item['type'] == 'float': setattr(cls, '{}_min'.format(item['id']), DecimalField('min value of {}'.format(item['name']), [validators.optional()])) setattr(cls, '{}_max'.format(item['id']), DecimalField('max value of {}'.format(item['name']), [validators.optional()])) if item['type'] == 'date': setattr(cls, '{}_earlier'.format(item['id']), DateField('earlier {}'.format(item['name']), [validators.optional()])) setattr(cls, '{}_later'.format(item['id']), DateField('later {}'.format(item['name']), [validators.optional()]))
def scaffold_form(self): class NewForm(Form): pass if self.create_form_class is None: return NewForm for field in self.create_form_class.DESCRIPTOR.fields: if self.form_excluded_columns and field.name in self.form_excluded_columns: continue field_type = field.type if field_type == 11: # Todo: handle "message" type, which is a nested object continue FormClass = wtforms_type_map[field_type] description = self.swagger['definitions'][ 'lnrpc' + self.create_form_class.__name__]['properties'][ field.name] description = description.get('title') or description.get( 'description') if description: description = description.replace('/ ', '') form_field = FormClass(field.name, default=field.default_value or None, description=description, validators=[validators.optional()] ) setattr(NewForm, field.name, form_field) return NewForm
def field_factory(attr): kwargs = defaultdict(list) kwargs['id'] = attr.name kwargs['label'] = attr.comment if attr.in_key: kwargs['validators'].append(required()) if attr.nullable or attr.default is not None: kwargs['validators'].append(optional()) if attr.type.startswith('int'): return wtf.IntegerField(**kwargs) elif attr.type == 'double' or attr.type == 'float': return wtf.FloatField(**kwargs) elif attr.type.startswith('varchar'): ml = int(attr.type.split('(')[-1][:-1]) return wtf.StringField(**kwargs) # TODO: can I specify a max length here? elif attr.type == 'date': kwargs['validators'].append(date_validator) return wtf.DateField(format='%Y-%m-%d', default=datetime.date.today(), **kwargs) elif attr.type.startswith('enum'): choices = [(e[1:-1],e[1:-1]) for e in attr.type[attr.type.find('(')+1:attr.type.rfind(')')].split(',')] return wtf.SelectField(choices=choices, **kwargs) elif attr.type.startswith('char'): l = int(attr.type.split('(')[-1][:-1]) kwargs['validators'].append(len_validator_factory(l)) return wtf.StringField(**kwargs) # TODO: can I specify a max length here? elif attr.type == 'timestamp': return wtf.DateTimeField(format='%Y-%m-%d %H:%M', default=datetime.datetime.today(), **kwargs) else: raise NotImplementedError('FieldFactory does not know what to do with %s' % (attr.type))
def convert(self, column): kwargs = { 'label': column.info.get('label', column.name), 'description': column.description, 'validators': [], 'default': column.default and column.default.arg } if column.info.get('optional', False): kwargs['validators'].append(validators.optional()) elif not column.nullable: kwargs['validators'].append(validators.required()) if hasattr(column.type, 'length') and column.type.length is not None: kwargs['validators'].append(validators.length(max=column.type.length)) fname = type(column.type).__name__ if len(column.foreign_keys) > 0: return self.conv_ForeignKey(kwargs, column) if fname in self.SIMPLE_CONVERSIONS: return self.SIMPLE_CONVERSIONS[fname](**kwargs) else: mod = getattr(self, 'conv_%s' % fname, None) if mod is not None: return mod(kwargs, column)
class PlotForm(FlaskForm): function_text = StringField(u"Function to plot", [validators.required()]) a = FloatField(u"Start", default=0) b = FloatField(u"End", default=1) n = IntegerField(u"Partition count", [validators.number_range(min=1)], default=20) error_method_text = StringField(u"Error method", [validators.optional()]) submit = SubmitField("Plot")
def __init__(self, **kwargs): warnings.warn("Field has been deprecated", PendingDeprecationWarning) defaults = dict(icon='flag', export_key='language', validators=[optional()], widget_classes="form-control") defaults.update(kwargs) super(LanguageField, self).__init__(**defaults)
class ObsIDSearchForm(FlaskForm): obsid = StringField('ObservationID', description='e.g. scuba2_00026_20200724T063132', validators=[validators.optional()]) utdate = IntegerField('UT Date', description='YYYYMMDD format', validators=[validators.optional()]) obsnum = IntegerField('Observation Number', validators=[validators.optional()]) backend = RadioField('Backend', description='Backend', choices=(('ACSIS', 'ACSIS'), ('SCUBA-2', 'SCUBA-2')), validators=[ validators.optional(), ], widget=ListWidget(prefix_label=True), option_widget=RadioInput())
class EndpointForm(Form): host = StringField(label="IP/Hostname:", validators=[validators.optional()]) port = IntegerField(label="Port:", validators=[ validators.NumberRange( min=0, max=65535, message="Please enter a valid port number " "(0-65535)."), validators.optional() ]) version = NonValidatingSelectField(label="API Version:", choices=[("v1.0", "v1.0"), ("v1.1", "v1.1"), ("v1.2", "v1.2"), ("v1.3", "v1.3")])
class CreateProductForm(FlaskForm): name = StringField('name', validators=[DataRequired()], description='Product name') description = TextAreaField('description', validators=[optional(), length(max=200)], description='Product description')
class UserLeave(Form): bye1 = StringField(u'Leaving', [validators.optional(), validators.length(max=3)]) bye2 = StringField(u'US', [validators.DataRequired(), validators.length(max=3)]) submit = SubmitField('submit', [validators.DataRequired()])
class TopicEditForm(ValidateForm): title = StringField('标题', validators=[ va.optional(), va.Length(config.TOPIC_TITLE_LENGTH_MIN, config.TOPIC_TITLE_LENGTH_MAX) ]) content = StringField('正文', validators=[ va.optional(), va.Length(1, config.TOPIC_CONTENT_LENGTH_MAX) ]) sticky_weight = IntegerField('置顶权重', validators=[]) weight = IntegerField('排序权重', validators=[]) board_id = StringField('板块', validators=[ my_optional, board_check ])
def test_input_optional_passes(dummy_form, dummy_field): """ optional should pause with given values """ validator = optional() dummy_field.data = "foobar" dummy_field.raw_data = ["foobar"] validator(dummy_form, dummy_field)
class PostForm(Form): """ Form to submit a Post TODO: Put a note in about Markdown formatting? """ title = TextField('Title', description='', validators=[required()]) url = URLField('URL', description='', validators=[url(), optional()]) text = TextAreaField('Text', description='', validators=[]) kind = TextField('Kind')
class CommissionForm(ContractForm): # 作品集委托辅导 univalent = IntegerField('单价(老师每课时基本薪酬)', validators=[InputRequired()], default=200) lesson = IntegerField('课时数', validators=[InputRequired()], default=40) level = StringField('教师级别', validators=[InputRequired()], default="辅导老师I级") award = IntegerField('奖金', validators=[InputRequired()], default=20) teacher = StringField('老师姓名', validators=[optional()]) works = IntegerField('作品数量', validators=[InputRequired()], default=4)
def __init__(self, **kwargs): defaults = dict( icon='calendar', validators=[optional()], widget_classes="form-control" ) defaults.update(kwargs) super(Date, self).__init__(**defaults)
class RegistrationForm(Form): email = StringField('email', validators=[DataRequired(), Email()]) name = StringField('name', validators=[DataRequired(), validators.length(min=MIN_LENGTH, max=MAX_LENGTH)]) app_name = StringField('app_name', validators=[DataRequired(), validators.length(min=MIN_LENGTH, max=MAX_LENGTH)]) public_wallet = StringField('public_wallet', validators=[validators.optional(), validators.length(min=PUBLIC_WALLET_LENGTH, max=PUBLIC_WALLET_LENGTH), validators.regexp(regex=PUBLIC_ADDRESS_PATTERN)])
class UserNewJobForm(FlaskForm): file = FileField('Upload File', validators=[validators.DataRequired('File Required')]) color = SelectField('Filament Color', choices=['Red', 'Green', 'Blue']) notes = TextAreaField('Special Notes', [validators.optional(), validators.length(max=200)]) submit = SubmitField('Submit')
class BookingForm(FlaskForm): # Luokka varausten lisäämiseen ja muokkaamiseen. # Sallii toistaiseksi duplikaattien lisäämisen. passengers = IntegerField("Matkustajia", [ validators.required(), validators.NumberRange( min=1, max=12, message= "1-12 matkustajaa, suuremmille ryhmille ota yhteyttä matkatoimistoon" ) ]) small_rooms = IntegerField("1-2 hengen huoneita", [validators.optional()]) large_rooms = IntegerField("3-4 hengen huoneita", [validators.optional()]) class Meta: csrf = False
class RegisterForm(KairaForm): name = StringField(u'Full Name', [validators.required(), validators.length(max=10)]) address = TextAreaField( u'Mailing Address', [validators.optional(), validators.length(max=200)])
class DeleteCollaborationApplicationForm(Form): application_id = IntegerField('application_id', validators=[validators.DataRequired()]) is_accepted = IntegerField('is_accepted', validators=[ validators.optional(), validators.NumberRange(min=0, max=1) ])
class RegisterForm(Form): email = StringField('Email', validators=[DataRequired(), Email()]) username = StringField( 'Username', validators=[ DataRequired(), Length(min=3, max=50, message="You must enter a min and max character") ]) password = PasswordField('Password', validators=[ DataRequired(), EqualTo('password2', message='Your Passwords must be same') ]) password2 = PasswordField('Re-Enter Password', validators=[ DataRequired(), EqualTo('password', message='Passwords must match.') ]) title = SelectField('Title', choices=[('mr', 'Mr'), ('miss', 'MIss'), ('mrs', 'Mrs'), ('dr', 'Dr'), ('prof', 'Prof'), ('el', 'El Hadj'), ('rev', 'Rev'), ('hon', 'Honourable')]) first_name = StringField('First Name', validators=[DataRequired()]) last_name = StringField('Last Name', validators=[DataRequired()]) other_names = StringField('Other Names') phone = StringField('Phone Number', validators=[DataRequired()]) address = TextAreaField('Your Address', [validators.optional()]) regions = QuerySelectField(get_label='region', query_factory=region_lists) district = QuerySelectField(get_label='district', query_factory=district_lists) subdistrict = QuerySelectField(get_label='name', query_factory=sub_districts) village = QuerySelectField(get_label='village', query_factory=villages_lists) roles = QuerySelectField(get_label='name', query_factory=roles_list, allow_blank=True) # location = '' # picture = ''name for name, in # position = ''#Roles submit = SubmitField('Register') def validate_email(self, field): if User.query.filter_by(email=field.data).first(): raise ValidationError( 'This email address is being used for a similar registration. Is it yours?' ) def validate_username(self, field): if User.query.filter_by(username=field.data).first(): raise ValidationError( 'This username is already Registered, is it yours?')
class ProjeDegerlendirmeForm(FlaskForm): """Example hakem proje degerlendirme formu""" proje_konusu = fields.RadioButtonField( _('Proje konusu özgün mü?'), choices=proje_degerlendirme_secenekleri) proje_amaci = fields.RadioButtonField( _('Proje amacı açık bir şekilde belirtilmiş mi?'), choices=proje_degerlendirme_secenekleri) proje_bilimsel = fields.RadioButtonField( _('Proje amacı bilimsel bakımdan anlamlı mı?'), choices=proje_degerlendirme_secenekleri) proje_katki = fields.RadioButtonField(_( 'Tamamlandığında sonuçları ile alanında bilime evrensel ve ulusal ölçülerde katkı ' 'yapması ve ülkenin teknolojik, ekonomik ve sosyo-kültürel kalkınmasına yönelik ' 'katkıları var mı ve gerçekçi mi?'), choices= proje_degerlendirme_secenekleri) proje_temeli = fields.RadioButtonField( _('Projenin kuramsal temeli yeterli düzeyde literatür ' 'araştırılması yapılarak verilmiş mi?'), choices=proje_degerlendirme_secenekleri) proje_metot = fields.RadioButtonField( _('Projede uygulanacak metotlar açık bir şekilde verilmiş mi?'), choices=proje_degerlendirme_secenekleri) proje_arastirma = fields.RadioButtonField( _('Proje araştırma yöntemi amacı ile tutarlı mı?'), choices=proje_degerlendirme_secenekleri) proje_takvimi = fields.RadioButtonField( _('Proje takviminde yer alan işler ve iş süreleri proje araştırma yönetimi ile uyumlu mu?' ), choices=proje_degerlendirme_secenekleri) sarf_techizat = fields.RadioButtonField( _('Talep edilen sarf ve teçhizat, araştırmanın amacı ve var olan alt yapı ile uyumlu mu?' ), choices=proje_degerlendirme_secenekleri) sanayi = fields.RadioButtonField(_('Proje sanayide uygulanabilir mi?'), choices=proje_degerlendirme_secenekleri) etik_kurul = fields.RadioButtonField( _('Etik Kurul Kararı gerekli mi?'), choices=proje_degerlendirme_secenekleri) gorus_oneri_degisiklik = TextAreaField( label=("Lütfen varsa görüş ve önerilerinizi belirtiniz."), render_kw={"placeholder": "Görüş / Öneri / Değişiklik"}) dosya = BooleanField(label=_( "Değerlendirmeye ek olarak, " "bilgisayarımdan dosya seçerek yüklemek istiyorum"), default=False) dosya_id = MultiFileField(label=_("Dosya Ekle"), validators=[validators.optional()], ids=uuid4().hex) degerlendirme_sonucu = fields.RadioButtonField( _('Lütfen inceleme sonucunuzu işaretleyiniz?'), choices=[(choice.name, choice.value) for choice in ProjeDegerlendirmeSonuc]) degerlendirme_tamamlandi = BooleanField( label=_("Proje değerlendirmesi tamamlandı."), default=False)
class UpdateCompany(FlaskForm): name = StringField( "Company Name", [validators.optional()], render_kw={ 'placeholder': "The name of the company you're applying to work for." }, ) description = TextAreaField( "Description of the company", [validators.optional()], render_kw={'placeholder': "A description of the company provided."}, ) location = StringField( "Company Location / Head Office", [validators.optional()], render_kw={ 'placeholder': "Where is the company located? If entirely remote, where is their Head Office/Main base of operations?" }, ) industry = StringField( "Industry", [validators.optional()], render_kw={ 'placeholder': "The industry/industries in which this company operates." }, ) interviewers = StringField( "Interviewer/s' Name/s", [validators.optional()], render_kw={ 'placeholder': "The name/s of the interviewer/s for this interview. (If known)" }, ) contact_number = TelField( "Telephone / Mobile number", [validators.optional()], render_kw={ 'placeholder': "The contact number for the interviewers / company." }, description= "The number you'll be expecting a call from for this interview.") url = URLField( "The Company's Website", [validators.optional()], render_kw={ 'placeholder': "The url for the company's website. EG: http://..." }, ) update_button = SubmitField("Update")
class SearchResultForm(FlaskForm): today = datetime.today().date() first_day = today.replace(day=1) last_first_day = first_day + relativedelta(months=-1) last_day = first_day + relativedelta(months=1, days=-1) project_name = StringField('プロジェクト名称', [validators.optional()]) estimation_no = StringField('見積No', [validators.optional()]) result_input_flag = CheckboxField('実績ステータス', choices=InputFlag.get_result_flag_for_radio()) end_user_company_id = SelectMultiFieldWithSubtext('エンドユーザー', [validators.optional()], render_kw={"title": "エンドユーザー(複数選択)", "data-live-search": "true", "data-size": "8", "data-actions-box": "true", "data-selected-text-format": "count > 3"}) client_company_id = SelectMultiFieldWithSubtext('顧客', [validators.optional()], render_kw={"title": "顧客会社(複数選択)", "data-live-search": "true", "data-size": "8", "data-actions-box": "true", "data-selected-text-format": "count > 3"}) recorded_department_id = SelectMultipleField('計上部署', render_kw={"title": "計上部署(複数選択)", "data-size": "8", "data-actions-box": "true", "data-selected-text-format": "count > 3"}) engineer_name = StringField('技術者名称', [validators.optional()]) result_month_from = StringField('実績年月(From)', [validators.optional()], default=last_first_day.strftime('%Y/%m'), render_kw={"autocomplete": "off"}) result_month_to = StringField('実績年月(To)', [validators.optional()], default=last_day.strftime('%Y/%m'), render_kw={"autocomplete": "off"})
class MentorRsvpForm(Form): attending = RadioField("Are you attending hackBCA III?", [ validators.Required( message="Please tell us if you are attending hackBCA III.") ], choices=attending_choices) phone = TextField("Phone Number", [ validators.Required(message="Confirm your preferred contact number."), validators.Regexp(phone_regex, message="Please enter a valid phone number.") ], description="Phone Number Confirmation") t_shirt_size = SelectField( "What is your shirt size?", [validators.Required(message="You must select an option.")], choices=shirt_sizes, description="What is your shirt size?") food_allergies = TextAreaField("Allergies", [ validators.optional(), ], description="Do you have any allergies?") medical_information = TextAreaField( "Medical Information", [ validators.optional(), ], description= "Are there any other medical issues that we should know about? (ex. Other allergies, illnesses, etc.)" ) hackbca_rules = BooleanField( "I agree", [validators.Required(message="Please read and agree to our rules.")], description="I agree to the rules set forth by hackBCA.", default=False) mlh_terms = BooleanField("I agree", [ validators.Required( message="Please read and agree to the MLH Code of Conduct.") ], description="I agree to the MLH Code of Conduct.", default=False)
class NewClientIDForm(FlaskForm): client_id = StringField( 'App Client ID', description='API Client ID you created', validators=[DataRequired(message="Need an OAuth API Client ID")]) service_name = SelectField( 'Service Group Name', description='Arbitrary string used to group like client\'s together', validate_choice=False) other_service = BooleanField('New Service Group', description="Create a new service group", validators=[optional()]) other_service_name = StringField( 'New Service Group Name', description="Name of the new service group desired", validators=[optional()]) auth_url = StringField( 'Authorization URL Endpoint', validators=[ DataRequired( message="Need an OAuth authorization URL for the service") ]) auth_url_qsparams = FieldList(FormField(QueryStringForm), max_entries=8) token_url = StringField( 'Token URL Endpoint', validators=[ DataRequired(message="Need an OAuth token URL for the service") ]) token_qsparams = FieldList(FormField(QueryStringForm), max_entries=8) use_refresh_token = BooleanField( 'Use Refresh Token', description="Enable using the refresh token if desired or available", validators=[optional()]) refresh_token_qsparams = FieldList(FormField(QueryStringForm), max_entries=8) redirect_url = StringField(f'App Redirect/Callback URL', default=f'{settings.OAUTH.REDIRECT_URL}', validators=[optional()]) submit = SubmitField('Submit')
class CertificateForm(Form): cert_title = StringField('인증 서비스명(한글)', validators=[validators.input_required()]) cert_pass = PasswordField('인증키 비밀번호', validators=[validators.input_required()]) country_name = StringField('Country Name', validators=[validators.optional()], description='2자리 국가코드') province_name = StringField('State or Province Name', validators=[validators.optional()], description='시/도') locality_name = StringField('Locality Name', validators=[validators.optional()], description='구/군/시') organization_name = StringField('Organization Name', validators=[validators.optional()], description='회사명') organizational_unit_name = StringField('Organizational Unit Name', validators=[validators.optional()], description='부서명') common_name = StringField('Common Name', validators=[validators.optional()], description='도메인명') email_address = StringField('Email Address', validators=[validators.optional()], description='담당자 이메일') cert_days = StringField('인증서 유효기간(일단위)', validators=[validators.input_required()])
class ProjectForm(FlaskForm): name = StringField('Project name', [validators.DataRequired()]) homepage = StringField('Homepage', [validators.DataRequired(), validators.URL()]) backend = SelectField('Backend', [validators.DataRequired()], choices=[(item, item) for item in []]) version_url = StringField('Version URL', [validators.optional()]) version_prefix = StringField('Version prefix', [validators.optional()]) version_scheme = SelectField('Version scheme', [validators.Required()], choices=[(item, item) for item in []]) regex = StringField('Regex', [validators.optional()]) insecure = BooleanField('Use insecure connection', [validators.optional()]) distro = StringField('Distro (optional)', [validators.optional()]) package_name = StringField('Package (optional)', [validators.optional()]) check_release = BooleanField('Check latest release on submit', [validators.optional()]) def __init__(self, *args, **kwargs): """ Calls the default constructor with the normal argument but uses the list of backends provided to fill the choices of the drop-down list. """ super(ProjectForm, self).__init__(*args, **kwargs) if 'backends' in kwargs: self.backend.choices = [(backend, backend) for backend in sorted(kwargs['backends'])] if 'version_schemes' in kwargs: self.version_scheme.choices = [ (version_scheme, version_scheme) for version_scheme in sorted(kwargs['version_schemes']) ]
class OfficeUpdateCoordinatesForm(OfficeHiddenIdentificationForm): CONTACT_MODES = ( ('mail', 'Par courrier'), ('email', 'Par email'), ('phone', 'Par téléphone'), ('office', 'Sur place'), ('website', 'Via votre site internet'), ) CONTACT_MODES_LABELS = dict(CONTACT_MODES) # Note : we add new_ to avoid conflict with request.args new_contact_mode = RadioField( 'Mode de contact à privilégier', choices=CONTACT_MODES, default='email' ) new_website = StringField( 'Site Internet', validators=[URL(), Optional()], render_kw={"placeholder": "http://exemple.com"} ) new_email = EmailField( 'Email recruteur', validators=[Email(), Optional()], render_kw={"placeholder": "*****@*****.**"} ) new_phone = StringField( 'Téléphone', validators=[Optional(), Regexp(PHONE_REGEX)], render_kw={"placeholder": "01 77 86 39 49, +331 77 86 39 49"} ) social_network = StringField('Réseau social', validators=[URL(), Optional()]) new_email_alternance = EmailField( 'Email recruteur spécialisé alternance', validators=[validators.optional(), Email()], render_kw={"placeholder": "*****@*****.**"} ) new_phone_alternance = StringField( 'Téléphone du recruteur spécialisé alternance', validators=[validators.optional(), Regexp(PHONE_REGEX)], render_kw={"placeholder": "01 77 86 39 49, +331 77 86 39 49"} ) rgpd_consent = BooleanField( 'En cochant cette case, vous consentez à diffuser des données à caractère personnel sur les services numériques de Pôle emploi.', [validators.required()] )
class RegistrationForm(Form): name = StringField( 'Name', [validators.required(), validators.Length(min=4, max=25)]) email = StringField( 'Email Address', [validators.required(), validators.email()]) phone = IntegerField('Phone Number (Optional)', [validators.optional()]) text = TextAreaField('Message', [validators.required()])
class AddressForm(Form): firstname = StringField('First Name', validators=[validators.Length(min=1, max=150), validators.DataRequired()]) lastname = StringField('Last Name', validators=[validators.Length(min=1,max=150), validators.DataRequired()]) address = StringField('Address', validators=[validators.DataRequired()]) country = StringField('Country',validators=[validators.DataRequired()]) city = StringField('City', validators=[validators.DataRequired()]) state = StringField('State', validators=[validators.optional()]) zipcode = StringField('ZIP Code/Postal Code', validators=[validators.DataRequired()]) mobile = TelField('Mobile Number', validators=[validators.DataRequired()])
class EditPetForm(FlaskForm): photo_url = StringField( 'Photo URL', validators=[URL(message='Must be a valid URL'), optional()]) notes = TextAreaField('Notes') available = BooleanField('This Pet is Available')
class UserSettingsForm(FlaskForm): """Form used to provide the Phabricator API Token.""" phab_api_token = StringField('Phabricator API Token', validators=[ optional(), Regexp('^api-[a-z0-9]{28}$', message='Invalid API Token format') ]) reset_phab_api_token = BooleanField('Delete', default="")
class TokenForm(FlaskForm): """ Form for API tokens. Attributes: description (StringField): The human-readable API token description, useful for users to describe the token's purpose. """ description = StringField('Token description', [validators.optional()])
def client_global_edit(client_id, dev_id): with app.db.session_scope(): dev = app.db.get_device(dev_id) known_items = {} class F(Form): pass for item in dev["parameters"]: item = dev["parameters"][item] default = item["value"] arguments = [Required()] # keep track of the known fields known_items[item["key"]] = {u"id": item["id"], u"type": item["type"]} # build the field if item["type"] == "boolean": if default == 'y' or default == 1 or default == True: # in db value stored in lowcase default = True else: default = False field = BooleanField(item["key"], [validators.optional()], default=default) # set to optional field due to WTForm BooleanField return no data for false value (HTML checkbox) elif item["type"] == "integer": field = IntegerField(item["key"], arguments, default=default) elif item["type"] == "float": field = DateTimeField(item["key"], arguments, default=default) else: # time, email, ipv4, ipv6, url field = TextField(item["key"], arguments, default=default) # add the field setattr(F, "{0}-{1}".format(item["id"], item["key"]), field) form = F() if request.method == 'POST' and form.validate(): for key, item in known_items.iteritems(): val = getattr(form, "{0}-{1}".format(item["id"], key)).data if item["type"] == "boolean": if val == False: val = 'n' # in db value stored in lowcase else: val = 'y' # in db value stored in lowcase app.db.udpate_device_param(item["id"], value=val) return redirect("/client/{0}/dmg_devices/known".format(client_id)) pass else: return render_template('client_global.html', form = form, clientid = client_id, client_detail = get_client_detail(client_id), mactive="clients", active = 'devices', device = dev)
def test_optional(self): self.assertEqual(optional()(self.form, DummyField('foobar', raw_data=['foobar'])), None) self.assertRaises(StopValidation, optional(), self.form, DummyField('', raw_data=[''])) self.assertEqual(optional().field_flags, ('optional', )) f = DummyField('', ['Invalid Integer Value'], raw_data=['']) self.assertEqual(len(f.errors), 1) self.assertRaises(StopValidation, optional(), self.form, f) self.assertEqual(len(f.errors), 0) # Test for whitespace behavior. whitespace_field = DummyField(' ', raw_data=[' ']) self.assertRaises(StopValidation, optional(), self.form, whitespace_field) self.assertEqual(optional(strip_whitespace=False)(self.form, whitespace_field), None)
def test_optional(self): self.assertEqual(optional()(self.form, DummyField("foobar", raw_data=["foobar"])), None) self.assertRaises(StopValidation, optional(), self.form, DummyField("", raw_data=[""])) self.assertEqual(optional().field_flags, ("optional",)) f = DummyField("", ["Invalid Integer Value"], raw_data=[""]) self.assertEqual(len(f.errors), 1) self.assertRaises(StopValidation, optional(), self.form, f) self.assertEqual(len(f.errors), 0) # Test for whitespace behavior. whitespace_field = DummyField(" ", raw_data=[" "]) self.assertRaises(StopValidation, optional(), self.form, whitespace_field) self.assertEqual(optional(strip_whitespace=False)(self.form, whitespace_field), None)
def convert(self, field): kwargs = { 'label': field.verbose_name, 'description': field.help_text, 'validators': [], 'default': field.default, } if field.blank: kwargs['validators'].append(validators.optional()) if field.max_length is not None and field.max_length > 0: kwargs['validators'].append(validators.length(max=field.max_length)) fname = type(field).__name__ if field.choices: kwargs['choices'] = field.choices return f.SelectField(**kwargs) elif fname in self.SIMPLE_CONVERSIONS: return self.SIMPLE_CONVERSIONS[fname](**kwargs) else: m = getattr(self, 'conv_%s' % fname, None) if m is not None: return m(kwargs, field)
def Optional(cls, strip_whitespace=True): ''' Allows empty input and stops the validation chain from continuing. ''' return validators.optional(strip_whitespace)
def __init__(self, viz): self.viz = viz from caravel.viz import viz_types viz = self.viz datasource = viz.datasource if not datasource.metrics_combo: raise Exception("Please define at least one metric for your table") default_metric = datasource.metrics_combo[0][0] gb_cols = datasource.groupby_column_names default_groupby = gb_cols[0] if gb_cols else None group_by_choices = self.choicify(gb_cols) # Pool of all the fields that can be used in Caravel field_data = { 'viz_type': (SelectField, { "label": "Viz", "default": 'table', "choices": [(k, v.verbose_name) for k, v in viz_types.items()], "description": "The type of visualization to display" }), 'metrics': (SelectMultipleSortableField, { "label": "Metrics", "choices": datasource.metrics_combo, "default": [default_metric], "description": "One or many metrics to display" }), 'metric': (SelectField, { "label": "Metric", "choices": datasource.metrics_combo, "default": default_metric, "description": "Choose the metric" }), 'stacked_style': (SelectField, { "label": "Chart Style", "choices": self.choicify(['stack', 'stream', 'expand']), "default": 'stack', "description": "" }), 'linear_color_scheme': (SelectField, { "label": "Color Scheme", "choices": self.choicify([ 'fire', 'blue_white_yellow', 'white_black', 'black_white']), "default": 'blue_white_yellow', "description": "" }), 'normalize_across': (SelectField, { "label": "Normalize Across", "choices": self.choicify([ 'heatmap', 'x', 'y']), "default": 'heatmap', "description": ( "Color will be rendered based on a ratio " "of the cell against the sum of across this " "criteria") }), 'horizon_color_scale': (SelectField, { "label": "Color Scale", "choices": self.choicify(['series', 'overall', 'change']), "default": 'series', "description": "Defines how the color are attributed." }), 'canvas_image_rendering': (SelectField, { "label": "Rendering", "choices": ( ('pixelated', 'pixelated (Sharp)'), ('auto', 'auto (Smooth)'), ), "default": 'pixelated', "description": ( "image-rendering CSS attribute of the canvas object that " "defines how the browser scales up the image") }), 'xscale_interval': (SelectField, { "label": "XScale Interval", "choices": self.choicify(range(1, 50)), "default": '1', "description": ( "Number of step to take between ticks when " "printing the x scale") }), 'yscale_interval': (SelectField, { "label": "YScale Interval", "choices": self.choicify(range(1, 50)), "default": '1', "description": ( "Number of step to take between ticks when " "printing the y scale") }), 'bar_stacked': (BetterBooleanField, { "label": "Stacked Bars", "default": False, "description": "" }), 'include_series': (BetterBooleanField, { "label": "Include Series", "default": False, "description": "Include series name as an axis" }), 'secondary_metric': (SelectField, { "label": "Color Metric", "choices": datasource.metrics_combo, "default": default_metric, "description": "A metric to use for color" }), 'country_fieldtype': (SelectField, { "label": "Country Field Type", "default": 'cca2', "choices": ( ('name', 'Full name'), ('cioc', 'code International Olympic Committee (cioc)'), ('cca2', 'code ISO 3166-1 alpha-2 (cca2)'), ('cca3', 'code ISO 3166-1 alpha-3 (cca3)'), ), "description": ( "The country code standard that Caravel should expect " "to find in the [country] column") }), 'groupby': (SelectMultipleSortableField, { "label": "Group by", "choices": self.choicify(datasource.groupby_column_names), "description": "One or many fields to group by" }), 'columns': (SelectMultipleSortableField, { "label": "Columns", "choices": self.choicify(datasource.groupby_column_names), "description": "One or many fields to pivot as columns" }), 'all_columns': (SelectMultipleSortableField, { "label": "Columns", "choices": self.choicify(datasource.column_names), "description": "Columns to display" }), 'all_columns_x': (SelectField, { "label": "X", "choices": self.choicify(datasource.column_names), "description": "Columns to display" }), 'all_columns_y': (SelectField, { "label": "Y", "choices": self.choicify(datasource.column_names), "description": "Columns to display" }), 'druid_time_origin': (FreeFormSelectField, { "label": "Origin", "choices": ( ('', 'default'), ('now', 'now'), ), "default": '', "description": ( "Defines the origin where time buckets start, " "accepts natural dates as in 'now', 'sunday' or '1970-01-01'") }), 'granularity': (FreeFormSelectField, { "label": "Time Granularity", "default": "one day", "choices": self.choicify([ 'all', '5 seconds', '30 seconds', '1 minute', '5 minutes', '1 hour', '6 hour', '1 day', '7 days', ]), "description": ( "The time granularity for the visualization. Note that you " "can type and use simple natural language as in '10 seconds', " "'1 day' or '56 weeks'") }), 'domain_granularity': (SelectField, { "label": "Domain", "default": "month", "choices": self.choicify([ 'hour', 'day', 'week', 'month', 'year', ]), "description": ( "The time unit used for the grouping of blocks") }), 'subdomain_granularity': (SelectField, { "label": "Subdomain", "default": "day", "choices": self.choicify([ 'min', 'hour', 'day', 'week', 'month', ]), "description": ( "The time unit for each block. Should be a smaller unit than " "domain_granularity. Should be larger or equal to Time Grain") }), 'link_length': (FreeFormSelectField, { "label": "Link Length", "default": "200", "choices": self.choicify([ '10', '25', '50', '75', '100', '150', '200', '250', ]), "description": "Link length in the force layout" }), 'charge': (FreeFormSelectField, { "label": "Charge", "default": "-500", "choices": self.choicify([ '-50', '-75', '-100', '-150', '-200', '-250', '-500', '-1000', '-2500', '-5000', ]), "description": "Charge in the force layout" }), 'granularity_sqla': (SelectField, { "label": "Time Column", "default": datasource.main_dttm_col or datasource.any_dttm_col, "choices": self.choicify(datasource.dttm_cols), "description": ( "The time column for the visualization. Note that you " "can define arbitrary expression that return a DATETIME " "column in the table editor. Also note that the " "filter bellow is applied against this column or " "expression") }), 'resample_rule': (FreeFormSelectField, { "label": "Resample Rule", "default": '', "choices": self.choicify(('1T', '1H', '1D', '7D', '1M', '1AS')), "description": ("Pandas resample rule") }), 'resample_how': (FreeFormSelectField, { "label": "Resample How", "default": '', "choices": self.choicify(('', 'mean', 'sum', 'median')), "description": ("Pandas resample how") }), 'resample_fillmethod': (FreeFormSelectField, { "label": "Resample Fill Method", "default": '', "choices": self.choicify(('', 'ffill', 'bfill')), "description": ("Pandas resample fill method") }), 'since': (FreeFormSelectField, { "label": "Since", "default": "7 days ago", "choices": self.choicify([ '1 hour ago', '12 hours ago', '1 day ago', '7 days ago', '28 days ago', '90 days ago', '1 year ago' ]), "description": ( "Timestamp from filter. This supports free form typing and " "natural language as in '1 day ago', '28 days' or '3 years'") }), 'until': (FreeFormSelectField, { "label": "Until", "default": "now", "choices": self.choicify([ 'now', '1 day ago', '7 days ago', '28 days ago', '90 days ago', '1 year ago']) }), 'max_bubble_size': (FreeFormSelectField, { "label": "Max Bubble Size", "default": "25", "choices": self.choicify([ '5', '10', '15', '25', '50', '75', '100', ]) }), 'whisker_options': (FreeFormSelectField, { "label": "Whisker/outlier options", "default": "Tukey", "description": ( "Determines how whiskers and outliers are calculated."), "choices": self.choicify([ 'Tukey', 'Min/max (no outliers)', '2/98 percentiles', '9/91 percentiles', ]) }), 'treemap_ratio': (DecimalField, { "label": "Ratio", "default": 0.5 * (1 + math.sqrt(5)), # d3 default, golden ratio "description": 'Target aspect ratio for treemap tiles.', }), 'number_format': (FreeFormSelectField, { "label": "Number format", "default": '.3s', "choices": [ ('.3s', '".3s" | 12.3k'), ('.3%', '".3%" | 1234543.210%'), ('.4r', '".4r" | 12350'), ('.3f', '".3f" | 12345.432'), ('+,', '"+," | +12,345.4321'), ('$,.2f', '"$,.2f" | $12,345.43'), ], "description": "D3 format syntax for numbers " "https: //github.com/mbostock/\n" "d3/wiki/Formatting" }), 'row_limit': (FreeFormSelectField, { "label": 'Row limit', "default": config.get("ROW_LIMIT"), "choices": self.choicify( [10, 50, 100, 250, 500, 1000, 5000, 10000, 50000]) }), 'limit': (FreeFormSelectField, { "label": 'Series limit', "choices": self.choicify(self.series_limits), "default": 50, "description": ( "Limits the number of time series that get displayed") }), 'rolling_type': (SelectField, { "label": "Rolling", "default": 'None', "choices": [(s, s) for s in ['None', 'mean', 'sum', 'std', 'cumsum']], "description": ( "Defines a rolling window function to apply, works along " "with the [Periods] text box") }), 'rolling_periods': (IntegerField, { "label": "Periods", "validators": [validators.optional()], "description": ( "Defines the size of the rolling window function, " "relative to the time granularity selected") }), 'series': (SelectField, { "label": "Series", "choices": group_by_choices, "default": default_groupby, "description": ( "Defines the grouping of entities. " "Each serie is shown as a specific color on the chart and " "has a legend toggle") }), 'entity': (SelectField, { "label": "Entity", "choices": group_by_choices, "default": default_groupby, "description": "This define the element to be plotted on the chart" }), 'x': (SelectField, { "label": "X Axis", "choices": datasource.metrics_combo, "default": default_metric, "description": "Metric assigned to the [X] axis" }), 'y': (SelectField, { "label": "Y Axis", "choices": datasource.metrics_combo, "default": default_metric, "description": "Metric assigned to the [Y] axis" }), 'size': (SelectField, { "label": 'Bubble Size', "default": default_metric, "choices": datasource.metrics_combo }), 'url': (TextField, { "label": "URL", "description": ( "The URL, this field is templated, so you can integrate " "{{ width }} and/or {{ height }} in your URL string." ), "default": 'https: //www.youtube.com/embed/JkI5rg_VcQ4', }), 'where': (TextField, { "label": "Custom WHERE clause", "default": '', "description": ( "The text in this box gets included in your query's WHERE " "clause, as an AND to other criteria. You can include " "complex expression, parenthesis and anything else " "supported by the backend it is directed towards.") }), 'having': (TextField, { "label": "Custom HAVING clause", "default": '', "description": ( "The text in this box gets included in your query's HAVING" " clause, as an AND to other criteria. You can include " "complex expression, parenthesis and anything else " "supported by the backend it is directed towards.") }), 'compare_lag': (TextField, { "label": "Comparison Period Lag", "description": ( "Based on granularity, number of time periods to " "compare against") }), 'compare_suffix': (TextField, { "label": "Comparison suffix", "description": "Suffix to apply after the percentage display" }), 'table_timestamp_format': (FreeFormSelectField, { "label": "Table Timestamp Format", "default": 'smart_date', "choices": TIMESTAMP_CHOICES, "description": "Timestamp Format" }), 'series_height': (FreeFormSelectField, { "label": "Series Height", "default": 25, "choices": self.choicify([10, 25, 40, 50, 75, 100, 150, 200]), "description": "Pixel height of each series" }), 'x_axis_format': (FreeFormSelectField, { "label": "X axis format", "default": 'smart_date', "choices": TIMESTAMP_CHOICES, "description": "D3 format syntax for y axis " "https: //github.com/mbostock/\n" "d3/wiki/Formatting" }), 'y_axis_format': (FreeFormSelectField, { "label": "Y axis format", "default": '.3s', "choices": [ ('.3s', '".3s" | 12.3k'), ('.3%', '".3%" | 1234543.210%'), ('.4r', '".4r" | 12350'), ('.3f', '".3f" | 12345.432'), ('+,', '"+," | +12,345.4321'), ('$,.2f', '"$,.2f" | $12,345.43'), ], "description": "D3 format syntax for y axis " "https: //github.com/mbostock/\n" "d3/wiki/Formatting" }), 'markup_type': (SelectField, { "label": "Markup Type", "choices": self.choicify(['markdown', 'html']), "default": "markdown", "description": "Pick your favorite markup language" }), 'rotation': (SelectField, { "label": "Rotation", "choices": [(s, s) for s in ['random', 'flat', 'square']], "default": "random", "description": "Rotation to apply to words in the cloud" }), 'line_interpolation': (SelectField, { "label": "Line Style", "choices": self.choicify([ 'linear', 'basis', 'cardinal', 'monotone', 'step-before', 'step-after']), "default": 'linear', "description": "Line interpolation as defined by d3.js" }), 'code': (TextAreaField, { "label": "Code", "description": "Put your code here", "default": '' }), 'pandas_aggfunc': (SelectField, { "label": "Aggregation function", "choices": self.choicify([ 'sum', 'mean', 'min', 'max', 'median', 'stdev', 'var']), "default": 'sum', "description": ( "Aggregate function to apply when pivoting and " "computing the total rows and columns") }), 'size_from': (TextField, { "label": "Font Size From", "default": "20", "description": "Font size for the smallest value in the list" }), 'size_to': (TextField, { "label": "Font Size To", "default": "150", "description": "Font size for the biggest value in the list" }), 'show_brush': (BetterBooleanField, { "label": "Range Filter", "default": False, "description": ( "Whether to display the time range interactive selector") }), 'show_datatable': (BetterBooleanField, { "label": "Data Table", "default": False, "description": "Whether to display the interactive data table" }), 'include_search': (BetterBooleanField, { "label": "Search Box", "default": False, "description": ( "Whether to include a client side search box") }), 'show_bubbles': (BetterBooleanField, { "label": "Show Bubbles", "default": False, "description": ( "Whether to display bubbles on top of countries") }), 'show_legend': (BetterBooleanField, { "label": "Legend", "default": True, "description": "Whether to display the legend (toggles)" }), 'x_axis_showminmax': (BetterBooleanField, { "label": "X bounds", "default": True, "description": ( "Whether to display the min and max values of the X axis") }), 'rich_tooltip': (BetterBooleanField, { "label": "Rich Tooltip", "default": True, "description": ( "The rich tooltip shows a list of all series for that" " point in time") }), 'y_axis_zero': (BetterBooleanField, { "label": "Y Axis Zero", "default": False, "description": ( "Force the Y axis to start at 0 instead of the minimum " "value") }), 'y_log_scale': (BetterBooleanField, { "label": "Y Log", "default": False, "description": "Use a log scale for the Y axis" }), 'x_log_scale': (BetterBooleanField, { "label": "X Log", "default": False, "description": "Use a log scale for the X axis" }), 'donut': (BetterBooleanField, { "label": "Donut", "default": False, "description": "Do you want a donut or a pie?" }), 'contribution': (BetterBooleanField, { "label": "Contribution", "default": False, "description": "Compute the contribution to the total" }), 'num_period_compare': (IntegerField, { "label": "Period Ratio", "default": None, "validators": [validators.optional()], "description": ( "[integer] Number of period to compare against, " "this is relative to the granularity selected") }), 'time_compare': (TextField, { "label": "Time Shift", "default": "", "description": ( "Overlay a timeseries from a " "relative time period. Expects relative time delta " "in natural language (example: 24 hours, 7 days, " "56 weeks, 365 days") }), 'subheader': (TextField, { "label": "Subheader", "description": ( "Description text that shows up below your Big " "Number") }), } # Override default arguments with form overrides for field_name, override_map in viz.form_overrides.items(): if field_name in field_data: field_data[field_name][1].update(override_map) self.field_dict = { field_name: v[0](**v[1]) for field_name, v in field_data.items() }
def vytvor_formular_pre_manazovanie_studentov(studenti_predmetu): class F(Form): pass count=0 for student_predmetu in studenti_predmetu: #konecna znamka setattr(F, 'select0_%d'%count, SelectField(student_predmetu.student.user.priezvisko, validators=[validators.optional()], choices=[('A', 'A'), ('B', 'B'), ('C', 'C'), ('D', 'D'), ('E', 'E'), ('FX', 'FX'), ('n/a', 'n/a')], default=student_predmetu.konecna_znamka if student_predmetu.konecna_znamka is not None else 'FX')) setattr(F, 'body_za_semester_%d'%count, TextField("", validators=[validators.optional()], default=student_predmetu.body_za_semester if student_predmetu.body_za_semester is not None else 0)) setattr(F, 'select1_%d'%count, SelectField(student_predmetu.student.user.priezvisko, validators=[validators.optional()], choices=[('A', 'A'), ('B', 'B'), ('C', 'C'), ('D', 'D'), ('E', 'E'), ('FX', 'FX'), ('n/a', 'n/a')], default=student_predmetu.znamka1 if student_predmetu.znamka1 is not None else 'FX')) setattr(F, 'poznamka1_%d'%count, TextField("", validators=[validators.optional()],default=student_predmetu.poznamka1)) setattr(F, 'datum1_%d'%count, TextField("", validators=[validators.optional()], default=student_predmetu.datum1.strftime("%x") if student_predmetu.datum1 else "")) setattr(F, 'select2_%d'%count, SelectField(student_predmetu.student.user.priezvisko, validators=[validators.optional()], choices=[('A', 'A'), ('B', 'B'), ('C', 'C'), ('D', 'D'), ('E', 'E'), ('FX', 'FX'), ('n/a', 'n/a')], default=student_predmetu.znamka2 if student_predmetu.znamka2 is not None else 'FX')) setattr(F, 'poznamka2_%d'%count, TextField("", validators=[validators.optional()],default=student_predmetu.poznamka2)) setattr(F, 'datum2_%d'%count, TextField("", validators=[validators.optional()], default=student_predmetu.datum2.strftime("%x") if student_predmetu.datum2 else "")) setattr(F, 'select3_%d'%count, SelectField(student_predmetu.student.user.priezvisko, validators=[validators.optional()], choices=[('A', 'A'), ('B', 'B'), ('C', 'C'), ('D', 'D'), ('E', 'E'), ('FX', 'FX'), ('n/a', 'n/a')], default=student_predmetu.znamka3 if student_predmetu.znamka3 is not None else 'FX')) setattr(F, 'poznamka3_%d'%count, TextField("", validators=[validators.optional()],default=student_predmetu.poznamka3)) setattr(F, 'datum3_%d'%count, TextField("", validators=[validators.optional()], default=student_predmetu.datum3.strftime("%x") if student_predmetu.datum3 else "")) count +=1 return F()
from flask_wtf import Form from wtforms.ext.appengine.ndb import model_form from wtforms.fields import StringField, HiddenField, PasswordField from wtforms import validators from family.models.member import Profile from family.models.message import Message BaseProfileForm = model_form(Profile, Form, field_args={ 'birth_date': {'validators': [validators.optional()]}} # disable DateField validator ) class MemberProfileForm(BaseProfileForm): member_id = HiddenField() first_name = StringField('First Name', [validators.input_required()]) last_name = StringField('Last Name', [validators.input_required()]) class ChangePasswordForm(Form): old_password = PasswordField('Old Password', [validators.input_required()]) new_password = PasswordField('New Password', [ validators.input_required(), validators.equal_to('confirm_password', message='Passwords must match') ]) confirm_password = PasswordField('Re-type New Password', [ validators.input_required(), validators.equal_to('new_password', message='Passwords must match') ])
def append_field_to_form(self, field, form): if field.fieldtype.type == 'Text': setattr(form, field.label, TextField(field.description, validators=[ validators.Required( message=u'Champ obligatoire' )] if field.mandatory else None )) elif field.fieldtype.type in self.app.config['DATE_FIELDTYPEZ']: setattr(form, field.label, DateTimeField(field.description, format=self.app.config['DATE_FORMAT'], validators=[ validators.Required( message=u'Champ obligatoire' )] if field.mandatory else [validators.optional()])) elif field.fieldtype.type == 'GIDNumber': setattr(form, field.label, SelectField(field.description, choices=self.get_posix_groupz_choices(), validators=[ validators.Required( message=u'Champ obligatoire' )] if field.mandatory else None)) elif field.fieldtype.type == 'CINESUser': setattr(form, field.label, SelectField(field.description, choices=self.get_posix_userz_choices('cines'), validators=[ validators.Required( message=u'Champ obligatoire' )] if field.mandatory else None)) elif field.fieldtype.type == 'Submission': setattr(form, field.label, FormField(EditSubmissionForm, validators=[ validators.Required( message=u'Champ obligatoire' )] if field.mandatory else None)) elif field.fieldtype.type == 'Shell': setattr(form, field.label, SelectField(field.description, choices=self.get_shellz_choices(), validators=[ validators.Required( message=u'Champ obligatoire' )] if field.mandatory else None)) elif field.fieldtype.type == 'Filesystem': setattr(form, field.label, SelectField(field.description, choices=self.get_filesystem_choices(), validators=[ validators.Required( message=u'Champ obligatoire' )] if field.mandatory else None)) elif field.fieldtype.type == 'Checkbox': setattr(form, field.label, BooleanField(field.description)) elif field.fieldtype.type == 'TextArea': setattr(form, field.label, TextAreaField(field.description, validators=[ validators.Required( message=u'Champ obligatoire' )] if field.mandatory else None)) elif field.fieldtype.type == 'Oui/Non': setattr(form, field.label, SelectField(field.description, choices=[('1', 'Oui'), ('-1', 'Non')]))
def client_global_edit(client_id, dev_id): with app.db.session_scope(): dev = app.db.get_device(dev_id) known_items = {} class F(Form): pass for item in dev["parameters"]: item = dev["parameters"][item] default = item["value"] arguments = [InputRequired()] # keep track of the known fields known_items[item["key"]] = {u"id": item["id"], u"type": item["type"]} # build the field if item["type"] == "boolean": if default == 'y' or default == 1 or default == True: # in db value stored in lowcase #default = True default = 'y' else: #default = False default = 'n' #field = BooleanField(item["key"], [validators.optional()], default=default) # set to optional field due to WTForm BooleanField return no data for false value (HTML checkbox) field = RadioField( item["key"], [validators.optional()], choices=[('y', 'Yes'), ('n', 'No')], default=default ) elif item["type"] == "integer": field = IntegerField(item["key"], arguments, default=default) elif item["type"] == "datetime": field = DateTimeField(item["key"], arguments, default=default) elif item["type"] == "float": field = FloatField(item["key"], arguments, default=default) else: # time, email, ipv4, ipv6, url field = TextField(item["key"], arguments, default=default) # add the field setattr(F, "{0}-{1}".format(item["id"], item["key"]), field) form = F() if request.method == 'POST' and form.validate(): for key, item in known_items.items(): val = getattr(form, "{0}-{1}".format(item["id"], key)).data if item["type"] == "boolean": if val == 'n': val = 'n' # in db value stored in lowcase else: val = 'y' # in db value stored in lowcase cli = MQSyncReq(app.zmq_context) msg = MQMessage() msg.set_action('deviceparam.update') msg.add_data('dpid', item["id"]) msg.add_data('value', val) res = cli.request('dbmgr', msg.get(), timeout=10) if res is not None: data = res.get_data() if data["status"]: flash(gettext("Param update succesfully"), 'success') else: flash(gettext("Param update failed"), 'warning') flash(data["reason"], 'danger') else: flash(gettext("DbMgr did not respond on the deviceparam.update, check the logs"), 'danger') return redirect("/client/{0}/dmg_devices/known".format(client_id)) pass else: return render_template('client_global.html', form = form, clientid = client_id, client_detail = get_client_detail(client_id), mactive="clients", active = 'devices', device = dev)
def __init__(self, viz): self.viz = viz from caravel.viz import viz_types viz = self.viz datasource = viz.datasource if not datasource.metrics_combo: raise Exception("Please define at least one metric for your table") default_metric = datasource.metrics_combo[0][0] gb_cols = datasource.groupby_column_names default_groupby = gb_cols[0] if gb_cols else None group_by_choices = self.choicify(gb_cols) order_by_choices = [] for s in sorted(datasource.num_cols): order_by_choices.append((json.dumps([s, True]), s + ' [asc]')) order_by_choices.append((json.dumps([s, False]), s + ' [desc]')) # Pool of all the fields that can be used in Caravel field_data = { 'viz_type': (SelectField, { "label": _("Viz"), "default": 'table', "choices": [(k, v.verbose_name) for k, v in viz_types.items()], "description": _("The type of visualization to display") }), 'metrics': (SelectMultipleSortableField, { "label": _("Metrics"), "choices": datasource.metrics_combo, "default": [default_metric], "description": _("One or many metrics to display") }), 'order_by_cols': (SelectMultipleSortableField, { "label": _("Ordering"), "choices": order_by_choices, "description": _("One or many metrics to display") }), 'metric': (SelectField, { "label": _("Metric"), "choices": datasource.metrics_combo, "default": default_metric, "description": _("Choose the metric") }), 'stacked_style': (SelectField, { "label": _("Chart Style"), "choices": ( ('stack', _('stack')), ('stream', _('stream')), ('expand', _('expand')), ), "default": 'stack', "description": "" }), 'linear_color_scheme': (SelectField, { "label": _("Color Scheme"), "choices": ( ('fire', _('fire')), ('blue_white_yellow', _('blue_white_yellow')), ('white_black', _('white_black')), ('black_white', _('black_white')), ), "default": 'blue_white_yellow', "description": "" }), 'normalize_across': (SelectField, { "label": _("Normalize Across"), "choices": ( ('heatmap', _('heatmap')), ('x', _('x')), ('y', _('y')), ), "default": 'heatmap', "description": _( "Color will be rendered based on a ratio " "of the cell against the sum of across this " "criteria") }), 'horizon_color_scale': (SelectField, { "label": _("Color Scale"), "choices": ( ('series', _('series')), ('overall', _('overall')), ('change', _('change')), ), "default": 'series', "description": _("Defines how the color are attributed.") }), 'canvas_image_rendering': (SelectField, { "label": _("Rendering"), "choices": ( ('pixelated', _('pixelated (Sharp)')), ('auto', _('auto (Smooth)')), ), "default": 'pixelated', "description": _( "image-rendering CSS attribute of the canvas object that " "defines how the browser scales up the image") }), 'xscale_interval': (SelectField, { "label": _("XScale Interval"), "choices": self.choicify(range(1, 50)), "default": '1', "description": _( "Number of step to take between ticks when " "printing the x scale") }), 'yscale_interval': (SelectField, { "label": _("YScale Interval"), "choices": self.choicify(range(1, 50)), "default": '1', "description": _( "Number of step to take between ticks when " "printing the y scale") }), 'bar_stacked': (BetterBooleanField, { "label": _("Stacked Bars"), "default": False, "description": "" }), 'show_controls': (BetterBooleanField, { "label": _("Extra Controls"), "default": False, "description": ( "Whether to show extra controls or not. Extra controls " "include things like making mulitBar charts stacked " "or side by side.") }), 'reduce_x_ticks': (BetterBooleanField, { "label": _("Reduce X ticks"), "default": False, "description": _( "Reduces the number of X axis ticks to be rendered. " "If true, the x axis wont overflow and labels may be " "missing. If false, a minimum width will be applied " "to columns and the width may overflow into an " "horizontal scroll."), }), 'include_series': (BetterBooleanField, { "label": _("Include Series"), "default": False, "description": _("Include series name as an axis") }), 'secondary_metric': (SelectField, { "label": _("Color Metric"), "choices": datasource.metrics_combo, "default": default_metric, "description": _("A metric to use for color") }), 'country_fieldtype': (SelectField, { "label": _("Country Field Type"), "default": 'cca2', "choices": ( ('name', _('Full name')), ('cioc', _('code International Olympic Committee (cioc)')), ('cca2', _('code ISO 3166-1 alpha-2 (cca2)')), ('cca3', _('code ISO 3166-1 alpha-3 (cca3)')), ), "description": _( "The country code standard that Caravel should expect " "to find in the [country] column") }), 'groupby': (SelectMultipleSortableField, { "label": _("Group by"), "choices": self.choicify(datasource.groupby_column_names), "description": _("One or many fields to group by") }), 'columns': (SelectMultipleSortableField, { "label": _("Columns"), "choices": self.choicify(datasource.groupby_column_names), "description": _("One or many fields to pivot as columns") }), 'all_columns': (SelectMultipleSortableField, { "label": _("Columns"), "choices": self.choicify(datasource.column_names), "description": _("Columns to display") }), 'all_columns_x': (SelectField, { "label": _("X"), "choices": self.choicify(datasource.column_names), "description": _("Columns to display") }), 'all_columns_y': (SelectField, { "label": _("Y"), "choices": self.choicify(datasource.column_names), "description": _("Columns to display") }), 'druid_time_origin': (FreeFormSelectField, { "label": _( "Origin"), "choices": ( ('', _('default')), ('now', _('now')), ), "default": '', "description": _( "Defines the origin where time buckets start, " "accepts natural dates as in 'now', 'sunday' or '1970-01-01'") }), 'bottom_margin': (FreeFormSelectField, { "label": _("Bottom Margin"), "choices": self.choicify([50, 75, 100, 125, 150, 200]), "default": 50, "description": _( "Bottom marging, in pixels, allowing for more room for " "axis labels"), }), 'granularity': (FreeFormSelectField, { "label": _("Time Granularity"), "default": "one day", "choices": ( ('all', _('all')), ('5 seconds', _('5 seconds')), ('30 seconds', _('30 seconds')), ('1 minute', _('1 minute')), ('5 minutes', _('5 minutes')), ('1 hour', _('1 hour')), ('6 hour', _('6 hour')), ('1 day', _('1 day')), ('7 days', _('7 days')), ), "description": _( "The time granularity for the visualization. Note that you " "can type and use simple natural language as in '10 seconds', " "'1 day' or '56 weeks'") }), 'domain_granularity': (SelectField, { "label": _("Domain"), "default": "month", "choices": ( ('hour', _('hour')), ('day', _('day')), ('week', _('week')), ('month', _('month')), ('year', _('year')), ), "description": _( "The time unit used for the grouping of blocks") }), 'subdomain_granularity': (SelectField, { "label": _("Subdomain"), "default": "day", "choices": ( ('min', _('min')), ('hour', _('hour')), ('day', _('day')), ('week', _('week')), ('month', _('month')), ), "description": _( "The time unit for each block. Should be a smaller unit than " "domain_granularity. Should be larger or equal to Time Grain") }), 'link_length': (FreeFormSelectField, { "label": _("Link Length"), "default": "200", "choices": self.choicify([ '10', '25', '50', '75', '100', '150', '200', '250', ]), "description": _("Link length in the force layout") }), 'charge': (FreeFormSelectField, { "label": _("Charge"), "default": "-500", "choices": self.choicify([ '-50', '-75', '-100', '-150', '-200', '-250', '-500', '-1000', '-2500', '-5000', ]), "description": _("Charge in the force layout") }), 'granularity_sqla': (SelectField, { "label": _("Time Column"), "default": datasource.main_dttm_col or datasource.any_dttm_col, "choices": self.choicify(datasource.dttm_cols), "description": _( "The time column for the visualization. Note that you " "can define arbitrary expression that return a DATETIME " "column in the table editor. Also note that the " "filter bellow is applied against this column or " "expression") }), 'resample_rule': (FreeFormSelectField, { "label": _("Resample Rule"), "default": '', "choices": ( ('1T', _('1T')), ('1H', _('1H')), ('1D', _('1D')), ('7D', _('7D')), ('1M', _('1M')), ('1AS', _('1AS')), ), "description": _("Pandas resample rule") }), 'resample_how': (FreeFormSelectField, { "label": _("Resample How"), "default": '', "choices": ( ('', ''), ('mean', _('mean')), ('sum', _('sum')), ('median', _('median')), ), "description": _("Pandas resample how") }), 'resample_fillmethod': (FreeFormSelectField, { "label": _("Resample Fill Method"), "default": '', "choices": ( ('', ''), ('ffill', _('ffill')), ('bfill', _('bfill')), ), "description": _("Pandas resample fill method") }), 'since': (FreeFormSelectField, { "label": _("Since"), "default": "7 days ago", "choices": ( ('1 hour ago', _('1 hour ago')), ('12 hours ago', _('12 hours ago')), ('1 day ago', _('1 day ago')), ('7 days ago', _('7 days ago')), ('28 days ago', _('28 days ago')), ('90 days ago', _('90 days ago')), ('1 year ago', _('1 year ago')), ), "description": _( "Timestamp from filter. This supports free form typing and " "natural language as in '1 day ago', '28 days' or '3 years'") }), 'until': (FreeFormSelectField, { "label": _("Until"), "default": "now", "choices": ( ('now', _('now')), ('1 day ago', _('1 day ago')), ('7 days ago', _('7 days ago')), ('28 days ago', _('28 days ago')), ('90 days ago', _('90 days ago')), ('1 year ago', _('1 year ago')), ) }), 'max_bubble_size': (FreeFormSelectField, { "label": _("Max Bubble Size"), "default": "25", "choices": self.choicify([ '5', '10', '15', '25', '50', '75', '100', ]) }), 'whisker_options': (FreeFormSelectField, { "label": _("Whisker/outlier options"), "default": "Tukey", "description": _( "Determines how whiskers and outliers are calculated."), "choices": ( ('Tukey', _('Tukey')), ('Min/max (no outliers)', _('Min/max (no outliers)')), ('2/98 percentiles', _('2/98 percentiles')), ('9/91 percentiles', _('9/91 percentiles')), ) }), 'treemap_ratio': (DecimalField, { "label": _("Ratio"), "default": 0.5 * (1 + math.sqrt(5)), # d3 default, golden ratio "description": _('Target aspect ratio for treemap tiles.'), }), 'number_format': (FreeFormSelectField, { "label": _("Number format"), "default": '.3s', "choices": [ ('.3s', '".3s" | 12.3k'), ('.3%', '".3%" | 1234543.210%'), ('.4r', '".4r" | 12350'), ('.3f', '".3f" | 12345.432'), ('+,', '"+," | +12,345.4321'), ('$,.2f', '"$,.2f" | $12,345.43'), ], "description": _("D3 format syntax for numbers " "https: //github.com/mbostock/\n" "d3/wiki/Formatting") }), 'row_limit': (FreeFormSelectField, { "label": _('Row limit'), "default": config.get("ROW_LIMIT"), "choices": self.choicify( [10, 50, 100, 250, 500, 1000, 5000, 10000, 50000]) }), 'limit': (FreeFormSelectField, { "label": _('Series limit'), "choices": self.choicify(self.series_limits), "default": 50, "description": _( "Limits the number of time series that get displayed") }), 'rolling_type': (SelectField, { "label": _("Rolling"), "default": 'None', "choices": [(s, s) for s in ['None', 'mean', 'sum', 'std', 'cumsum']], "description": _( "Defines a rolling window function to apply, works along " "with the [Periods] text box") }), 'rolling_periods': (IntegerField, { "label": _("Periods"), "validators": [validators.optional()], "description": _( "Defines the size of the rolling window function, " "relative to the time granularity selected") }), 'series': (SelectField, { "label": _("Series"), "choices": group_by_choices, "default": default_groupby, "description": _( "Defines the grouping of entities. " "Each serie is shown as a specific color on the chart and " "has a legend toggle") }), 'entity': (SelectField, { "label": _("Entity"), "choices": group_by_choices, "default": default_groupby, "description": _("This define the element to be plotted on the chart") }), 'x': (SelectField, { "label": _("X Axis"), "choices": datasource.metrics_combo, "default": default_metric, "description": _("Metric assigned to the [X] axis") }), 'y': (SelectField, { "label": _("Y Axis"), "choices": datasource.metrics_combo, "default": default_metric, "description": _("Metric assigned to the [Y] axis") }), 'size': (SelectField, { "label": _('Bubble Size'), "default": default_metric, "choices": datasource.metrics_combo }), 'url': (TextField, { "label": _("URL"), "description": _( "The URL, this field is templated, so you can integrate " "{{ width }} and/or {{ height }} in your URL string." ), "default": 'https: //www.youtube.com/embed/JkI5rg_VcQ4', }), 'x_axis_label': (TextField, { "label": _("X Axis Label"), "default": '', }), 'y_axis_label': (TextField, { "label": _("Y Axis Label"), "default": '', }), 'where': (TextField, { "label": _("Custom WHERE clause"), "default": '', "description": _( "The text in this box gets included in your query's WHERE " "clause, as an AND to other criteria. You can include " "complex expression, parenthesis and anything else " "supported by the backend it is directed towards.") }), 'having': (TextField, { "label": _("Custom HAVING clause"), "default": '', "description": _( "The text in this box gets included in your query's HAVING" " clause, as an AND to other criteria. You can include " "complex expression, parenthesis and anything else " "supported by the backend it is directed towards.") }), 'compare_lag': (TextField, { "label": _("Comparison Period Lag"), "description": _( "Based on granularity, number of time periods to " "compare against") }), 'compare_suffix': (TextField, { "label": _("Comparison suffix"), "description": _("Suffix to apply after the percentage display") }), 'table_timestamp_format': (FreeFormSelectField, { "label": _("Table Timestamp Format"), "default": 'smart_date', "choices": TIMESTAMP_CHOICES, "description": _("Timestamp Format") }), 'series_height': (FreeFormSelectField, { "label": _("Series Height"), "default": 25, "choices": self.choicify([10, 25, 40, 50, 75, 100, 150, 200]), "description": _("Pixel height of each series") }), 'x_axis_format': (FreeFormSelectField, { "label": _("X axis format"), "default": 'smart_date', "choices": TIMESTAMP_CHOICES, "description": _("D3 format syntax for y axis " "https: //github.com/mbostock/\n" "d3/wiki/Formatting") }), 'y_axis_format': (FreeFormSelectField, { "label": _("Y axis format"), "default": '.3s', "choices": [ ('.3s', '".3s" | 12.3k'), ('.3%', '".3%" | 1234543.210%'), ('.4r', '".4r" | 12350'), ('.3f', '".3f" | 12345.432'), ('+,', '"+," | +12,345.4321'), ('$,.2f', '"$,.2f" | $12,345.43'), ], "description": _("D3 format syntax for y axis " "https: //github.com/mbostock/\n" "d3/wiki/Formatting") }), 'markup_type': (SelectField, { "label": _("Markup Type"), "choices": ( ('markdown', _('markdown')), ('html', _('html')) ), "default": "markdown", "description": _("Pick your favorite markup language") }), 'rotation': (SelectField, { "label": _("Rotation"), "choices": ( ('random', _('random')), ('flat', _('flat')), ('square', _('square')), ), "default": "random", "description": _("Rotation to apply to words in the cloud") }), 'line_interpolation': (SelectField, { "label": _("Line Style"), "choices": ( ('linear', _('linear')), ('basis', _('basis')), ('cardinal', _('cardinal')), ('monotone', _('monotone')), ('step-before', _('step-before')), ('step-after', _('step-after')), ), "default": 'linear', "description": _("Line interpolation as defined by d3.js") }), 'code': (TextAreaField, { "label": _("Code"), "description": _("Put your code here"), "default": '' }), 'pandas_aggfunc': (SelectField, { "label": _("Aggregation function"), "choices": ( ('sum', _('sum')), ('mean', _('mean')), ('min', _('min')), ('max', _('max')), ('median', _('median')), ('stdev', _('stdev')), ('var', _('var')), ), "default": 'sum', "description": _( "Aggregate function to apply when pivoting and " "computing the total rows and columns") }), 'size_from': (TextField, { "label": _("Font Size From"), "default": "20", "description": _("Font size for the smallest value in the list") }), 'size_to': (TextField, { "label": _("Font Size To"), "default": "150", "description": _("Font size for the biggest value in the list") }), 'show_brush': (BetterBooleanField, { "label": _("Range Filter"), "default": False, "description": _( "Whether to display the time range interactive selector") }), 'show_datatable': (BetterBooleanField, { "label": _("Data Table"), "default": False, "description": _("Whether to display the interactive data table") }), 'include_search': (BetterBooleanField, { "label": _("Search Box"), "default": False, "description": _( "Whether to include a client side search box") }), 'show_bubbles': (BetterBooleanField, { "label": _("Show Bubbles"), "default": False, "description": _( "Whether to display bubbles on top of countries") }), 'show_legend': (BetterBooleanField, { "label": _("Legend"), "default": True, "description": _("Whether to display the legend (toggles)") }), 'x_axis_showminmax': (BetterBooleanField, { "label": _("X bounds"), "default": True, "description": _( "Whether to display the min and max values of the X axis") }), 'rich_tooltip': (BetterBooleanField, { "label": _("Rich Tooltip"), "default": True, "description": _( "The rich tooltip shows a list of all series for that" " point in time") }), 'y_axis_zero': (BetterBooleanField, { "label": _("Y Axis Zero"), "default": False, "description": _( "Force the Y axis to start at 0 instead of the minimum " "value") }), 'y_log_scale': (BetterBooleanField, { "label": _("Y Log"), "default": False, "description": _("Use a log scale for the Y axis") }), 'x_log_scale': (BetterBooleanField, { "label": _("X Log"), "default": False, "description": _("Use a log scale for the X axis") }), 'donut': (BetterBooleanField, { "label": _("Donut"), "default": False, "description": _("Do you want a donut or a pie?") }), 'contribution': (BetterBooleanField, { "label": _("Contribution"), "default": False, "description": _("Compute the contribution to the total") }), 'num_period_compare': (IntegerField, { "label": _("Period Ratio"), "default": None, "validators": [validators.optional()], "description": _( "[integer] Number of period to compare against, " "this is relative to the granularity selected") }), 'time_compare': (TextField, { "label": _("Time Shift"), "default": "", "description": _( "Overlay a timeseries from a " "relative time period. Expects relative time delta " "in natural language (example: 24 hours, 7 days, " "56 weeks, 365 days") }), 'subheader': (TextField, { "label": _("Subheader"), "description": _( "Description text that shows up below your Big " "Number") }), 'mapbox_label': (SelectMultipleSortableField, { "label": "Label", "choices": self.choicify(["count"] + datasource.column_names), "description": _( "'count' is COUNT(*) if a group by is used. " "Numerical columns will be aggregated with the aggregator. " "Non-numerical columns will be used to label points. " "Leave empty to get a count of points in each cluster."), }), 'mapbox_style': (SelectField, { "label": "Map Style", "choices": [ ("mapbox://styles/mapbox/streets-v9", "Streets"), ("mapbox://styles/mapbox/dark-v9", "Dark"), ("mapbox://styles/mapbox/light-v9", "Light"), ("mapbox://styles/mapbox/satellite-streets-v9", "Satellite Streets"), ("mapbox://styles/mapbox/satellite-v9", "Satellite"), ("mapbox://styles/mapbox/outdoors-v9", "Outdoors"), ], "description": _("Base layer map style") }), 'clustering_radius': (FreeFormSelectField, { "label": _("Clustering Radius"), "default": "60", "choices": self.choicify([ '0', '20', '40', '60', '80', '100', '200', '500', '1000', ]), "description": _( "The radius (in pixels) the algorithm uses to define a cluster. " "Choose 0 to turn off clustering, but beware that a large " "number of points (>1000) will cause lag.") }), 'point_radius': (SelectField, { "label": _("Point Radius"), "default": "Auto", "choices": self.choicify(["Auto"] + datasource.column_names), "description": _( "The radius of individual points (ones that are not in a cluster). " "Either a numerical column or 'Auto', which scales the point based " "on the largest cluster") }), 'point_radius_unit': (SelectField, { "label": _("Point Radius Unit"), "default": "Pixels", "choices": self.choicify([ "Pixels", "Miles", "Kilometers", ]), "description": _("The unit of measure for the specified point radius") }), 'global_opacity': (DecimalField, { "label": _("Opacity"), "default": 1, "description": _( "Opacity of all clusters, points, and labels. " "Between 0 and 1."), }), 'viewport_zoom': (DecimalField, { "label": _("Zoom"), "default": 11, "validators": [validators.optional()], "description": _("Zoom level of the map"), "places": 8, }), 'viewport_latitude': (DecimalField, { "label": _("Default latitude"), "default": 37.772123, "description": _("Latitude of default viewport"), "places": 8, }), 'viewport_longitude': (DecimalField, { "label": _("Default longitude"), "default": -122.405293, "description": _("Longitude of default viewport"), "places": 8, }), 'render_while_dragging': (BetterBooleanField, { "label": _("Live render"), "default": True, "description": _("Points and clusters will update as viewport " "is being changed") }), 'mapbox_color': (FreeFormSelectField, { "label": _("RGB Color"), "default": "rgb(0, 122, 135)", "choices": [ ("rgb(0, 139, 139)", "Dark Cyan"), ("rgb(128, 0, 128)", "Purple"), ("rgb(255, 215, 0)", "Gold"), ("rgb(69, 69, 69)", "Dim Gray"), ("rgb(220, 20, 60)", "Crimson"), ("rgb(34, 139, 34)", "Forest Green"), ], "description": _("The color for points and clusters in RGB") }), } # Override default arguments with form overrides for field_name, override_map in viz.form_overrides.items(): if field_name in field_data: field_data[field_name][1].update(override_map) self.field_dict = { field_name: v[0](**v[1]) for field_name, v in field_data.items() }
def generate_submission_edit_form_class(form): form_fields = {} STATUS_CHOICES = ( ('', _('Unmarked')), ('confirmed', _('Confirmed')), ('rejected', _('Rejected')), ('citizen', _('Citizen Report')), ) WITNESS_CHOICES = ( ('', _('Unspecified')), ('witnessed', _('I witnessed the incident')), ('after', _('I arrived just after the incident')), ('reported', _('The incident was reported to me by someone else')), ) form_fields['contributor'] = CustomModelSelectField( _('Participant'), allow_blank=True, blank_text=_('Participant'), widget=widgets.HiddenInput(), validators=[validators.optional()], model=Participant, queryset=participants.find() ) form_fields['location'] = CustomModelSelectField( _('Location'), allow_blank=True, blank_text=_('Location'), widget=widgets.HiddenInput(), model=Location, queryset=locations.find() ) for index, group in enumerate(form.groups): for field in group.fields: if field.options: choices = [(v, k) for k, v in field.options.iteritems()] if field.allows_multiple_values: form_fields[field.name] = SelectMultipleField( field.name, choices=choices, coerce=int, description=field.description, validators=[validators.optional()], option_widget=widgets.CheckboxInput(), widget=widgets.ListWidget() ) else: form_fields[field.name] = IntegerField( field.name, description=field.description, validators=[ validators.optional(), validators.AnyOf([v for v, k in choices])], widget=widgets.TextInput() ) else: if form.form_type == 'CHECKLIST': form_fields[field.name] = IntegerField( field.name, description=field.description, validators=[ validators.optional(), validators.NumberRange(min=field.min_value, max=field.max_value)] ) else: form_fields[field.name] = BooleanField( field.name, description=field.description, filters=[lambda data: 1 if data else None], validators=[validators.optional()] ) if form.form_type == 'INCIDENT': form_fields['status'] = SelectField( choices=STATUS_CHOICES, filters=[lambda data: data if data else None], validators=[validators.optional()] ) form_fields['witness'] = SelectField( choices=WITNESS_CHOICES, validators=[validators.optional()] ) form_fields['description'] = StringField( widget=widgets.TextArea() ) return type( 'SubmissionEditForm', (WTSecureForm,), form_fields )
def generate_submission_edit_form_class(form): form_fields = {} STATUS_CHOICES = ( ('', _('Unmarked')), ('confirmed', _('Confirmed')), ('rejected', _('Rejected')), ('citizen', _('Citizen Report')), ) form_fields['contributor'] = CustomModelSelectField( _('Participant'), allow_blank=True, blank_text=_('Participant'), widget=widgets.HiddenInput(), validators=[validators.optional()], model=Participant, queryset=participants.find() ) form_fields['location'] = CustomModelSelectField( _('Location'), allow_blank=True, blank_text=_('Location'), widget=widgets.HiddenInput(), model=Location, queryset=locations.find() ) for index, group in enumerate(form.groups): for field in group.fields: if field.is_comment_field: form_fields[field.name] = TextField( field.name, description=field.description, widget=widgets.TextArea()) elif field.options: choices = [(v, k) for k, v in field.options.iteritems()] if field.allows_multiple_values: form_fields[field.name] = SelectMultipleField( field.name, choices=choices, coerce=int, description=field.description, filters=[lambda data: data if data else None], validators=[validators.optional()], option_widget=widgets.CheckboxInput(), widget=widgets.ListWidget() ) else: form_fields[field.name] = IntegerField( field.name, description=field.description, validators=[ validators.optional(), validators.AnyOf([v for v, k in choices])], widget=widgets.TextInput() ) else: if form.form_type == 'CHECKLIST': form_fields[field.name] = IntegerField( field.name, description=field.description, validators=[ validators.optional(), validators.NumberRange(min=field.min_value, max=field.max_value)] ) else: form_fields[field.name] = BooleanField( field.name, description=field.description, filters=[lambda data: 1 if data else None], validators=[validators.optional()] ) if ( form.form_type == 'CHECKLIST' and permissions.edit_submission_quarantine_status.can() ): form_fields['quarantine_status'] = SelectField( choices=Submission.QUARANTINE_STATUSES, filters=[lambda data: data if data else ''], validators=[validators.optional()] ) if ( form.form_type == 'CHECKLIST' and permissions.edit_submission_verification_status.can() ): form_fields['verification_status'] = SelectField( choices=Submission.VERIFICATION_STATUSES, filters=[lambda data: data if data else ''], validators=[validators.optional()] ) if form.form_type == 'INCIDENT': form_fields['status'] = SelectField( choices=STATUS_CHOICES, filters=[lambda data: data if data else None], validators=[validators.optional()] ) form_fields['description'] = StringField( widget=widgets.TextArea() ) form_fields['validate'] = validate_location return type( 'SubmissionEditForm', (WTSecureForm,), form_fields )
def __init__(self, viz): self.viz = viz from dashed.viz import viz_types viz = self.viz datasource = viz.datasource default_metric = datasource.metrics_combo[0][0] default_groupby = datasource.groupby_column_names[0] group_by_choices = [(s, s) for s in datasource.groupby_column_names] # Pool of all the fields that can be used in Dashed self.field_dict = { 'viz_type': SelectField( 'Viz', default='table', choices=[(k, v.verbose_name) for k, v in viz_types.items()], description="The type of visualization to display"), 'metrics': SelectMultipleSortableField( 'Metrics', choices=datasource.metrics_combo, default=[default_metric], description="One or many metrics to display"), 'metric': SelectField( 'Metric', choices=datasource.metrics_combo, default=default_metric, description="Chose the metric"), 'stacked_style': SelectField( 'Chart Style', choices=self.choicify( ['stack', 'stream', 'expand']), default='stack', description=""), 'linear_color_scheme': SelectField( 'Color Scheme', choices=self.choicify([ 'fire', 'blue_white_yellow', 'white_black', 'black_white']), default='fire', description=""), 'normalize_across': SelectField( 'Normalize Across', choices=self.choicify([ 'heatmap', 'x', 'y']), default='heatmap', description=( "Color will be rendered based on a ratio " "of the cell against the sum of across this " "criteria")), 'canvas_image_rendering': SelectField( 'Rendering', choices=( ('pixelated', 'pixelated (Sharp)'), ('auto', 'auto (Smooth)'), ), default='pixelated', description=( "image-rendering CSS attribute of the canvas object that " "defines how the browser scales up the image")), 'xscale_interval': SelectField( 'XScale Interval', choices=self.choicify(range(1, 50)), default='1', description=( "Number of step to take between ticks when " "printing the x scale")), 'yscale_interval': SelectField( 'YScale Interval', choices=self.choicify(range(1, 50)), default='1', description=( "Number of step to take between ticks when " "printing the y scale")), 'bar_stacked': BetterBooleanField( 'Stacked Bars', default=False, description=""), 'secondary_metric': SelectField( 'Color Metric', choices=datasource.metrics_combo, default=default_metric, description="A metric to use for color"), 'country_fieldtype': SelectField( 'Country Field Type', default='cca2', choices=( ('name', 'Full name'), ('cioc', 'code International Olympic Committee (cioc)'), ('cca2', 'code ISO 3166-1 alpha-2 (cca2)'), ('cca3', 'code ISO 3166-1 alpha-3 (cca3)'), ), description=( "The country code standard that Dashed should expect " "to find in the [country] column")), 'groupby': SelectMultipleSortableField( 'Group by', choices=self.choicify(datasource.groupby_column_names), description="One or many fields to group by"), 'columns': SelectMultipleSortableField( 'Columns', choices=self.choicify(datasource.groupby_column_names), description="One or many fields to pivot as columns"), 'all_columns': SelectMultipleSortableField( 'Columns', choices=self.choicify(datasource.column_names), description="Columns to display"), 'all_columns_x': SelectField( 'X', choices=self.choicify(datasource.column_names), description="Columns to display"), 'all_columns_y': SelectField( 'Y', choices=self.choicify(datasource.column_names), description="Columns to display"), 'granularity': FreeFormSelectField( 'Time Granularity', default="one day", choices=self.choicify([ 'all', '5 seconds', '30 seconds', '1 minute', '5 minutes', '1 hour', '6 hour', '1 day', '7 days', ]), description=( "The time granularity for the visualization. Note that you " "can type and use simple natural language as in '10 seconds', " "'1 day' or '56 weeks'")), 'link_length': FreeFormSelectField( 'Link Length', default="200", choices=self.choicify([ '10', '25', '50', '75', '100', '150', '200', '250', ]), description="Link length in the force layout"), 'charge': FreeFormSelectField( 'Charge', default="-500", choices=self.choicify([ '-50', '-75', '-100', '-150', '-200', '-250', '-500', '-1000', '-2500', '-5000', ]), description="Charge in the force layout"), 'granularity_sqla': SelectField( 'Time Column', default=datasource.main_dttm_col or datasource.any_dttm_col, choices=self.choicify(datasource.dttm_cols), description=( "The time column for the visualization. Note that you " "can define arbitrary expression that return a DATETIME " "column in the table editor. Also note that the " "filter bellow is applied against this column or " "expression")), 'resample_rule': FreeFormSelectField( 'Resample Rule', default='', choices=self.choicify(('1T', '1H', '1D', '7D', '1M', '1AS')), description=("Pandas resample rule")), 'resample_how': FreeFormSelectField( 'Resample How', default='', choices=self.choicify(('', 'mean', 'sum', 'median')), description=("Pandas resample how")), 'resample_fillmethod': FreeFormSelectField( 'Resample Fill Method', default='', choices=self.choicify(('', 'ffill', 'bfill')), description=("Pandas resample fill method")), 'since': FreeFormSelectField( 'Since', default="7 days ago", choices=self.choicify([ '1 hour ago', '12 hours ago', '1 day ago', '7 days ago', '28 days ago', '90 days ago', '1 year ago' ]), description=( "Timestamp from filter. This supports free form typing and " "natural language as in '1 day ago', '28 days' or '3 years'")), 'until': FreeFormSelectField('Until', default="now", choices=self.choicify([ 'now', '1 day ago', '7 days ago', '28 days ago', '90 days ago', '1 year ago']) ), 'max_bubble_size': FreeFormSelectField( 'Max Bubble Size', default="25", choices=self.choicify([ '5', '10', '15', '25', '50', '75', '100', ]) ), 'row_limit': FreeFormSelectField( 'Row limit', default=config.get("ROW_LIMIT"), choices=self.choicify( [10, 50, 100, 250, 500, 1000, 5000, 10000, 50000])), 'limit': FreeFormSelectField( 'Series limit', choices=self.choicify(self.series_limits), default=50, description=( "Limits the number of time series that get displayed")), 'rolling_type': SelectField( 'Rolling', default='None', choices=[(s, s) for s in ['None', 'mean', 'sum', 'std', 'cumsum']], description=( "Defines a rolling window function to apply, works along " "with the [Periods] text box")), 'rolling_periods': IntegerField( 'Periods', validators=[validators.optional()], description=( "Defines the size of the rolling window function, " "relative to the time granularity selected")), 'series': SelectField( 'Series', choices=group_by_choices, default=default_groupby, description=( "Defines the grouping of entities. " "Each serie is shown as a specific color on the chart and " "has a legend toggle")), 'entity': SelectField('Entity', choices=group_by_choices, default=default_groupby, description="This define the element to be plotted on the chart"), 'x': SelectField( 'X Axis', choices=datasource.metrics_combo, default=default_metric, description="Metric assigned to the [X] axis"), 'y': SelectField('Y Axis', choices=datasource.metrics_combo, default=default_metric, description="Metric assigned to the [Y] axis"), 'size': SelectField( 'Bubble Size', default=default_metric, choices=datasource.metrics_combo), 'url': TextField( 'URL', default='www.airbnb.com',), 'where': TextField( 'Custom WHERE clause', default='', description=( "The text in this box gets included in your query's WHERE " "clause, as an AND to other criteria. You can include " "complex expression, parenthesis and anything else " "supported by the backend it is directed towards.")), 'having': TextField('Custom HAVING clause', default='', description=( "The text in this box gets included in your query's HAVING" " clause, as an AND to other criteria. You can include " "complex expression, parenthesis and anything else " "supported by the backend it is directed towards.")), 'compare_lag': TextField('Comparison Period Lag', description=( "Based on granularity, number of time periods to " "compare against")), 'compare_suffix': TextField('Comparison suffix', description="Suffix to apply after the percentage display"), 'x_axis_format': FreeFormSelectField('X axis format', default='smart_date', choices=[ ('smart_date', 'Adaptative formating'), ("%m/%d/%Y", '"%m/%d/%Y" | 01/14/2019'), ("%Y-%m-%d", '"%Y-%m-%d" | 2019-01-14'), ("%Y-%m-%d %H:%M:%S", '"%Y-%m-%d %H:%M:%S" | 2019-01-14 01:32:10'), ("%H:%M:%S", '"%H:%M:%S" | 01:32:10'), ], description="D3 format syntax for y axis " "https://github.com/mbostock/\n" "d3/wiki/Formatting"), 'y_axis_format': FreeFormSelectField('Y axis format', default='.3s', choices=[ ('.3s', '".3s" | 12.3k'), ('.3%', '".3%" | 1234543.210%'), ('.4r', '".4r" | 12350'), ('.3f', '".3f" | 12345.432'), ('+,', '"+," | +12,345.4321'), ('$,.2f', '"$,.2f" | $12,345.43'), ], description="D3 format syntax for y axis " "https://github.com/mbostock/\n" "d3/wiki/Formatting"), 'markup_type': SelectField( "Markup Type", choices=self.choicify(['markdown', 'html']), default="markdown", description="Pick your favorite markup language"), 'rotation': SelectField( "Rotation", choices=[(s, s) for s in ['random', 'flat', 'square']], default="random", description="Rotation to apply to words in the cloud"), 'line_interpolation': SelectField( "Line Style", choices=self.choicify([ 'linear', 'basis', 'cardinal', 'monotone', 'step-before', 'step-after']), default='linear', description="Line interpolation as defined by d3.js"), 'code': TextAreaField( "Code", description="Put your code here", default=''), 'pandas_aggfunc': SelectField( "Aggregation function", choices=self.choicify([ 'sum', 'mean', 'min', 'max', 'median', 'stdev', 'var']), default='sum', description=( "Aggregate function to apply when pivoting and " "computing the total rows and columns")), 'size_from': TextField( "Font Size From", default="20", description="Font size for the smallest value in the list"), 'size_to': TextField( "Font Size To", default="150", description="Font size for the biggest value in the list"), 'show_brush': BetterBooleanField( "Range Filter", default=False, description=( "Whether to display the time range interactive selector")), 'show_datatable': BetterBooleanField( "Data Table", default=False, description="Whether to display the interactive data table"), 'include_search': BetterBooleanField( "Search Box", default=False, description=( "Whether to include a client side search box")), 'show_bubbles': BetterBooleanField( "Show Bubbles", default=False, description=( "Whether to display bubbles on top of countries")), 'show_legend': BetterBooleanField( "Legend", default=True, description="Whether to display the legend (toggles)"), 'x_axis_showminmax': BetterBooleanField( "X bounds", default=True, description=( "Whether to display the min and max values of the X axis")), 'rich_tooltip': BetterBooleanField( "Rich Tooltip", default=True, description=( "The rich tooltip shows a list of all series for that" " point in time")), 'y_axis_zero': BetterBooleanField( "Y Axis Zero", default=False, description=( "Force the Y axis to start at 0 instead of the minimum " "value")), 'y_log_scale': BetterBooleanField( "Y Log", default=False, description="Use a log scale for the Y axis"), 'x_log_scale': BetterBooleanField( "X Log", default=False, description="Use a log scale for the X axis"), 'donut': BetterBooleanField( "Donut", default=False, description="Do you want a donut or a pie?"), 'contribution': BetterBooleanField( "Contribution", default=False, description="Compute the contribution to the total"), 'num_period_compare': IntegerField( "Period Ratio", default=None, validators=[validators.optional()], description=( "[integer] Number of period to compare against, " "this is relative to the granularity selected")), 'time_compare': TextField( "Time Shift", default="", description=( "Overlay a timeseries from a " "relative time period. Expects relative time delta " "in natural language (example: 24 hours, 7 days, " "56 weeks, 365 days")), }
def __init__(self, viz): self.viz = viz from panoramix.viz import viz_types viz = self.viz datasource = viz.datasource default_metric = datasource.metrics_combo[0][0] default_groupby = datasource.groupby_column_names[0] group_by_choices = [(s, s) for s in datasource.groupby_column_names] # Pool of all the fields that can be used in Panoramix self.field_dict = { 'viz_type': SelectField( 'Viz', default='table', choices=[(k, v.verbose_name) for k, v in viz_types.items()], description="The type of visualization to display"), 'metrics': SelectMultipleField( 'Metrics', choices=datasource.metrics_combo, default=[default_metric], description="One or many metrics to display"), 'metric': SelectField( 'Metric', choices=datasource.metrics_combo, default=default_metric, description="One or many metrics to display"), 'groupby': SelectMultipleField( 'Group by', choices=self.choicify(datasource.groupby_column_names), description="One or many fields to group by"), 'granularity': TextField( 'Time Granularity', default="one day", description=( "The time granularity for the visualization. Note that you " "can type and use simple natural language as in '10 seconds', " "'1 day' or '56 weeks'")), 'since': TextField( 'Since', default="7 days ago", description=( "Timestamp from filter. This supports free form typing and " "natural language as in '1 day ago', '28 days' or '3 years'")), 'until': TextField('Until', default="now"), 'row_limit': SelectField( 'Row limit', default=config.get("ROW_LIMIT"), choices=self.choicify(self.row_limits)), 'limit': SelectField( 'Series limit', choices=self.choicify(self.series_limits), default=50, description=( "Limits the number of time series that get displayed")), 'rolling_type': SelectField( 'Rolling', default='mean', choices=[(s, s) for s in ['mean', 'sum', 'std']], description=( "Defines a rolling window function to apply")), 'rolling_periods': IntegerField( 'Periods', validators=[validators.optional()], description=( "Defines the size of the rolling window function, " "relative to the 'granularity' field")), 'series': SelectField( 'Series', choices=group_by_choices, default=default_groupby, description=( "Defines the grouping of entities. " "Each serie is shown as a specific color on the chart and " "has a legend toggle")), 'entity': SelectField('Entity', choices=group_by_choices, default=default_groupby, description="This define the element to be plotted on the chart"), 'x': SelectField( 'X Axis', choices=datasource.metrics_combo, default=default_metric, description="Metric assigned to the [X] axis"), 'y': SelectField('Y Axis', choices=datasource.metrics_combo, default=default_metric, description="Metric assigned to the [Y] axis"), 'size': SelectField( 'Bubble Size', default=default_metric, choices=datasource.metrics_combo), 'where': TextField('Custom WHERE clause', default=''), 'compare_lag': TextField('Comparison Period Lag', description="Based on granularity, number of time periods to compare against"), 'compare_suffix': TextField('Comparison suffix', description="Suffix to apply after the percentage display"), 'markup_type': SelectField( "Markup Type", choices=self.choicify(['markdown', 'html']), default="markdown", description="Pick your favorite markup language"), 'rotation': SelectField( "Rotation", choices=[(s, s) for s in ['random', 'flat', 'square']], default="random", description="Rotation to apply to words in the cloud"), 'line_interpolation': SelectField( "Line Interpolation", choices=self.choicify([ 'linear', 'basis', 'cardinal', 'monotone', 'step-before', 'step-after']), default='linear', description="Line interpolation as defined by d3.js"), 'code': TextAreaField("Code", description="Put your code here"), 'size_from': TextField( "Font Size From", default="20", description="Font size for the smallest value in the list"), 'size_to': TextField( "Font Size To", default="150", description="Font size for the biggest value in the list"), 'show_brush': BooleanField( "Range Selector", default=True, description="Whether to display the time range interactive selector"), 'show_legend': BooleanField( "Legend", default=True, description="Whether to display the legend (toggles)"), 'rich_tooltip': BooleanField( "Rich Tooltip", default=True, description="The rich tooltip shows a list of all series for that point in time"), 'y_axis_zero': BooleanField( "Y Axis Zero", default=False, description="Force the Y axis to start at 0 instead of the minimum value"), 'y_log_scale': BooleanField( "Y Log", default=False, description="Use a log scale for the Y axis"), 'x_log_scale': BooleanField( "X Log", default=False, description="Use a log scale for the X axis"), 'donut': BooleanField( "Donut", default=False, description="Do you want a donut or a pie?"), 'contribution': BooleanField( "Contribution", default=False, description="Compute the contribution to the total"), 'num_period_compare': IntegerField( "Period Ratio", default=None, validators=[validators.optional()], description=( "[integer] Number of period to compare against, " "this is relative to the granularity selected")), 'time_compare': TextField( "Time Shift Compare", default="", description=( "Overlay a timeseries from a " "relative time period. Expects relative time delta " "in natural language (example: 24 hours, 7 days, " "56 weeks, 365 days")), }
def __init__(self, viz): self.viz = viz from panoramix.viz import viz_types viz = self.viz datasource = viz.datasource default_metric = datasource.metrics_combo[0][0] default_groupby = datasource.groupby_column_names[0] group_by_choices = [(s, s) for s in datasource.groupby_column_names] # Pool of all the fields that can be used in Panoramix self.field_dict = { 'viz_type': SelectField( 'Viz', default='table', choices=[(k, v.verbose_name) for k, v in viz_types.items()], description="The type of visualization to display"), 'metrics': SelectMultipleSortableField( 'Metrics', choices=datasource.metrics_combo, default=[default_metric], description="One or many metrics to display"), 'metric': SelectField( 'Metric', choices=datasource.metrics_combo, default=default_metric, description="Chose the metric"), 'secondary_metric': SelectField( 'Color Metric', choices=datasource.metrics_combo, default=default_metric, description="A metric to use for color"), 'groupby': SelectMultipleSortableField( 'Group by', choices=self.choicify(datasource.groupby_column_names), description="One or many fields to group by"), 'columns': SelectMultipleSortableField( 'Columns', choices=self.choicify(datasource.groupby_column_names), description="One or many fields to pivot as columns"), 'granularity': FreeFormSelectField( 'Time Granularity', default="one day", choices=self.choicify([ 'all', '5 seconds', '30 seconds', '1 minute', '5 minutes', '1 hour', '6 hour', '1 day', '7 days', ]), description=( "The time granularity for the visualization. Note that you " "can type and use simple natural language as in '10 seconds', " "'1 day' or '56 weeks'")), 'granularity_sqla': SelectField( 'Time Column', default=datasource.main_dttm_col, choices=self.choicify(datasource.dttm_cols), description=( "The time granularity for the visualization. Note that you " "can define arbitrary expression that return a DATETIME " "column in the table editor")), 'since': FreeFormSelectField( 'Since', default="7 days ago", choices=self.choicify([ '1 hour ago', '12 hours ago', '1 day ago', '7 days ago', '28 days ago', '90 days ago', '1 year ago' ]), description=( "Timestamp from filter. This supports free form typing and " "natural language as in '1 day ago', '28 days' or '3 years'")), 'until': FreeFormSelectField('Until', default="now", choices=self.choicify([ 'now', '1 day ago', '7 days ago', '28 days ago', '90 days ago', '1 year ago']) ), 'row_limit': SelectField( 'Row limit', default=config.get("ROW_LIMIT"), choices=self.choicify(self.row_limits)), 'limit': SelectField( 'Series limit', choices=self.choicify(self.series_limits), default=50, description=( "Limits the number of time series that get displayed")), 'rolling_type': SelectField( 'Rolling', default='None', choices=[(s, s) for s in ['None', 'mean', 'sum', 'std', 'cumsum']], description=( "Defines a rolling window function to apply, works along " "with the [Periods] text box")), 'rolling_periods': IntegerField( 'Periods', validators=[validators.optional()], description=( "Defines the size of the rolling window function, " "relative to the time granularity selected")), 'series': SelectField( 'Series', choices=group_by_choices, default=default_groupby, description=( "Defines the grouping of entities. " "Each serie is shown as a specific color on the chart and " "has a legend toggle")), 'entity': SelectField('Entity', choices=group_by_choices, default=default_groupby, description="This define the element to be plotted on the chart"), 'x': SelectField( 'X Axis', choices=datasource.metrics_combo, default=default_metric, description="Metric assigned to the [X] axis"), 'y': SelectField('Y Axis', choices=datasource.metrics_combo, default=default_metric, description="Metric assigned to the [Y] axis"), 'size': SelectField( 'Bubble Size', default=default_metric, choices=datasource.metrics_combo), 'where': TextField( 'Custom WHERE clause', default='', description=( "The text in this box gets included in your query's WHERE " "clause, as an AND to other criteria. You can include " "complex expression, parenthesis and anything else " "supported by the backend it is directed towards.")), 'having': TextField('Custom HAVING clause', default='', description=( "The text in this box gets included in your query's HAVING" " clause, as an AND to other criteria. You can include " "complex expression, parenthesis and anything else " "supported by the backend it is directed towards.")), 'compare_lag': TextField('Comparison Period Lag', description="Based on granularity, number of time periods to compare against"), 'compare_suffix': TextField('Comparison suffix', description="Suffix to apply after the percentage display"), 'y_axis_format': TextField('Y axis format', description="D3 format syntax for y axis " "https://github.com/mbostock/\n" "d3/wiki/Formatting"), 'markup_type': SelectField( "Markup Type", choices=self.choicify(['markdown', 'html']), default="markdown", description="Pick your favorite markup language"), 'rotation': SelectField( "Rotation", choices=[(s, s) for s in ['random', 'flat', 'square']], default="random", description="Rotation to apply to words in the cloud"), 'line_interpolation': SelectField( "Line Style", choices=self.choicify([ 'linear', 'basis', 'cardinal', 'monotone', 'step-before', 'step-after']), default='linear', description="Line interpolation as defined by d3.js"), 'code': TextAreaField( "Code", description="Put your code here", default=''), 'pandas_aggfunc': SelectField( "Aggregation function", choices=self.choicify([ 'sum', 'mean', 'min', 'max', 'median', 'stdev', 'var']), default='sum', description=( "Aggregate function to apply when pivoting and " "computing the total rows and columns")), 'size_from': TextField( "Font Size From", default="20", description="Font size for the smallest value in the list"), 'size_to': TextField( "Font Size To", default="150", description="Font size for the biggest value in the list"), 'show_brush': BetterBooleanField( "Range Filter", default=True, description=( "Whether to display the time range interactive selector")), 'show_legend': BetterBooleanField( "Legend", default=True, description="Whether to display the legend (toggles)"), 'x_axis_showminmax': BetterBooleanField( "X axis show min/max", default=True, description=( "Whether to display the min and max values of the axis")), 'rich_tooltip': BetterBooleanField( "Rich Tooltip", default=True, description="The rich tooltip shows a list of all series for that point in time"), 'y_axis_zero': BetterBooleanField( "Y Axis Zero", default=False, description="Force the Y axis to start at 0 instead of the minimum value"), 'y_log_scale': BetterBooleanField( "Y Log", default=False, description="Use a log scale for the Y axis"), 'x_log_scale': BetterBooleanField( "X Log", default=False, description="Use a log scale for the X axis"), 'donut': BetterBooleanField( "Donut", default=False, description="Do you want a donut or a pie?"), 'contribution': BetterBooleanField( "Contribution", default=False, description="Compute the contribution to the total"), 'num_period_compare': IntegerField( "Period Ratio", default=None, validators=[validators.optional()], description=( "[integer] Number of period to compare against, " "this is relative to the granularity selected")), 'time_compare': TextField( "Time Shift", default="", description=( "Overlay a timeseries from a " "relative time period. Expects relative time delta " "in natural language (example: 24 hours, 7 days, " "56 weeks, 365 days")), }