Skip to content

Commit 029d4bd

Browse files
stephenfinfstachura
authored andcommitted
parser: Extract and save labels
1 parent e70f54f commit 029d4bd

3 files changed

Lines changed: 123 additions & 21 deletions

File tree

‎patchwork/parser.py‎

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
from patchwork.models import CoverComment
2727
from patchwork.models import DelegationRule
2828
from patchwork.models import get_default_initial_patch_state
29+
from patchwork.models import Label
2930
from patchwork.models import Patch
3031
from patchwork.models import PatchComment
3132
from patchwork.models import Person
@@ -246,7 +247,7 @@ def _find_series_by_references(project, mail):
246247
The matching ``Series`` instance, if any
247248
"""
248249
subject = mail.get('Subject')
249-
name, prefixes = clean_subject(subject, [project.linkname])
250+
name, prefixes, _ = clean_subject(subject, [project.linkname])
250251
version = parse_version(name, prefixes)
251252

252253
msg_id = find_message_id(mail)
@@ -300,7 +301,7 @@ def _find_series_by_markers(project, mail, author):
300301
"""
301302

302303
subject = mail.get('Subject')
303-
name, prefixes = clean_subject(subject, [project.linkname])
304+
name, prefixes, _ = clean_subject(subject, [project.linkname])
304305
_, total = parse_series_marker(prefixes)
305306
version = parse_version(name, prefixes)
306307

@@ -837,6 +838,7 @@ def clean_subject(subject, drop_prefixes=None):
837838
subject = normalise_space(subject)
838839

839840
prefixes = []
841+
cleaned_prefixes = []
840842

841843
match = prefix_re.match(subject)
842844

@@ -848,14 +850,18 @@ def clean_subject(subject, drop_prefixes=None):
848850
if p.lower() not in drop_prefixes
849851
]
850852

853+
cleaned_prefixes += [
854+
p for p in split_prefixes(prefix_str) if p.lower() in drop_prefixes
855+
]
856+
851857
subject = match.group(2)
852858
match = prefix_re.match(subject)
853859

854860
subject = normalise_space(subject)
855861
if prefixes:
856862
subject = '[%s] %s' % (','.join(prefixes), subject)
857863

858-
return (subject, prefixes)
864+
return (subject, prefixes, cleaned_prefixes)
859865

860866

861867
def subject_check(subject):
@@ -1236,7 +1242,19 @@ def parse_mail(mail, list_id=None):
12361242

12371243
msgid = find_message_id(mail)
12381244
subject = mail.get('Subject')
1239-
name, prefixes = clean_subject(subject, [project.linkname])
1245+
1246+
project_labels = Label.get_project_labels(project)
1247+
project_labels_names = [label.name.lower() for label in project_labels]
1248+
name, prefixes, cleaned_prefixes = clean_subject(
1249+
subject, [project.linkname, *project_labels_names]
1250+
)
1251+
cleaned_prefixes = [prefix.lower() for prefix in cleaned_prefixes]
1252+
labels = [
1253+
label
1254+
for label in project_labels
1255+
if label.name.lower() in cleaned_prefixes
1256+
]
1257+
12401258
is_comment = subject_check(subject)
12411259
x, n = parse_series_marker(prefixes)
12421260
version = parse_version(name, prefixes)
@@ -1284,6 +1302,9 @@ def parse_mail(mail, list_id=None):
12841302
delegate=delegate,
12851303
state=find_state(mail),
12861304
)
1305+
if labels:
1306+
patch.labels.set(labels)
1307+
12871308
logger.debug('Patch saved')
12881309

12891310
for attempt in range(1, 11): # arbitrary retry count

‎patchwork/tests/unit/test_parser.py‎

Lines changed: 83 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
from patchwork.tests.utils import create_cover_comment
4242
from patchwork.tests.utils import create_patch
4343
from patchwork.tests.utils import create_patch_comment
44+
from patchwork.tests.utils import create_label
4445
from patchwork.tests.utils import create_project
4546
from patchwork.tests.utils import create_series
4647
from patchwork.tests.utils import create_series_reference
@@ -542,7 +543,7 @@ def _create_email(subject):
542543

