def post(self): starter = request.environ.get('REMOTE_USER') form = ReleasesForm() form.readyReleases.choices = [(r.name, r.name) for r in getReleases(ready=False)] # Don't include completed or ready releases, because they aren't allowed to be deleted form.deleteReleases.choices = [(r.name, r.name) for r in getReleases(complete=False, ready=False)] if not form.validate(): cef_event('User Input Failed', CEF_WARN, **form.errors) return make_response(render_template('releases.html', errors=form.errors, releases=sortedReleases(), form=form), 400) for release in form.deleteReleases.data: log.debug('%s is being deleted', release) table = getReleaseTable(release) r = table.query.filter_by(name=release).first() db.session.delete(r) for release in form.readyReleases.data: log.debug('%s is being marked as ready', release) table = getReleaseTable(release) r = table.query.filter_by(name=release).first() r.ready = True r.status = 'Pending' r.comment = form.comment.data r.starter = starter db.session.add(r) db.session.commit() return render_template('releases.html', releases=sortedReleases(), form=form)
def post(self): starter = request.environ.get('REMOTE_USER') form = ReleasesForm() form.readyReleases.choices = [(r.name, r.name) for r in getReleases(ready=False)] # Don't include completed or ready releases, because they aren't allowed to be deleted form.deleteReleases.choices = [(r.name, r.name) for r in getReleases(complete=False, ready=False)] if not form.validate(): cef_event('User Input Failed', CEF_WARN, **form.errors) return make_response(render_template('releases.html', errors=form.errors, releases=sortedReleases(), form=form), 400) for release in form.deleteReleases.data: log.debug('%s is being deleted', release) table = getReleaseTable(release) r = table.query.filter_by(name=release).first() db.session.delete(r) for release in form.readyReleases.data: log.debug('%s is being marked as ready', release) table = getReleaseTable(release) r = table.query.filter_by(name=release).first() r.ready = True r.status = 'Pending' r.comment = form.comment.data r.starter = starter db.session.add(r) db.session.commit() return render_template('releases.html', releases=sortedReleases(ready=False), form=form)
def getFilteredReleases(product, categories, ESR_NEXT=False, lastRelease=None, withL10N=False): version = [] # we don't export esr in the version name if "major" in categories: version.append("([0-9]+\.[0-9]+|14\.0\.1)$") if "stability" in categories: version.append("([0-9]+\.[0-9]+\.[0-9]+(esr|)$|[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+(esr|)$)") if "dev" in categories: # We had 38.0.5b2 version.append("([0-9]+\.[0-9]|[0-9]+\.[0-9]+\.[0-9])(b|rc|build|plugin)[0-9]+$") if "esr" in categories: if ESR_NEXT: # Ugly hack to manage the next ESR (when we have two overlapping esr) version.append("(" + config.ESR_NEXT + "\.[0-9]+\.[0-9]+esr$|" + config.ESR_NEXT + "\.[0-9]+\.[0-9]+\.[0-9]+esr$)") else: version.append("(" + config.CURRENT_ESR + "\.[0-9]+\.[0-9]+esr$|" + config.CURRENT_ESR + "\.[0-9]+\.[0-9]+\.[0-9]+esr$)") releases = getReleases(ready=True, productFilter=product, versionFilterCategory=version, lastRelease=lastRelease) results = [] for r in releases: version = r.version.replace("esr", "") if r._shippedAt: shippedAt = r._shippedAt.strftime("%Y-%m-%d") else: # No shipped date, we are not interested by this release, skip continue if withL10N: # We need the list of locales results.append([version, shippedAt, r.l10nChangesets]) else: results.append([version, shippedAt]) return results
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.') # 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
def get(self): start = request.args.get('iDisplayStart', type=int) length = request.args.get('iDisplayLength', type=int) readyParam = request.args.get('ready') completeParam = request.args.get('complete') ready = None complete = None if readyParam is not None: ready = readyParam == 'true' if completeParam is not None: complete = completeParam == 'true' searchFilterDict = self.getSearchFilterDict() orderByDict = self.getOrderByDict() total = self.getTotal(complete=complete, ready=ready, searchFilter=searchFilterDict) paginationCriteria = ReleasesPaginationCriteria(start, length, orderByDict) releases = getReleases(complete=complete, ready=ready, paginationCriteria=paginationCriteria, searchFilter=searchFilterDict) paginatedReleases = { 'releases': [r.toDict() for r in releases], 'iTotalDisplayRecords': total, 'iTotalRecords': total } return jsonify(paginatedReleases)
def get(self): start = request.args.get('iDisplayStart', type=int) length = request.args.get('iDisplayLength', type=int) readyParam = request.args.get('ready') completeParam = request.args.get('complete') ready = None complete = None if readyParam is not None: ready = readyParam == 'true' if completeParam is not None: complete = completeParam == 'true' searchFilterDict = self.getSearchFilterDict() orderByDict = self.getOrderByDict() total = self.getTotal(complete=complete, ready=ready, searchFilter=searchFilterDict) paginationCriteria = ReleasesPaginationCriteria( start, length, orderByDict) releases = getReleases(complete=complete, ready=ready, paginationCriteria=paginationCriteria, searchFilter=searchFilterDict) paginatedReleases = { 'releases': [r.toDict() for r in releases], 'iTotalDisplayRecords': total, 'iTotalRecords': total } return jsonify(paginatedReleases)
def generateListPerProduct(product): releases = getReleases(ready=True, productFilter=product) version_list = [] for r in releases: if r._shippedAt and r.l10nChangesets != config.LEGACY_KEYWORD: # Only list version which shipped with l10n content version_list.append(r.name) return version_list
def getFilteredReleases(product, categories, ESR_NEXT=False, lastRelease=None, withL10N=False, detailledInfo=False): version = [] # we don't export esr in the version name if "major" in categories: version.append(("major", "([0-9]+\.[0-9]+|14\.0\.1)$")) if "stability" in categories: version.append(("stability", "([0-9]+\.[0-9]+\.[0-9]+(esr|)$|[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+(esr|)$)")) if "dev" in categories: # We had 38.0.5b2 version.append(("dev", "([0-9]+\.[0-9]|[0-9]+\.[0-9]+\.[0-9])(b|rc|build|plugin)[0-9]+$")) if "esr" in categories: if ESR_NEXT: # Ugly hack to manage the next ESR (when we have two overlapping esr) version.append(("esr", "(" + config.ESR_NEXT + "\.[0-9]+\.[0-9]+esr$|" + config.ESR_NEXT + "\.[0-9]+\.[0-9]+\.[0-9]+esr$)")) else: version.append(("esr", "(" + config.CURRENT_ESR + "\.[0-9]+\.[0-9]+esr$|" + config.CURRENT_ESR + "\.[0-9]+\.[0-9]+\.[0-9]+esr$)")) releases = getReleases(ready=True, productFilter=product, versionFilterCategory=version, lastRelease=lastRelease) results = [] for r in releases: version = r.version.replace("esr", "") if r._shippedAt: shippedAt = r._shippedAt.strftime("%Y-%m-%d") else: # No shipped date, we are not interested by this release, skip continue if withL10N: # We need the list of locales results.append([version, shippedAt, r.l10nChangesets ]) else: if detailledInfo: results.append({"version": version, "shippedAt": shippedAt, "versionDetailled": r.version, "category": r.category, "description": r.description, "isSecurityDriven": r.isSecurityDriven }) else: results.append([version, shippedAt ]) return results
def get(self): # We can't get request.args to convert directly to a bool because # it will convert even if the arg isn't present! In these cases # we need to be able to pass along a None, so we must be a bit # roundabout here. try: ready = request.args.get('ready', type=int) complete = request.args.get('complete', type=int) if ready is not None: ready = bool(ready) if complete is not None: complete = bool(complete) except ValueError: cef_event('User Input Failed', CEF_INFO, ready=ready, complete=complete) return Response(status=400, response="Got unparseable value for ready or complete") releases = [r.name for r in getReleases(ready, complete)] return jsonify({'releases': releases})
def sortedReleases(): def cmpReleases(x, y): # Not ready releases should come before ready ones. # Incomplete releases should come before completed ones. # After that, sort by submission time # Newer releases should be at the top. if x.ready: if not y.ready: return 1 elif y.ready: return -1 if x.complete: if not y.complete: return 1 elif y.complete: return -1 return cmp(y._submittedAt, x._submittedAt) return sorted(getReleases(), cmp=cmpReleases)
def sortedReleases(ready=None): def cmpReleases(x, y): # Not ready releases should come before ready ones. # Incomplete releases should come before completed ones. # After that, sort by submission time # Newer releases should be at the top. if x.ready: if not y.ready: return 1 elif y.ready: return -1 if x.complete: if not y.complete: return 1 elif y.complete: return -1 return cmp(y._submittedAt, x._submittedAt) # NOQA return sorted(getReleases(ready=ready), cmp=cmpReleases)
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
def getFilteredReleases(product, categories, esrNext=False, lastRelease=None, withL10N=False, detailledInfo=False, exclude_esr=False): version = [] # we don't export esr in the version name if "major" in categories: if product == "thunderbird": special_majors = patternize_versions(SPECIAL_THUNDERBIRD_MAJORS) else: special_majors = patternize_versions(SPECIAL_FIREFOX_MAJORS) if exclude_esr: version.append(("major", r"([0-9]+\.[0-9]+%s)$" % special_majors)) else: version.append(("major", r"([0-9]+\.[0-9]+(esr|)%s)$" % special_majors)) if "stability" in categories: if exclude_esr: version.append(("stability", r"([0-9]+\.[0-9]+\.[0-9]+$|[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$)")) else: version.append(("stability", r"([0-9]+\.[0-9]+\.[0-9]+(esr|)$|[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+(esr|)$)")) if "dev" in categories: # We had 38.0.5b2 version.append(("dev", r"([0-9]+\.[0-9]|[0-9]+\.[0-9]+\.[0-9])(b|rc|build|plugin)[0-9]+$")) if "esr" in categories: if esrNext and not config.ESR_NEXT: # No ESR_NEXT yet return if esrNext: # Ugly hack to manage the next ESR (when we have two overlapping esr) version.append(("esr", config.ESR_NEXT + r"(\.[0-9]+){1,2}esr$")) else: version.append(("esr", config.CURRENT_ESR + r"(\.[0-9]+){1,2}esr$")) releases = getReleases(ready=True, productFilter=product, versionFilterCategory=version, lastRelease=lastRelease) results = [] for r in releases: version = r.version.replace("esr", "") if r._shippedAt: shippedAt = r._shippedAt.strftime("%Y-%m-%d") else: # No shipped date, we are not interested by this release, skip continue if withL10N: # We need the list of locales results.append([version, shippedAt, r.l10nChangesets ]) else: if detailledInfo: results.append({"version": version, "buildNumber": r.buildNumber, "shippedAt": shippedAt, "versionDetailled": r.version, "category": r.category, "description": r.description, "isSecurityDriven": r.isSecurityDriven }) else: results.append([version, shippedAt ]) return results
def generateListPerProduct(product): releases = getReleases(ready=True, productFilter=product) registrar = _L10nReleasesRegistrar() for r in releases: registrar.addRelease(r) return registrar.releases
def getFilteredReleases(product, categories, esrNext=False, lastRelease=None, withL10N=False, detailledInfo=False, exclude_esr=False): version = [] # we don't export esr in the version name if "major" in categories: if product == "thunderbird": special_majors = patternize_versions(SPECIAL_THUNDERBIRD_MAJORS) else: special_majors = patternize_versions(SPECIAL_FIREFOX_MAJORS) version.append(("major", r"([0-9]+\.[0-9]+%s)$" % special_majors)) if "stability" in categories: if exclude_esr: version.append( ("stability", r"([0-9]+\.[0-9]+\.[0-9]+$|[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$)")) else: version.append(( "stability", r"([0-9]+\.[0-9]+\.[0-9]+(esr|)$|[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+(esr|)$)" )) if "dev" in categories: # We had 38.0.5b2 version.append( ("dev", r"([0-9]+\.[0-9]|[0-9]+\.[0-9]+\.[0-9])(b|rc|build|plugin)[0-9]+$" )) if "esr" in categories: if esrNext and not config.ESR_NEXT: # No ESR_NEXT yet return if esrNext: # Ugly hack to manage the next ESR (when we have two overlapping esr) version.append(("esr", config.ESR_NEXT + r"(\.[0-9]+){1,2}esr$")) else: version.append( ("esr", config.CURRENT_ESR + r"(\.[0-9]+){1,2}esr$")) releases = getReleases(ready=True, productFilter=product, versionFilterCategory=version, lastRelease=lastRelease) results = [] for r in releases: version = r.version.replace("esr", "") if r._shippedAt: shippedAt = r._shippedAt.strftime("%Y-%m-%d") else: # No shipped date, we are not interested by this release, skip continue if withL10N: # We need the list of locales results.append([version, shippedAt, r.l10nChangesets]) else: if detailledInfo: results.append({ "version": version, "shippedAt": shippedAt, "versionDetailled": r.version, "category": r.category, "description": r.description, "isSecurityDriven": r.isSecurityDriven }) else: results.append([version, shippedAt]) return results