class ThunderbirdReleaseForm(DesktopReleaseForm): product = HiddenField('product') commRevision = StringField('Comm Revision:') commRelbranch = StringField('Comm Relbranch:', filters=[noneFilter]) def __init__(self, *args, **kwargs): ReleaseForm.__init__(self, prefix='thunderbird', product='thunderbird', *args, **kwargs) def validate(self, *args, **kwargs): valid = DesktopReleaseForm.validate(self, *args, **kwargs) if self.commRelbranch.data: self.commRevision.data = self.commRelbranch.data else: if not self.commRevision.data: valid = False self.errors['commRevision'] = ['Comm revision is required'] return valid def updateFromRow(self, row): self.version.data = row.version self.buildNumber.data = row.buildNumber self.branch.data = row.branch if not row.mozillaRelbranch: self.mozillaRevision.data = row.mozillaRevision if not row.commRelbranch: self.commRevision.data = row.commRevision self.partials.data = row.partials self.promptWaitTime.data = row.promptWaitTime self.dashboardCheck.data = row.dashboardCheck self.l10nChangesets.data = row.l10nChangesets self.mozillaRelbranch.data = row.mozillaRelbranch self.commRelbranch.data = row.commRelbranch
class ThunderbirdReleaseForm(DesktopReleaseForm): product = HiddenField('product') commRevision = StringField('Comm Revision:') commRelbranch = StringField('Comm Relbranch:', filters=[noneFilter]) def __init__(self, *args, **kwargs): ReleaseForm.__init__(self, prefix='thunderbird', product='thunderbird', *args, **kwargs) def validate(self, *args, **kwargs): valid = DesktopReleaseForm.validate(self, *args, **kwargs) if self.commRelbranch.data: self.commRevision.data = self.commRelbranch.data else: if not self.commRevision.data: valid = False self.errors['commRevision'] = ['Comm revision is required'] return valid def updateFromRow(self, row): DesktopReleaseForm.updateFromRow(self, row) self.promptWaitTime.data = row.promptWaitTime self.commRelbranch.data = row.commRelbranch if not row.commRelbranch: self.commRevision.data = row.commRevision
class ThunderbirdReleaseForm(DesktopReleaseForm): product = HiddenField('product') commRevision = StringField('Comm Revision:') commRelbranch = StringField('Comm Relbranch:', filters=[noneFilter]) # Do not validate Thunderbird partials, they are not implemented partials = StringField('Partials:') def __init__(self, *args, **kwargs): ReleaseForm.__init__(self, prefix='thunderbird', product='thunderbird', *args, **kwargs) def validate(self, *args, **kwargs): valid = DesktopReleaseForm.validate(self, *args, **kwargs) if self.commRelbranch.data: self.commRevision.data = self.commRelbranch.data else: if not self.commRevision.data: # Thunderbird uses "revision" for commRevision, but # shipitscript converts it to mozillaRevision self.commRevision.data = self.mozillaRevision.data return valid def updateFromRow(self, row): DesktopReleaseForm.updateFromRow(self, row) self.promptWaitTime.data = row.promptWaitTime self.commRelbranch.data = row.commRelbranch if not row.commRelbranch: self.commRevision.data = row.commRevision
class ReleaseEventsAPIForm(Form): sent = DateTimeField('Sent:', validators=[InputRequired('Sent is required.')]) event_name = StringField('Event Name:', validators=[InputRequired('Event Name is required.'), Length(0, 150)]) platform = StringField('Platform:') results = IntegerField('Results:', default=0, validators=[InputRequired('Results is required.')]) chunkNum = IntegerField('Chunk Number:', default=1) chunkTotal = IntegerField('Chunk Total:', default=1) group = StringField('Group:', default='other')
class SearchForm(Form): first_name = StringField('First Name', [name_length_check]) last_name = StringField('Last Name', [name_length_check]) encoding = SelectField( 'Search Type', default='normalize', choices=ENCODING_CHOICES, )
class DesktopReleaseForm(ReleaseForm): partials = StringField( 'Partial versions:', validators=[ Regexp(PARTIAL_VERSIONS_REGEX, message='Invalid partials format.') ], filters=[collapseSpaces], ) promptWaitTime = NullableIntegerField('Update prompt wait time:') l10nChangesets = PlainChangesetsField( 'L10n Changesets:', validators=[DataRequired('L10n Changesets are required.')]) def addSuggestions(self): ReleaseForm.addSuggestions(self) table = getReleaseTable(self.product.data) recentReleases = table.getRecentShipped() seenVersions = [] partials = defaultdict(list) # The UI will suggest any versions which are on the same branch as # the one given, but only the highest build number for that version. # One exception is Firefox RC builds (version X.0), which should be added # to the list of betas for release in reversed(recentReleases): if release.version not in seenVersions: partials[release.branch].append( '%sbuild%d' % (release.version, release.buildNumber)) seenVersions.append(release.version) # here's the exception if release.product == 'firefox' and \ release.branch == 'releases/mozilla-release' and \ re.match('^\d+\.0$', release.version): partials['releases/mozilla-beta'].append( '%sbuild%d' % (release.version, release.buildNumber)) self.partials.suggestions = json.dumps(partials)
class placeableUpgradeForm(Form): name = StringField('Type Name', [validators.Length(min=4, max=20)]) description = TextAreaField('Describe the Intention of this upgrade', [validators.Length(min=4, max=250)]) #Upgrde type selectable upgrade_type = SelectField(u'Upgrade Type', coerce=unicode) del_entity = HiddenField('del_entity')
class DesktopReleaseForm(ReleaseForm): partials = StringField( 'Partial versions:', validators=[ Regexp(PARTIAL_VERSIONS_REGEX, message='Invalid partials format.') ], filters=[collapseSpaces], ) promptWaitTime = NullableIntegerField('Update prompt wait time:') l10nChangesets = PlainChangesetsField( 'L10n Changesets:', validators=[DataRequired('L10n Changesets are required.')]) def addSuggestions(self): ReleaseForm.addSuggestions(self) table = getReleaseTable(self.product.data) recentReleases = table.getRecentShipped() seenVersions = [] partials = {} # The UI will suggest any versions which are on the same branch as # the one given, but only the highest build number for that version. for release in reversed(recentReleases): if release.branch not in partials: partials[release.branch] = [] if release.version not in seenVersions: partials[release.branch].append( '%sbuild%d' % (release.version, release.buildNumber)) seenVersions.append(release.version) self.partials.suggestions = json.dumps(partials)
class EditReleaseForm(Form): shippedAtDate = DateField('Shipped date', format='%Y/%m/%d', validators=[ validators.optional(), ]) shippedAtTime = StringField('Shipped time') isSecurityDriven = BooleanField('Is Security Driven ?') description = TextAreaField('Description') isShipped = BooleanField('Is Shipped ?') def validate_isShipped(form, field): if form.isShipped.data: dt = form.shippedAt if (not dt) or (dt > datetime.now()): raise ValidationError('Invalid Date for Shipped release') @property def shippedAt(self): dateAndTime = None if self.shippedAtDate.data: dt = self.shippedAtDate.data tm = datetime.strptime(self.shippedAtTime.data, '%H:%M:%S').time() dateAndTime = datetime.combine(dt, tm) return dateAndTime
class ReleaseAPIForm(Form): ready = ThreeStateField('ready') complete = ThreeStateField('complete') # If the client sends us a really long status we'd rather truncate # it than complain, because it's purely informational. # Use the Column length directly rather than duplicating its value. status = StringField('status', filters=[truncateFilter(Release.status.type.length)]) enUSPlatforms = JSONField('enUSPlatforms') shippedAt = DateTimeField('shippedAt', [validators.optional()]) description = TextAreaField('description', [validators.optional()]) isSecurityDriven = BooleanField('isSecurityDriven', [validators.optional()]) def validate(self, release, *args, **kwargs): valid = Form.validate(self, *args, **kwargs) # Completed releases shouldn't be altered in terms of readyness or # completeness. Status updates are OK though. if release.complete: if self.ready.data is False or self.complete.data is False: valid = False if 'ready' not in self.errors: self.errors['ready'] = [] self.errors['ready'].append( 'Cannot make a completed release not ready or incomplete.') if self.description: # We just want to update the description & isSecurityDriven valid = True else: # Check if there is an other product-version already shipped similar = getReleases(status="postrelease", productFilter=release.product, versionFilter=release.version) if similar and self.status.data != "Started": # In most of the cases, it is useless since bug 1121032 has been implemented but keeping it # in case we change/revert in the future and because we cannot always trust the client valid = False if 'postrelease' not in self.errors: self.errors['postrelease'] = [] self.errors['postrelease'].append( 'Version ' + release.version + ' already marked as shipped') # If the release isn't complete, we can accept changes to readyness or # completeness, but marking a release as not ready *and* complete at # the same time is invalid. else: if self.ready.data is False and self.complete.data is True: valid = False if 'ready' not in self.errors: self.errors['ready'] = [] self.errors['ready'].append( 'A release cannot be made ready and complete at the same time' ) return valid
class SpammerForm(Form): address = StringField(u"Address Entry", [ validators.DataRequired(message=u"You must enter an address."), validators.Regexp( reg, flags=0, message=u"Invalid address. The address must begin with an '@'.") ]) submit = SubmitField()
class SpammerForm(Form): error_msg = u"""The address you tried to add is wrong. Please type it like this:<ul><li>Everything <em>after</em> the "@" sign, with no spaces.</li> <li>Example: <strong>enterprise-weasels.co.uk</strong></li></ul>""" address = StringField(u"Address Entry", [ validators.DataRequired(message=u"You have to enter an address."), validators.Regexp(reg, flags=0, message=error_msg) ]) submit = SubmitField()
class JobSettingsForm(Form): choices = [] for name in stat.stat_names(): if name == 'glm': for family in stat.glm_families(): x = name + " (" + family + ")" choices.append((x, x)) else: choices.append((name, name)) statistic = SelectField('Statistic', choices=choices) bins = IntegerField('Number of bins', validators=[Required()], default=pade.model.DEFAULT_NUM_BINS) permutations = IntegerField('Maximum number of permutations', validators=[Required()], default=pade.model.DEFAULT_NUM_SAMPLES) sample_from_residuals = BooleanField( 'Sample from residuals', validators=[Required()], default=pade.model.DEFAULT_SAMPLE_FROM_RESIDUALS) sample_with_replacement = BooleanField( 'Use bootstrapping (instead of permutation test)', validators=[Required()], default=pade.model.DEFAULT_SAMPLE_WITH_REPLACEMENT) equalize_means = BooleanField('Equalize means', validators=[Required()], default=pade.model.DEFAULT_EQUALIZE_MEANS) summary_min_conf_level = FloatField( 'Minimum confidence level', validators=[Required()], default=pade.model.DEFAULT_SUMMARY_MIN_CONF) summary_step_size = FloatField( 'Summary step size', validators=[Required()], default=pade.model.DEFAULT_SUMMARY_STEP_SIZE) tuning_params = StringField('Tuning parameters', validators=[Required()], default=' '.join( map(str, pade.model.DEFAULT_TUNING_PARAMS))) submit = SubmitField()
class PlaceableForm(Form): placeableName = StringField('Name', [validators.Length(min=4, max=20)]) new_description = TextAreaField('Description', [validators.Length(min=4, max=250)]) del_entity = HiddenField('del_entity')
class NewFactorForm(Form): factor_name = StringField('Factor name', validators=[Required()]) possible_values = FieldList(StringField('')) submit = SubmitField()
class ReleaseForm(Form): version = StringField('Version:', validators=[ Regexp(ANY_VERSION_REGEX, message='Invalid version format.') ]) buildNumber = IntegerField( 'Build Number:', validators=[DataRequired('Build number is required.')]) branch = StringField('Branch:', validators=[DataRequired('Branch is required')]) mozillaRevision = StringField('Mozilla Revision:') dashboardCheck = BooleanField('Dashboard check?', default=False) mozillaRelbranch = StringField('Mozilla Relbranch:', filters=[noneFilter]) comment = TextAreaField('Extra information to release-drivers:') description = TextAreaField('Description:') isSecurityDriven = BooleanField('Is a security driven release?', default=False) mh_changeset = StringField('Mozharness Revision:') def __init__(self, suggest=True, *args, **kwargs): Form.__init__(self, *args, **kwargs) if suggest: self.addSuggestions() def validate(self, *args, **kwargs): valid = Form.validate(self, *args, **kwargs) # If a relbranch has been passed revision is ignored. if self.mozillaRelbranch.data: self.mozillaRevision.data = self.mozillaRelbranch.data # However, if a relbranch hasn't been passed, revision is required. else: if not self.mozillaRevision.data: valid = False self.errors['mozillaRevision'] = [ 'Mozilla revision is required' ] return valid def addSuggestions(self): table = getReleaseTable(self.product.data) recentReleases = table.getRecent() # Before we make any suggestions we need to do some preprocessing of # the data to get it into useful structures. Specifically, we need a # set containing all of the recent versions, and a dict that associates # them with the branch they were built on. recentVersions = set() recentBranches = defaultdict(list) for release in recentReleases: recentVersions.add(release.version) recentBranches[release.branch].append(LooseVersion( release.version)) # Now that we have the data in the format we want it in we can start # making suggestions. suggestedVersions = set() buildNumbers = {} # This wrapper method is used to centralize the build number suggestion # logic in one place, because there's more than one spot below that # adds a version suggestion. def addVersionSuggestion(version): suggestedVersions.add(version) # We want the UI to be able to automatically set build number # to the next available one for whatever version is entered. # To make this work we need to tell it what the next available # one is for all existing versions. We don't need to add versions # that are on build1, because it uses that as the default. maxBuildNumber = table.getMaxBuildNumber(version) if maxBuildNumber: buildNumbers[version] = maxBuildNumber + 1 else: buildNumbers[version] = 1 # Every version we see will have its potential next versions # suggested, except if we already have that version. # Note that we don't look through the entire table for every # version (because that could be expensive) but any versions # which are suggested and have already happened should be in # 'recentVersions', so it's unlikely we'll be suggesting # something that has already happened. for version in recentVersions: for v in getPossibleNextVersions(version): if v not in recentVersions: addVersionSuggestion(v) # Additional, we need to suggest the most recent version for each # branch, because we may want a build2 (or higher) of it. for branchVersions in recentBranches.values(): addVersionSuggestion(str(max(branchVersions))) # Finally, attach the suggestions to their fields. self.branch.suggestions = json.dumps(list(recentBranches.keys())) self.version.suggestions = json.dumps(list(suggestedVersions)) self.buildNumber.suggestions = json.dumps(buildNumbers)
class placeableUpgradeTypeForm(Form): name = StringField('Type Name', [validators.Length(min=4, max=20)]) description = TextAreaField('Describe the Intention of this type', [validators.Length(min=4, max=250)]) del_entity = HiddenField('del_entity')
class CharacterClassForm(Form): className = StringField('Character Class Name', [validators.Length(min=4, max=20)]) classDescription = TextAreaField( 'Describe the intention of this character class', [validators.Length(min=4, max=250)])
class ReleaseForm(Form): version = StringField('Version:', validators=[ Regexp(ANY_VERSION_REGEX, message='Invalid version format.') ]) buildNumber = IntegerField( 'Build Number:', validators=[DataRequired('Build number is required.')]) branch = StringField('Branch:', validators=[DataRequired('Branch is required')]) mozillaRevision = StringField('Mozilla Revision:') mozillaRelbranch = StringField('Mozilla Relbranch:', filters=[noneFilter]) comment = TextAreaField('Extra information to release-drivers:') description = TextAreaField('Description:') isSecurityDriven = BooleanField('Is a security driven release?', default=False) mh_changeset = StringField('Mozharness Revision:') release_eta_date = DateField('Release ETA date:', format='%Y-%m-%d', validators=[validators.optional()]) release_eta_time = StringField('Release ETA time:') VALID_VERSION_PATTERN = re.compile( r"""^(\d+)\.( # Major version number (0)(a1|a2|b(\d+)|esr)? # 2-digit-versions (like 46.0, 46.0b1, 46.0esr) |( # Here begins the 3-digit-versions. ([1-9]\d*)\.(\d+)|(\d+)\.([1-9]\d*) # 46.0.0 is not correct )(esr)? # Neither is 46.2.0b1 )(build(\d+))?$""", re.VERBOSE) # See more examples of (in)valid versions in the tests def __init__(self, suggest=True, *args, **kwargs): Form.__init__(self, *args, **kwargs) if suggest: self.addSuggestions() def validate(self, *args, **kwargs): valid = Form.validate(self, *args, **kwargs) # If a relbranch has been passed revision is ignored. if self.mozillaRelbranch.data: self.mozillaRevision.data = self.mozillaRelbranch.data # However, if a relbranch hasn't been passed, revision is required. else: if not self.mozillaRevision.data: valid = False self.errors['mozillaRevision'] = [ 'Mozilla revision is required' ] if self.VALID_VERSION_PATTERN.match(self.version.data) is None: valid = False self.errors['version'] = ['Version must match either X.0 or X.Y.Z'] return valid def addSuggestions(self): table = getReleaseTable(self.product.data) recentReleases = table.getRecent() # Before we make any suggestions we need to do some preprocessing of # the data to get it into useful structures. Specifically, we need a # set containing all of the recent versions, and a dict that associates # them with the branch they were built on. recentVersions = set() recentBranches = defaultdict(list) for release in recentReleases: recentVersions.add(release.version) recentBranches[release.branch].append(MozVersion(release.version)) # Now that we have the data in the format we want it in we can start # making suggestions. suggestedVersions = set() buildNumbers = {} # This wrapper method is used to centralize the build number suggestion # logic in one place, because there's more than one spot below that # adds a version suggestion. def addVersionSuggestion(version): suggestedVersions.add(version) # We want the UI to be able to automatically set build number # to the next available one for whatever version is entered. # To make this work we need to tell it what the next available # one is for all existing versions. We don't need to add versions # that are on build1, because it uses that as the default. maxBuildNumber = table.getMaxBuildNumber(version) if maxBuildNumber: buildNumbers[version] = maxBuildNumber + 1 else: buildNumbers[version] = 1 # Every version we see will have its potential next versions # suggested, except if we already have that version. # Note that we don't look through the entire table for every # version (because that could be expensive) but any versions # which are suggested and have already happened should be in # 'recentVersions', so it's unlikely we'll be suggesting # something that has already happened. for version in recentVersions: for v in getPossibleNextVersions(version): if v not in recentVersions: addVersionSuggestion(v) # Additional, we need to suggest the most recent version for each # branch, because we may want a build2 (or higher) of it. for branchVersions in recentBranches.values(): addVersionSuggestion(str(max(branchVersions))) # Finally, attach the suggestions to their fields. self.branch.suggestions = json.dumps(list(recentBranches.keys())) self.version.suggestions = json.dumps(list(suggestedVersions)) self.buildNumber.suggestions = json.dumps(buildNumbers) def updateFromRow(self, row): self.version.data = row.version self.buildNumber.data = row.buildNumber self.branch.data = row.branch # Revision is a disabled field if relbranch is present, so we shouldn't # put any data in it. if not row.mozillaRelbranch: self.mozillaRevision.data = row.mozillaRevision self.l10nChangesets.data = row.l10nChangesets self.mozillaRelbranch.data = row.mozillaRelbranch self.mh_changeset.data = row.mh_changeset if row.release_eta: release_eta = parse_iso8601_to_date_time(row.release_eta) self.release_eta_date.data = release_eta.date() # Conversion needed because release_eta_time is a StringField self.release_eta_time.data = release_eta.strftime('%H:%M %Z') @property def release_eta(self): if self.release_eta_date.data and self.release_eta_time.data: dt = self.release_eta_date.data tm = datetime.strptime(self.release_eta_time.data, '%H:%M %Z').time() return datetime.combine(dt, tm) else: return None
class EventActorForm(Form): actorName = StringField('Event Actor name', [validators.Length(min=4, max=20)]) description = TextAreaField('Describe the intention of this actor', [validators.Length(min=4, max=250)])
class EventForm(Form): eventName = StringField('Event Name', [validators.Length(min=4, max=30)])