543544
def _test_encoding(self, subject_header, parsed_subject):
544545
email = self._create_email(subject_header)
545-
name, _ = clean_subject(email.get('Subject'))
546+
name, _, _ = clean_subject(email.get('Subject'))
546547
self.assertEqual(name, parsed_subject)
547548

548549
def test_subject_ascii_encoding(self):
@@ -1106,52 +1107,61 @@ def test_tags(self):
11061107

11071108
class SubjectTest(TestCase):
11081109
def test_clean_subject(self):
1109-
self.assertEqual(clean_subject('meep'), ('meep', []))
1110-
self.assertEqual(clean_subject('Re: meep'), ('meep', []))
1111-
self.assertEqual(clean_subject('[PATCH] meep'), ('meep', []))
1110+
self.assertEqual(clean_subject('meep'), ('meep', [], []))
1111+
self.assertEqual(clean_subject('Re: meep'), ('meep', [], []))
11121112
self.assertEqual(
1113-
clean_subject('[PATCH] meep \n meep'), ('meep meep', [])
1113+
clean_subject('[PATCH] meep'), ('meep', [], ['PATCH'])
11141114
)
11151115
self.assertEqual(
1116-
clean_subject('[PATCH] meep,\n meep'), ('meep, meep', [])
1116+
clean_subject('[PATCH] meep \n meep'), ('meep meep', [], ['PATCH'])
11171117
)
11181118
self.assertEqual(
1119-
clean_subject('[PATCH RFC] meep'), ('[RFC] meep', ['RFC'])
1119+
clean_subject('[PATCH] meep,\n meep'),
1120+
('meep, meep', [], ['PATCH']),
11201121
)
11211122
self.assertEqual(
1122-
clean_subject('[PATCH,RFC] meep'), ('[RFC] meep', ['RFC'])
1123+
clean_subject('[PATCH RFC] meep'),
1124+
('[RFC] meep', ['RFC'], ['PATCH']),
11231125
)
11241126
self.assertEqual(
1125-
clean_subject('[PATCH,1/2] meep'), ('[1/2] meep', ['1/2'])
1127+
clean_subject('[PATCH,RFC] meep'),
1128+
('[RFC] meep', ['RFC'], ['PATCH']),
1129+
)
1130+
self.assertEqual(
1131+
clean_subject('[PATCH,1/2] meep'),
1132+
('[1/2] meep', ['1/2'], ['PATCH']),
11261133
)
11271134
self.assertEqual(
11281135
clean_subject('[PATCH RFC 1/2] meep'),
1129-
('[RFC,1/2] meep', ['RFC', '1/2']),
1136+
('[RFC,1/2] meep', ['RFC', '1/2'], ['PATCH']),
11301137
)
11311138
self.assertEqual(
1132-
clean_subject('[PATCH] [RFC] meep'), ('[RFC] meep', ['RFC'])
1139+
clean_subject('[PATCH] [RFC] meep'),
1140+
('[RFC] meep', ['RFC'], ['PATCH']),
11331141
)
11341142
self.assertEqual(
11351143
clean_subject('[PATCH] [RFC,1/2] meep'),
1136-
('[RFC,1/2] meep', ['RFC', '1/2']),
1144+
('[RFC,1/2] meep', ['RFC', '1/2'], ['PATCH']),
11371145
)
11381146
self.assertEqual(
11391147
clean_subject('[PATCH] [RFC] [1/2] meep'),
1140-
('[RFC,1/2] meep', ['RFC', '1/2']),
1148+
('[RFC,1/2] meep', ['RFC', '1/2'], ['PATCH']),
11411149
)
11421150
self.assertEqual(
11431151
clean_subject('[PATCH] rewrite [a-z] regexes'),
1144-
('rewrite [a-z] regexes', []),
1152+
('rewrite [a-z] regexes', [], ['PATCH']),
11451153
)
11461154
self.assertEqual(
11471155
clean_subject('[PATCH] [RFC] rewrite [a-z] regexes'),
1148-
('[RFC] rewrite [a-z] regexes', ['RFC']),
1156+
('[RFC] rewrite [a-z] regexes', ['RFC'], ['PATCH']),
11491157
)
11501158
self.assertEqual(
1151-
clean_subject('[foo] [bar] meep', ['foo']), ('[bar] meep', ['bar'])
1159+
clean_subject('[foo] [bar] meep', ['foo']),
1160+
('[bar] meep', ['bar'], ['foo']),
11521161
)
11531162
self.assertEqual(
1154-
clean_subject('[FOO] [bar] meep', ['foo']), ('[bar] meep', ['bar'])
1163+
clean_subject('[FOO] [bar] meep', ['foo']),
1164+
('[bar] meep', ['bar'], ['FOO']),
11551165
)
11561166

