Create new creator field for features (#2034)

* add creator field

* cron job to add creator field

* changes suggested by @jrobbins

* add logging
This commit is contained in:
Daniel Smith 2022-07-20 09:43:19 -07:00 коммит произвёл GitHub
Родитель 6bc5ebb3c4
Коммит 8ee81f5d82
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
6 изменённых файлов: 46 добавлений и 5 удалений

Просмотреть файл

@ -14,3 +14,6 @@ cron:
- description: Trigger a DataStore export for backup.
url: /cron/export_backup
schedule: every day 03:00
- description: Writes string creator field from created_by user field.
url: /cron/write_creator
schedule: 1 of month 03:00

Просмотреть файл

@ -77,6 +77,7 @@ class PermissionFunctionTests(testing_config.CustomTestCase):
# Feature for checking permissions against
self.feature_1 = models.Feature(
name='feature one', summary='sum',
creator="feature_creator@example.com",
owner=['feature_owner@example.com'],
editors=['feature_editor@example.com'], category=1, visibility=1,
standardization=1, web_dev_views=1, impl_status_chrome=1)
@ -130,7 +131,7 @@ class PermissionFunctionTests(testing_config.CustomTestCase):
def check_function_results_with_feature(
self, func, additional_args, unregistered='missing',
registered='missing', feature_owner='missing', feature_editor='missing',
site_editor='missing', admin='missing'):
creator='missing', site_editor='missing', admin='missing'):
"""Test func in the context of a specific feature id."""
# Test unregistered users
testing_config.sign_in('unregistered@example.com', 123)
@ -152,6 +153,11 @@ class PermissionFunctionTests(testing_config.CustomTestCase):
user = users.get_current_user()
self.assertEqual(feature_editor, func(user, *additional_args))
# Test feature editors
testing_config.sign_in('feature_creator@example.com', 123)
user = users.get_current_user()
self.assertEqual(creator, func(user, *additional_args))
# Test site editor user
testing_config.sign_in('editor@example.com', 123)
user = users.get_current_user()
@ -178,7 +184,7 @@ class PermissionFunctionTests(testing_config.CustomTestCase):
permissions.can_view_feature, (self.feature_id,),
unregistered=True, registered=True,
feature_owner=True, feature_editor=True,
site_editor=True, admin=True
creator=True, site_editor=True, admin=True
)
def test_can_create_feature(self):
@ -204,7 +210,7 @@ class PermissionFunctionTests(testing_config.CustomTestCase):
permissions.can_edit_feature, (self.feature_id,),
unregistered=False, registered=True,
feature_owner=True, feature_editor=True,
site_editor=True, admin=True
creator=False, site_editor=True, admin=True
)
def test_can_approve_feature(self):

Просмотреть файл

@ -634,6 +634,7 @@ class Feature(DictModel):
}
d['tags'] = d.pop('search_tags', [])
d['editors'] = d.pop('editors', [])
d['creator'] = d.pop('creator', None)
d['browsers'] = {
'chrome': {
'bug': d.pop('bug_url', None),
@ -786,7 +787,8 @@ class Feature(DictModel):
# This includes being an owner, editor, or the original creator
# of the feature.
query = query.filter(
ndb.OR(Feature.owner == comparator, Feature.editors == comparator))
ndb.OR(Feature.owner == comparator, Feature.editors == comparator,
Feature.creator == comparator))
else:
query = query.filter(getattr(Feature, filter_type) == comparator)
@ -899,7 +901,8 @@ class Feature(DictModel):
# Owners and editors of a feature should still be able to see their features.
if ((not f.get('unlisted', False)) or
('browsers' in f and email in f['browsers']['chrome']['owners']) or
(email in f.get('editors', []))):
(email in f.get('editors', [])) or
(email is not None and f.get('creator') == email)):
listed_features.append(f)
return listed_features
@ -1257,6 +1260,7 @@ class Feature(DictModel):
# General info.
category = ndb.IntegerProperty(required=True)
creator = ndb.StringProperty()
name = ndb.StringProperty(required=True)
feature_type = ndb.IntegerProperty(default=FEATURE_TYPE_INCUBATE_ID)
intent_stage = ndb.IntegerProperty(default=0)
@ -1401,6 +1405,7 @@ QUERIABLE_FIELDS = {
'star_count': Feature.star_count,
'tags': Feature.search_tags,
'owner': Feature.owner,
'creator': Feature.creator,
'browsers.chrome.owners': Feature.owner,
'editors': Feature.editors,
'intent_to_implement_url': Feature.intent_to_implement_url,

Просмотреть файл

@ -0,0 +1,24 @@
import logging
from framework.basehandlers import FlaskHandler
from internals.models import Feature
class UpdateCreatorHandler(FlaskHandler):
def get_template_data():
"""Writes string creator field from created_by user field."""
q = Feature.query()
features = q.fetch()
update_count = 0
for feature in features:
if feature.created_by and not feature.creator:
update_count += 1
email = "Unknown"
if feature.created_by:
email = feature.created_by.email()
feature.creator = email
feature.put(notify=False)
logging.info(f'{update_count} features updated with new creator field.')
return 'Success'

Просмотреть файл

@ -38,6 +38,7 @@ from internals import detect_intent
from internals import fetchmetrics
from internals import notifier
from internals import data_backup
from internals import write_creator
from pages import blink_handler
from pages import featuredetail
from pages import featurelist
@ -190,6 +191,7 @@ internals_routes = [
('/cron/histograms', fetchmetrics.HistogramsHandler),
('/cron/update_blink_components', fetchmetrics.BlinkComponentHandler),
('/cron/export_backup', data_backup.BackupExportHandler),
('/cron/write_creator', write_creator.UpdateCreatorHandler),
('/tasks/email-subscribers', notifier.FeatureChangeHandler),

Просмотреть файл

@ -141,6 +141,7 @@ class FeatureNew(basehandlers.FlaskHandler):
summary=self.form.get('summary'),
owner=owners,
editors=editors,
creator=signed_in_user.email(),
impl_status_chrome=models.NO_ACTIVE_DEV,
standardization=models.EDITORS_DRAFT,
unlisted=self.form.get('unlisted') == 'on',