def get(self, path, feature_id): user = users.get_current_user() if user is None: # Redirect to public URL for unauthenticated users. return self.redirect(format_feature_url(feature_id)) if not self.user_can_edit(user): common.handle_401(self.request, self.response, Exception) return f = models.Feature.get_by_id(long(feature_id)) if f is None: self.abort(404) feature_process = processes.ALL_PROCESSES.get( f.feature_type, processes.BLINK_LAUNCH_PROCESS) template_data = { 'overview_form': guideforms.MetadataForm(f.format_for_edit()), 'process_json': json.dumps(processes.process_to_dict(feature_process)), } progress_so_far = self.detect_progress(f) # Provide new or populated form to template. template_data.update({ 'feature': f.format_for_template(), 'feature_id': f.key().id, 'feature_json': json.dumps(f.format_for_template()), 'progress_so_far': json.dumps(progress_so_far), }) self._add_common_template_values(template_data) self.render(data=template_data, template_path=os.path.join(path + '.html'))
def post(self, path): user = users.get_current_user() if user is None or (user and not self.user_can_edit(user)): common.handle_401(self.request, self.response, Exception) return owner_addrs = self.split_input('owner', delim=',') owners = [db.Email(addr) for addr in owner_addrs] blink_components = ( self.split_input('blink_components', delim=',') or [models.BlinkComponent.DEFAULT_COMPONENT]) # TODO(jrobbins): Validate input, even though it is done on client. feature = models.Feature( category=int(self.request.get('category')), name=self.request.get('name'), feature_type=int(self.request.get('feature_type', 0)), intent_stage=models.INTENT_NONE, summary=self.request.get('summary'), owner=owners, impl_status_chrome=models.NO_ACTIVE_DEV, standardization=models.EDITORS_DRAFT, unlisted=self.request.get('unlisted') == 'on', web_dev_views=models.DEV_NO_SIGNALS, blink_components=blink_components) key = feature.put() # TODO(jrobbins): enumerate and remove only the relevant keys. memcache.flush_all() redirect_url = '/guide/edit/' + str(key.id()) return self.redirect(redirect_url)
def get(self, path, feature_id=None): user = users.get_current_user() if user is None: if feature_id: # Redirect to public URL for unauthenticated users. return self.redirect(self.DEFAULT_URL + '/' + feature_id) else: return self.redirect(users.create_login_url(self.request.uri)) # Remove trailing slash from URL and redirect. e.g. /metrics/ -> /metrics if path[-1] == '/': return self.redirect(self.request.path.rstrip('/')) # TODO(ericbidelman): This creates a additional call to # _is_user_whitelisted() (also called in common.py), resulting in another # db query. if not self._is_user_whitelisted(user): #TODO(ericbidelman): Use render(status=401) instead. #self.render(data={}, template_path=os.path.join(path + '.html'), status=401) common.handle_401(self.request, self.response, Exception) return if not feature_id and not 'new' in path: # /features/edit|launch -> /features/new return self.redirect(self.ADD_NEW_URL) elif feature_id and 'new' in path: return self.redirect(self.ADD_NEW_URL) template_data = {'feature_form': models.FeatureForm()} if feature_id: f = models.Feature.get_by_id(long(feature_id)) if f is None: return self.redirect(self.ADD_NEW_URL) # Provide new or populated form to template. template_data.update({ 'feature': f.format_for_template(), 'feature_form': models.FeatureForm(f.format_for_edit()), 'default_url': '%s://%s%s/%s' % (self.request.scheme, self.request.host, self.DEFAULT_URL, feature_id), 'edit_url': '%s://%s%s/%s' % (self.request.scheme, self.request.host, self.EDIT_URL, feature_id) }) if self.LAUNCH_PARAM in self.request.params: template_data[self.LAUNCH_PARAM] = True if self.INTENT_PARAM in self.request.params: template_data[self.INTENT_PARAM] = True self._add_common_template_values(template_data) self.render(data=template_data, template_path=os.path.join(path + '.html'))
def get(self, path, feature_id=None): user = users.get_current_user() if user is None: if feature_id: # Redirect to public URL for unauthenticated users. return self.redirect(self.DEFAULT_URL + '/' + feature_id) else: return self.redirect(users.create_login_url(self.request.uri)) # Remove trailing slash from URL and redirect. e.g. /metrics/ -> /metrics if path[-1] == '/': return self.redirect(self.request.path.rstrip('/')) # TODO(ericbidelman): This creates a additional call to # _is_user_whitelisted() (also called in common.py), resulting in another # db query. if not self._is_user_whitelisted(user): #TODO(ericbidelman): Use render(status=401) instead. #self.render(data={}, template_path=os.path.join(path + '.html'), status=401) common.handle_401(self.request, self.response, Exception) return if not feature_id and not 'new' in path: # /features/edit|launch -> /features/new return self.redirect(self.ADD_NEW_URL) elif feature_id and 'new' in path: return self.redirect(self.ADD_NEW_URL) feature = None template_data = { 'feature_form': models.FeatureForm() } if feature_id: f = models.Feature.get_by_id(long(feature_id)) if f is None: return self.redirect(self.ADD_NEW_URL) # Provide new or populated form to template. template_data.update({ 'feature': f.format_for_template(), 'feature_form': models.FeatureForm(f.format_for_edit()), 'default_url': '%s://%s%s/%s' % (self.request.scheme, self.request.host, self.DEFAULT_URL, feature_id), 'edit_url': '%s://%s%s/%s' % (self.request.scheme, self.request.host, self.EDIT_URL, feature_id) }) if self.LAUNCH_PARAM in self.request.params: template_data[self.LAUNCH_PARAM] = True if self.INTENT_PARAM in self.request.params: template_data[self.INTENT_PARAM] = True self._add_common_template_values(template_data) self.render(data=template_data, template_path=os.path.join(path + '.html'))
def get(self, path): user = users.get_current_user() if user is None: return self.redirect(users.create_login_url(self.request.uri)) if not self.user_can_edit(user): common.handle_401(self.request, self.response, Exception) return template_data = { 'overview_form': guideforms.NewFeatureForm(), } self._add_common_template_values(template_data) self.render(data=template_data, template_path=os.path.join(path + '.html'))
def get(self, path, feature_id, stage_id): stage_id = int(stage_id) user = users.get_current_user() if user is None: # Redirect to public URL for unauthenticated users. return self.redirect(format_feature_url(feature_id)) if not self.user_can_edit(user): common.handle_401(self.request, self.response, Exception) return f = models.Feature.get_by_id(long(feature_id)) if f is None: self.abort(404) feature_process = processes.ALL_PROCESSES.get( f.feature_type, processes.BLINK_LAUNCH_PROCESS) stage_name = '' for stage in feature_process.stages: if stage.outgoing_stage == stage_id: stage_name = stage.name template_data = { 'stage_name': stage_name, 'stage_id': stage_id, } # TODO(jrobbins): show useful error if stage not found. detail_form_class = STAGE_FORMS[f.feature_type][stage_id] # Provide new or populated form to template. template_data.update({ 'feature': f, 'feature_id': f.key().id, 'feature_form': detail_form_class(f.format_for_edit()), }) if self.LAUNCH_PARAM in self.request.params: template_data[self.LAUNCH_PARAM] = True if self.INTENT_PARAM in self.request.params: template_data[self.INTENT_PARAM] = True self._add_common_template_values(template_data) self.render(data=template_data, template_path=os.path.join(path + '.html'))
def post(self, path, feature_id=None): user = users.get_current_user() if user is None or (user and not self.user_can_edit(user)): common.handle_401(self.request, self.response, Exception) return spec_link = self.__FullQualifyLink('spec_link') explainer_links = self.request.get('explainer_links') or [] if explainer_links: explainer_links = filter(bool, [x.strip() for x in re.split('\\r?\\n', explainer_links)]) bug_url = self.__FullQualifyLink('bug_url') launch_bug_url = self.__FullQualifyLink('launch_bug_url') initial_public_proposal_url = self.__FullQualifyLink( 'initial_public_proposal_url') intent_to_implement_url = self.__FullQualifyLink('intent_to_implement_url') origin_trial_feedback_url = self.__FullQualifyLink('origin_trial_feedback_url') ff_views_link = self.__FullQualifyLink('ff_views_link') ie_views_link = self.__FullQualifyLink('ie_views_link') safari_views_link = self.__FullQualifyLink('safari_views_link') web_dev_views_link = self.__FullQualifyLink('web_dev_views_link') # Cast incoming milestones to ints. shipped_milestone = self.__ToInt('shipped_milestone') shipped_android_milestone = self.__ToInt('shipped_android_milestone') shipped_ios_milestone = self.__ToInt('shipped_ios_milestone') shipped_webview_milestone = self.__ToInt('shipped_webview_milestone') shipped_opera_milestone = self.__ToInt('shipped_opera_milestone') shipped_opera_android_milestone = self.__ToInt('shipped_opera_android_milestone') owners = self.request.get('owner') or [] if owners: owners = [db.Email(x.strip()) for x in owners.split(',')] doc_links = self.request.get('doc_links') or [] if doc_links: doc_links = filter(bool, [x.strip() for x in re.split('\\r?\\n', doc_links)]) sample_links = self.request.get('sample_links') or [] if sample_links: sample_links = filter(bool, [x.strip() for x in re.split('\\r?\\n', sample_links)]) search_tags = self.request.get('search_tags') or [] if search_tags: search_tags = filter(bool, [x.strip() for x in search_tags.split(',')]) blink_components = self.request.get('blink_components') or models.BlinkComponent.DEFAULT_COMPONENT if blink_components: blink_components = filter(bool, [x.strip() for x in blink_components.split(',')]) devrel = self.request.get('devrel') or [] if devrel: devrel = [db.Email(x.strip()) for x in devrel.split(',')] try: intent_stage = int(self.request.get('intent_stage')) except: logging.error('Invalid intent_stage \'{}\'' \ .format(self.request.get('intent_stage'))) # Default the intent stage to 1 (Prototype) if we failed to get a valid # intent stage from the request. This should be removed once we # understand what causes this. intent_stage = 1 if feature_id: # /admin/edit/1234 feature = models.Feature.get_by_id(long(feature_id)) if feature is None: return self.redirect(self.request.path) if 'delete' in path: feature.delete() memcache.flush_all() return # Bomb out early for AJAX delete. No need to redirect. # Update properties of existing feature. feature.category = int(self.request.get('category')) feature.name = self.request.get('name') feature.intent_stage = intent_stage feature.summary = self.request.get('summary') feature.unlisted = self.request.get('unlisted') == 'on' feature.intent_to_implement_url = intent_to_implement_url feature.origin_trial_feedback_url = origin_trial_feedback_url feature.motivation = self.request.get('motivation') feature.explainer_links = explainer_links feature.owner = owners feature.bug_url = bug_url feature.launch_bug_url = launch_bug_url feature.initial_public_proposal_url = initial_public_proposal_url feature.blink_components = blink_components feature.devrel = devrel feature.impl_status_chrome = int(self.request.get('impl_status_chrome')) feature.shipped_milestone = shipped_milestone feature.shipped_android_milestone = shipped_android_milestone feature.shipped_ios_milestone = shipped_ios_milestone feature.shipped_webview_milestone = shipped_webview_milestone feature.shipped_opera_milestone = shipped_opera_milestone feature.shipped_opera_android_milestone = shipped_opera_android_milestone feature.footprint = int(self.request.get('footprint')) feature.interop_compat_risks = self.request.get('interop_compat_risks') feature.ergonomics_risks = self.request.get('ergonomics_risks') feature.activation_risks = self.request.get('activation_risks') feature.security_risks = self.request.get('security_risks') feature.debuggability = self.request.get('debuggability') feature.all_platforms = self.request.get('all_platforms') == 'on' feature.all_platforms_descr = self.request.get('all_platforms_descr') feature.wpt = self.request.get('wpt') == 'on' feature.wpt_descr = self.request.get('wpt_descr') feature.ff_views = int(self.request.get('ff_views')) feature.ff_views_link = ff_views_link feature.ff_views_notes = self.request.get('ff_views_notes') feature.ie_views = int(self.request.get('ie_views')) feature.ie_views_link = ie_views_link feature.ie_views_notes = self.request.get('ie_views_notes') feature.safari_views = int(self.request.get('safari_views')) feature.safari_views_link = safari_views_link feature.safari_views_notes = self.request.get('safari_views_notes') feature.web_dev_views = int(self.request.get('web_dev_views')) feature.web_dev_views_link = web_dev_views_link feature.web_dev_views_notes = self.request.get('web_dev_views_notes') feature.prefixed = self.request.get('prefixed') == 'on' feature.spec_link = spec_link feature.tag_review = self.request.get('tag_review') feature.standardization = int(self.request.get('standardization')) feature.doc_links = doc_links feature.sample_links = sample_links feature.search_tags = search_tags feature.comments = self.request.get('comments') feature.experiment_goals = self.request.get('experiment_goals') feature.experiment_timeline = self.request.get('experiment_timeline') feature.experiment_risks = self.request.get('experiment_risks') feature.experiment_extension_reason = self.request.get('experiment_extension_reason') feature.ongoing_constraints = self.request.get('ongoing_constraints') else: # Check bug for existing blink component(s) used to label the bug. If # found, use the first component name instead of the generic "Blink" name. try: blink_components = self.__get_blink_component_from_bug(blink_components, bug_url) except Exception: pass feature = models.Feature( category=int(self.request.get('category')), name=self.request.get('name'), intent_stage=intent_stage, summary=self.request.get('summary'), intent_to_implement_url=intent_to_implement_url, origin_trial_feedback_url=origin_trial_feedback_url, motivation=self.request.get('motivation'), explainer_links=explainer_links, owner=owners, bug_url=bug_url, launch_bug_url=launch_bug_url, initial_public_proposal_url=initial_public_proposal_url, blink_components=blink_components, devrel=devrel, impl_status_chrome=int(self.request.get('impl_status_chrome')), shipped_milestone=shipped_milestone, shipped_android_milestone=shipped_android_milestone, shipped_ios_milestone=shipped_ios_milestone, shipped_webview_milestone=shipped_webview_milestone, shipped_opera_milestone=shipped_opera_milestone, shipped_opera_android_milestone=shipped_opera_android_milestone, interop_compat_risks=self.request.get('interop_compat_risks'), ergonomics_risks=self.request.get('ergonomics_risks'), activation_risks=self.request.get('activation_risks'), security_risks=self.request.get('security_risks'), debuggability=self.request.get('debuggability'), all_platforms=self.request.get('all_platforms') == 'on', all_platforms_descr=self.request.get('all_platforms_descr'), wpt=self.request.get('wpt') == 'on', wpt_descr=self.request.get('wpt_descr'), footprint=int(self.request.get('footprint')), ff_views=int(self.request.get('ff_views')), ff_views_link=ff_views_link, ff_views_notes=self.request.get('ff_views_notes'), ie_views=int(self.request.get('ie_views')), ie_views_link=ie_views_link, ie_views_notes=self.request.get('ie_views_notes'), safari_views=int(self.request.get('safari_views')), safari_views_link=safari_views_link, safari_views_notes=self.request.get('safari_views_notes'), web_dev_views=int(self.request.get('web_dev_views')), web_dev_views_link=web_dev_views_link, web_dev_views_notes=self.request.get('web_dev_views_notes'), prefixed=self.request.get('prefixed') == 'on', spec_link=spec_link, tag_review=self.request.get('tag_review'), standardization=int(self.request.get('standardization')), doc_links=doc_links, sample_links=sample_links, search_tags=search_tags, comments=self.request.get('comments'), experiment_goals=self.request.get('experiment_goals'), experiment_timeline=self.request.get('experiment_timeline'), experiment_risks=self.request.get('experiment_risks'), experiment_extension_reason=self.request.get('experiment_extension_reason'), ongoing_constraints=self.request.get('ongoing_constraints'), ) params = [] if self.request.get('create_launch_bug') == 'on': params.append(self.LAUNCH_PARAM) if self.request.get('intent_to_implement') == 'on': params.append(self.INTENT_PARAM) feature.intent_template_use_count += 1 key = feature.put() # TODO(ericbidelman): enumerate and remove only the relevant keys. memcache.flush_all() redirect_url = '/feature/' + str(key.id()) if len(params): redirect_url = '%s/%s?%s' % (self.LAUNCH_URL, key.id(), '&'.join(params)) return self.redirect(redirect_url)
def post(self, path, feature_id=None): user = users.get_current_user() if user is None or (user and not self._is_user_whitelisted(user)): common.handle_401(self.request, self.response, Exception) return spec_link = self.__FullQualifyLink('spec_link') bug_url = self.__FullQualifyLink('bug_url') ff_views_link = self.__FullQualifyLink('ff_views_link') ie_views_link = self.__FullQualifyLink('ie_views_link') safari_views_link = self.__FullQualifyLink('safari_views_link') # Cast incoming milestones to ints. shipped_milestone = self.__ToInt('shipped_milestone') shipped_android_milestone = self.__ToInt('shipped_android_milestone') shipped_ios_milestone = self.__ToInt('shipped_ios_milestone') shipped_webview_milestone = self.__ToInt('shipped_webview_milestone') shipped_opera_milestone = self.__ToInt('shipped_opera_milestone') shipped_opera_android_milestone = self.__ToInt('shipped_opera_android_milestone') owners = self.request.get('owner') or [] if owners: owners = [db.Email(x.strip()) for x in owners.split(',')] doc_links = self.request.get('doc_links') or [] if doc_links: doc_links = filter(bool, [x.strip() for x in re.split('\\r?\\n', doc_links)]) sample_links = self.request.get('sample_links') or [] if sample_links: sample_links = filter(bool, [x.strip() for x in re.split('\\r?\\n', sample_links)]) search_tags = self.request.get('search_tags') or [] if search_tags: search_tags = filter(bool, [x.strip() for x in search_tags.split(',')]) blink_components = self.request.get('blink_components') or models.BlinkComponent.DEFAULT_COMPONENT if blink_components: blink_components = filter(bool, [x.strip() for x in blink_components.split(',')]) if feature_id: # /admin/edit/1234 feature = models.Feature.get_by_id(long(feature_id)) if feature is None: return self.redirect(self.request.path) if 'delete' in path: feature.delete() memcache.flush_all() return # Bomb out early for AJAX delete. No need to redirect. # Update properties of existing feature. feature.category = int(self.request.get('category')) feature.name = self.request.get('name') feature.summary = self.request.get('summary') feature.owner = owners feature.bug_url = bug_url feature.blink_components = blink_components feature.impl_status_chrome = int(self.request.get('impl_status_chrome')) feature.shipped_milestone = shipped_milestone feature.shipped_android_milestone = shipped_android_milestone feature.shipped_ios_milestone = shipped_ios_milestone feature.shipped_webview_milestone = shipped_webview_milestone feature.shipped_opera_milestone = shipped_opera_milestone feature.shipped_opera_android_milestone = shipped_opera_android_milestone feature.footprint = int(self.request.get('footprint')) feature.visibility = int(self.request.get('visibility')) feature.ff_views = int(self.request.get('ff_views')) feature.ff_views_link = ff_views_link feature.ie_views = int(self.request.get('ie_views')) feature.ie_views_link = ie_views_link feature.safari_views = int(self.request.get('safari_views')) feature.safari_views_link = safari_views_link feature.prefixed = self.request.get('prefixed') == 'on' feature.spec_link = spec_link feature.standardization = int(self.request.get('standardization')) feature.comments = self.request.get('comments') feature.web_dev_views = int(self.request.get('web_dev_views')) feature.doc_links = doc_links feature.sample_links = sample_links feature.search_tags = search_tags else: # Check bug for existing blink component(s) used to label the bug. If # found, use the first component name instead of the generic "Blink" name. try: blink_components = self.__get_blink_component_from_bug(blink_components, bug_url) except Exception: pass feature = models.Feature( category=int(self.request.get('category')), name=self.request.get('name'), summary=self.request.get('summary'), owner=owners, bug_url=bug_url, blink_components=blink_components, impl_status_chrome=int(self.request.get('impl_status_chrome')), shipped_milestone=shipped_milestone, shipped_android_milestone=shipped_android_milestone, shipped_ios_milestone=shipped_ios_milestone, shipped_webview_milestone=shipped_webview_milestone, shipped_opera_milestone=shipped_opera_milestone, shipped_opera_android_milestone=shipped_opera_android_milestone, footprint=int(self.request.get('footprint')), visibility=int(self.request.get('visibility')), ff_views=int(self.request.get('ff_views')), ff_views_link=ff_views_link, ie_views=int(self.request.get('ie_views')), ie_views_link=ie_views_link, safari_views=int(self.request.get('safari_views')), safari_views_link=safari_views_link, prefixed=self.request.get('prefixed') == 'on', spec_link=spec_link, standardization=int(self.request.get('standardization')), comments=self.request.get('comments'), web_dev_views=int(self.request.get('web_dev_views')), doc_links=doc_links, sample_links=sample_links, search_tags=search_tags, ) key = feature.put() # TODO(ericbidelman): enumerate and remove only the relevant keys. memcache.flush_all() params = [] if self.request.get('create_launch_bug') == 'on': params.append(self.LAUNCH_PARAM) if self.request.get('intent_to_implement') == 'on': params.append(self.INTENT_PARAM) redirect_url = '/feature/' + str(key.id()) if len(params): redirect_url = '%s/%s?%s' % (self.LAUNCH_URL, key.id(), '&'.join(params)) return self.redirect(redirect_url)
def post(self, path, feature_id=None): user = users.get_current_user() if user is None or (user and not self._is_user_whitelisted(user)): common.handle_401(self.request, self.response, Exception) return spec_link = self.__FullQualifyLink('spec_link') explainer_links = self.request.get('explainer_links') or [] if explainer_links: explainer_links = filter(bool, [x.strip() for x in re.split('\\r?\\n', explainer_links)]) bug_url = self.__FullQualifyLink('bug_url') intent_to_implement_url = self.__FullQualifyLink('intent_to_implement_url') origin_trial_feedback_url = self.__FullQualifyLink('origin_trial_feedback_url') ff_views_link = self.__FullQualifyLink('ff_views_link') ie_views_link = self.__FullQualifyLink('ie_views_link') safari_views_link = self.__FullQualifyLink('safari_views_link') web_dev_views_link = self.__FullQualifyLink('web_dev_views_link') # Cast incoming milestones to ints. shipped_milestone = self.__ToInt('shipped_milestone') shipped_android_milestone = self.__ToInt('shipped_android_milestone') shipped_ios_milestone = self.__ToInt('shipped_ios_milestone') shipped_webview_milestone = self.__ToInt('shipped_webview_milestone') shipped_opera_milestone = self.__ToInt('shipped_opera_milestone') shipped_opera_android_milestone = self.__ToInt('shipped_opera_android_milestone') owners = self.request.get('owner') or [] if owners: owners = [db.Email(x.strip()) for x in owners.split(',')] doc_links = self.request.get('doc_links') or [] if doc_links: doc_links = filter(bool, [x.strip() for x in re.split('\\r?\\n', doc_links)]) sample_links = self.request.get('sample_links') or [] if sample_links: sample_links = filter(bool, [x.strip() for x in re.split('\\r?\\n', sample_links)]) search_tags = self.request.get('search_tags') or [] if search_tags: search_tags = filter(bool, [x.strip() for x in search_tags.split(',')]) blink_components = self.request.get('blink_components') or models.BlinkComponent.DEFAULT_COMPONENT if blink_components: blink_components = filter(bool, [x.strip() for x in blink_components.split(',')]) try: intent_stage = int(self.request.get('intent_stage')) except: logging.error('Invalid intent_stage \'{}\'' \ .format(self.request.get('intent_stage'))) # Default the intent stage to 1 (Implement) if we failed to get a valid # intent stage from the request. This should be removed once we # understand what causes this. intent_stage = 1 if feature_id: # /admin/edit/1234 feature = models.Feature.get_by_id(long(feature_id)) if feature is None: return self.redirect(self.request.path) if 'delete' in path: feature.delete() memcache.flush_all() return # Bomb out early for AJAX delete. No need to redirect. # Update properties of existing feature. feature.category = int(self.request.get('category')) feature.name = self.request.get('name') feature.intent_stage = intent_stage feature.summary = self.request.get('summary') feature.intent_to_implement_url = intent_to_implement_url feature.origin_trial_feedback_url = origin_trial_feedback_url feature.motivation = self.request.get('motivation') feature.explainer_links = explainer_links feature.owner = owners feature.bug_url = bug_url feature.blink_components = blink_components feature.impl_status_chrome = int(self.request.get('impl_status_chrome')) feature.shipped_milestone = shipped_milestone feature.shipped_android_milestone = shipped_android_milestone feature.shipped_ios_milestone = shipped_ios_milestone feature.shipped_webview_milestone = shipped_webview_milestone feature.shipped_opera_milestone = shipped_opera_milestone feature.shipped_opera_android_milestone = shipped_opera_android_milestone feature.footprint = int(self.request.get('footprint')) feature.interop_compat_risks = self.request.get('interop_compat_risks') feature.ergonomics_risks = self.request.get('ergonomics_risks') feature.activation_risks = self.request.get('activation_risks') feature.security_risks = self.request.get('security_risks') feature.debuggability = self.request.get('debuggability') feature.all_platforms = self.request.get('all_platforms') == 'on' feature.all_platforms_descr = self.request.get('all_platforms_descr') feature.wpt = self.request.get('wpt') == 'on' feature.wpt_descr = self.request.get('wpt_descr') feature.visibility = int(self.request.get('visibility')) feature.ff_views = int(self.request.get('ff_views')) feature.ff_views_link = ff_views_link feature.ff_views_notes = self.request.get('ff_views_notes') feature.ie_views = int(self.request.get('ie_views')) feature.ie_views_link = ie_views_link feature.ie_views_notes = self.request.get('ie_views_notes') feature.safari_views = int(self.request.get('safari_views')) feature.safari_views_link = safari_views_link feature.safari_views_notes = self.request.get('safari_views_notes') feature.web_dev_views = int(self.request.get('web_dev_views')) feature.web_dev_views_link = web_dev_views_link feature.web_dev_views_notes = self.request.get('web_dev_views_notes') feature.prefixed = self.request.get('prefixed') == 'on' feature.spec_link = spec_link feature.tag_review = self.request.get('tag_review') feature.standardization = int(self.request.get('standardization')) feature.doc_links = doc_links feature.sample_links = sample_links feature.search_tags = search_tags feature.comments = self.request.get('comments') feature.experiment_goal = self.request.get('experiment_goal') feature.experiment_timeline = self.request.get('experiment_timeline') feature.experiment_risks = self.request.get('experiment_risks') feature.experiment_extension_reason = self.request.get('experiment_extension_reason') feature.ongoing_constraints = self.request.get('ongoing_constraints') else: # Check bug for existing blink component(s) used to label the bug. If # found, use the first component name instead of the generic "Blink" name. try: blink_components = self.__get_blink_component_from_bug(blink_components, bug_url) except Exception: pass feature = models.Feature( category=int(self.request.get('category')), name=self.request.get('name'), intent_stage=intent_stage, summary=self.request.get('summary'), intent_to_implement_url=intent_to_implement_url, origin_trial_feedback_url=origin_trial_feedback_url, motivation=self.request.get('motivation'), explainer_links=explainer_links, owner=owners, bug_url=bug_url, blink_components=blink_components, impl_status_chrome=int(self.request.get('impl_status_chrome')), shipped_milestone=shipped_milestone, shipped_android_milestone=shipped_android_milestone, shipped_ios_milestone=shipped_ios_milestone, shipped_webview_milestone=shipped_webview_milestone, shipped_opera_milestone=shipped_opera_milestone, shipped_opera_android_milestone=shipped_opera_android_milestone, interop_compat_risks=self.request.get('interop_compat_risks'), ergonomics_risks=self.request.get('ergonomics_risks'), activation_risks=self.request.get('activation_risks'), security_risks=self.request.get('security_risks'), debuggability=self.request.get('debuggability'), all_platforms=self.request.get('all_platforms') == 'on', all_platforms_descr=self.request.get('all_platforms_descr'), wpt=self.request.get('wpt') == 'on', wpt_descr=self.request.get('wpt_descr'), footprint=int(self.request.get('footprint')), visibility=int(self.request.get('visibility')), ff_views=int(self.request.get('ff_views')), ff_views_link=ff_views_link, ff_views_notes=self.request.get('ff_views_notes'), ie_views=int(self.request.get('ie_views')), ie_views_link=ie_views_link, ie_views_notes=self.request.get('ie_views_notes'), safari_views=int(self.request.get('safari_views')), safari_views_link=safari_views_link, safari_views_notes=self.request.get('safari_views_notes'), web_dev_views=int(self.request.get('web_dev_views')), web_dev_views_link=web_dev_views_link, web_dev_views_notes=self.request.get('web_dev_views_notes'), prefixed=self.request.get('prefixed') == 'on', spec_link=spec_link, tag_review=self.request.get('tag_review'), standardization=int(self.request.get('standardization')), doc_links=doc_links, sample_links=sample_links, search_tags=search_tags, comments=self.request.get('comments'), experiment_goal=self.request.get('experiment_goal'), experiment_timeline=self.request.get('experiment_timeline'), experiment_risks=self.request.get('experiment_risks'), experiment_extension_reason=self.request.get('experiment_extension_reason'), ongoing_constraints=self.request.get('ongoing_constraints'), ) key = feature.put() # TODO(ericbidelman): enumerate and remove only the relevant keys. memcache.flush_all() params = [] if self.request.get('create_launch_bug') == 'on': params.append(self.LAUNCH_PARAM) if self.request.get('intent_to_implement') == 'on': params.append(self.INTENT_PARAM) redirect_url = '/feature/' + str(key.id()) if len(params): redirect_url = '%s/%s?%s' % (self.LAUNCH_URL, key.id(), '&'.join(params)) return self.redirect(redirect_url)
def post(self, path, feature_id, stage_id): user = users.get_current_user() if user is None or (user and not self.user_can_edit(user)): common.handle_401(self.request, self.response, Exception) return if feature_id: feature = models.Feature.get_by_id(long(feature_id)) if feature is None: self.abort(404) stage_id = int(stage_id) logging.info('POST is %r', self.request.POST) if self.touched('spec_link'): feature.spec_link = self.parse_link('spec_link') if self.touched('initial_public_proposal_url'): feature.initial_public_proposal_url = self.parse_link( 'initial_public_proposal_url') if self.touched('explainer_links'): feature.explainer_links = self.split_input('explainer_links') if self.touched('bug_url'): feature.bug_url = self.parse_link('bug_url') if self.touched('launch_bug_url'): feature.launch_bug_url = self.parse_link('launch_bug_url') if self.touched('intent_to_implement_url'): feature.intent_to_implement_url = self.parse_link( 'intent_to_implement_url') if self.touched('origin_trial_feedback_url'): feature.origin_trial_feedback_url = self.parse_link( 'origin_trial_feedback_url') # Cast incoming milestones to ints. # TODO(jrobbins): Consider supporting milestones that are not ints. if self.touched('shipped_milestone = self'): feature.shipped_milestone = self.parse_int('shipped_milestone') if self.touched('shipped_android_milestone'): feature.shipped_android_milestone = self.parse_int( 'shipped_android_milestone') if self.touched('shipped_ios_milestone'): feature.shipped_ios_milestone = self.parse_int('shipped_ios_milestone') if self.touched('shipped_webview_milestone'): feature.shipped_webview_milestone = self.parse_int( 'shipped_webview_milestone') if self.touched('shipped_opera_milestone'): feature.shipped_opera_milestone = self.parse_int('shipped_opera_milestone') if self.touched('shipped_opera_android'): feature.shipped_opera_android_milestone = self.parse_int( 'shipped_opera_android_milestone') if self.touched('owner'): owner_addrs = self.split_input('owner', delim=',') feature.owner = [db.Email(addr) for addr in owner_addrs] if self.touched('doc_links'): feature.doc_links = self.split_input('doc_links') if self.touched('sample_links'): feature.sample_links = self.split_input('sample_links') if self.touched('search_tags'): feature.search_tags = self.split_input('search_tags', delim=',') if self.touched('blink_components'): feature.blink_components = ( self.split_input('blink_components', delim=',') or [models.BlinkComponent.DEFAULT_COMPONENT]) if self.touched('devrel'): devrel_addrs = self.split_input('devrel', delim=',') feature.devrel = [db.Email(addr) for addr in devrel_addrs] if self.touched('feature_type'): feature.feature_type = int(self.request.get('feature_type')) if self.touched('intent_stage'): feature.intent_stage = int(self.request.get('intent_stage')) elif self.request.get('set_stage') == 'on': feature.intent_stage = stage_id if self.touched('category'): feature.category = int(self.request.get('category')) if self.touched('name'): feature.name = self.request.get('name') if self.touched('summary'): feature.summary = self.request.get('summary') if self.touched('motivation'): feature.motivation = self.request.get('motivation') if self.touched('impl_status_chrome'): feature.impl_status_chrome = int(self.request.get('impl_status_chrome')) if self.touched('footprint'): feature.footprint = int(self.request.get('footprint')) if self.touched('interop_compat_risks'): feature.interop_compat_risks = self.request.get('interop_compat_risks') if self.touched('ergonomics_risks'): feature.ergonomics_risks = self.request.get('ergonomics_risks') if self.touched('activation_risks'): feature.activation_risks = self.request.get('activation_risks') if self.touched('security_risks'): feature.security_risks = self.request.get('security_risks') if self.touched('debuggability'): feature.debuggability = self.request.get('debuggability') if self.touched('all_platforms'): feature.all_platforms = self.request.get('all_platforms') == 'on' if self.touched('all_platforms_descr'): feature.all_platforms_descr = self.request.get('all_platforms_descr') if self.touched('wpt'): feature.wpt = self.request.get('wpt') == 'on' if self.touched('wpt_descr'): feature.wpt_descr = self.request.get('wpt_descr') if self.touched('ff_views'): feature.ff_views = int(self.request.get('ff_views')) if self.touched('ff_views_link'): feature.ff_views_link = self.parse_link('ff_views_link') if self.touched('ff_views_notes'): feature.ff_views_notes = self.request.get('ff_views_notes') if self.touched('ie_views'): feature.ie_views = int(self.request.get('ie_views')) if self.touched('ie_views_link'): feature.ie_views_link = self.parse_link('ie_views_link') if self.touched('ie_views_notes'): feature.ie_views_notes = self.request.get('ie_views_notes') if self.touched('safari_views'): feature.safari_views = int(self.request.get('safari_views')) if self.touched('safari_views_link'): feature.safari_views_link = self.parse_link('safari_views_link') if self.touched('safari_views_notes'): feature.safari_views_notes = self.request.get('safari_views_notes') if self.touched('web_dev_views'): feature.web_dev_views = int(self.request.get('web_dev_views')) if self.touched('web_dev_views'): feature.web_dev_views_link = self.parse_link('web_dev_views_link') if self.touched('web_dev_views_notes'): feature.web_dev_views_notes = self.request.get('web_dev_views_notes') if self.touched('prefixed'): feature.prefixed = self.request.get('prefixed') == 'on' if self.touched('tag_review'): feature.tag_review = self.request.get('tag_review') if self.touched('standardization'): feature.standardization = int(self.request.get('standardization')) if self.touched('unlisted'): feature.unlisted = self.request.get('unlisted') == 'on' if self.touched('comments'): feature.comments = self.request.get('comments') if self.touched('experiment_goals'): feature.experiment_goals = self.request.get('experiment_goals') if self.touched('experiment_timeline'): feature.experiment_timeline = self.request.get('experiment_timeline') if self.touched('experiment_risks'): feature.experiment_risks = self.request.get('experiment_risks') if self.touched('experiment_extension_reason'): feature.experiment_extension_reason = self.request.get( 'experiment_extension_reason') if self.touched('ongoing_constraints'): feature.ongoing_constraints = self.request.get('ongoing_constraints') params = [] if self.request.get('create_launch_bug') == 'on': params.append(self.LAUNCH_PARAM) if self.request.get('intent_to_implement') == 'on': params.append(self.INTENT_PARAM) feature.intent_template_use_count += 1 key = feature.put() # TODO(jrobbins): enumerate and remove only the relevant keys. memcache.flush_all() redirect_url = '/guide/edit/' + str(key.id()) if len(params): redirect_url = '%s/%s?%s' % (self.LAUNCH_URL, key.id(), '&'.join(params)) return self.redirect(redirect_url)