11571167
def test_subject_check(self):
@@ -1570,3 +1580,59 @@ def test_parse_depends_on_url(self):
15701580
result = parser.parse_depends_on('\n'.join([content2, content3]))
15711581
self.assertIn(self.series1, result)
15721582
self.assertIn(self.series2, result)
1583+
1584+
1585+
class TestParseLabels(TestCase):
1586+
orig_diff = read_patch('0001-add-line.patch')
1587+
1588+
def setUp(self):
1589+
create_state()
1590+
self.project = create_project()
1591+
1592+
self.label = create_label(name='label', project=None)
1593+
self.label_rfc = create_label(name='RFC', project=self.project)
1594+
1595+
def test_single_label(self):
1596+
msgid = make_msgid()
1597+
email = create_email(
1598+
self.orig_diff,
1599+
listid=self.project.listid,
1600+
msgid=msgid,
1601+
subject='[PATCH,label] test subject',
1602+
)
1603+
_parse_mail(email)
1604+
1605+
patch = Patch.objects.filter(msgid=msgid)[0]
1606+
self.assertEqual(
1607+
list(patch.labels.values_list('id', flat=True)), [self.label.id]
1608+
)
1609+
self.assertEqual(patch.name, 'test subject')
1610+
1611+
def test_many_labels(self):
1612+
msgid = make_msgid()
1613+
email = create_email(
1614+
self.orig_diff,
1615+
listid=self.project.listid,
1616+
msgid=msgid,
1617+
subject='[PATCH label v2 RFC 3/8] test subject',
1618+
)
1619+
_parse_mail(email)
1620+
patch = Patch.objects.filter(msgid=msgid)[0]
1621+
self.assertEqual(patch.labels.count(), 2)
1622+
patch_labels = list(patch.labels.values_list('id', flat=True))
1623+
self.assertIn(self.label.id, patch_labels)
1624+
self.assertIn(self.label_rfc.id, patch_labels)
1625+
self.assertEqual(patch.name, '[v2,3/8] test subject')
1626+
1627+
def test_unknown_label(self):
1628+
msgid = make_msgid()
1629+
email = create_email(
1630+
self.orig_diff,
1631+
listid=self.project.listid,
1632+
msgid=msgid,
1633+
subject='[PATCH,unknown-label] test subject',
1634+
)
1635+
_parse_mail(email)
1636+
patch = Patch.objects.filter(msgid=msgid)[0]
1637+
self.assertEqual(patch.labels.count(), 0)
1638+
self.assertEqual(patch.name, '[unknown-label] test subject')

‎patchwork/tests/utils.py‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from patchwork.models import Check
1515
from patchwork.models import Cover
1616
from patchwork.models import CoverComment
17+
from patchwork.models import Label
1718
from patchwork.models import Patch
1819
from patchwork.models import PatchComment
1920
from patchwork.models import PatchRelation
@@ -313,6 +314,20 @@ def create_relation(**kwargs):
313314
return PatchRelation.objects.create(**kwargs)
314315

315316

317+
def create_label(**kwargs):
318+
"""Create a 'Label' object."""
319+
num = Label.objects.count()
320+
321+
values = {
322+
'name': 'label%d' % num if 'name' not in kwargs else kwargs['name'],
323+
'project': create_project() if 'project' not in kwargs else None,
324+
'color': '#fff',
325+
}
326+
values.update(**kwargs)
327+
328+
return Label.objects.create(**values)
329+
330+
316331
def _create_submissions(create_func, count=1, **kwargs):
317332
"""Create 'count' SubmissionMixin-based objects.
318333

0 commit comments

Comments
 (0)