Merged in [19396] from rjsparks@nostrum.com:
Provide a metadata endpoint to assist rfcdiff.pyht.
- Legacy-Id: 19397
Note: SVN reference [19396] has been migrated to Git commit 036966da97
This commit is contained in:
commit
6a13fd7062
|
@ -48,7 +48,7 @@ from ietf.name.models import SessionStatusName, BallotPositionName, DocTypeName
|
|||
from ietf.person.models import Person
|
||||
from ietf.person.factories import PersonFactory, EmailFactory
|
||||
from ietf.utils.mail import outbox
|
||||
from ietf.utils.test_utils import login_testing_unauthorized, unicontent
|
||||
from ietf.utils.test_utils import login_testing_unauthorized, unicontent, reload_db_objects
|
||||
from ietf.utils.test_utils import TestCase
|
||||
from ietf.utils.text import normalize_text
|
||||
|
||||
|
@ -2502,3 +2502,126 @@ class Idnits2SupportTests(TestCase):
|
|||
r = self.client.get(url)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertContains(r,'Proposed')
|
||||
|
||||
class RfcdiffSupportTests(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.target_view = 'ietf.doc.views_doc.rfcdiff_latest_json'
|
||||
|
||||
def getJson(self, view_args):
|
||||
url = urlreverse(self.target_view, kwargs=view_args)
|
||||
r = self.client.get(url)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
return r.json()
|
||||
|
||||
def test_draft(self):
|
||||
draft = IndividualDraftFactory(name='draft-somebody-did-something',rev='00')
|
||||
for r in range(0,13):
|
||||
e = NewRevisionDocEventFactory(doc=draft,rev=f'{r:02d}')
|
||||
draft.rev = f'{r:02d}'
|
||||
draft.save_with_history([e])
|
||||
draft = reload_db_objects(draft)
|
||||
|
||||
received = self.getJson(dict(name=draft.name))
|
||||
self.assertEqual(received, dict(
|
||||
name=draft.name,
|
||||
rev=draft.rev,
|
||||
content_url=draft.get_href(),
|
||||
previous=f'{draft.name}-{(int(draft.rev)-1):02d}'
|
||||
))
|
||||
|
||||
received = self.getJson(dict(name=draft.name, rev=draft.rev))
|
||||
self.assertEqual(received, dict(
|
||||
name=draft.name,
|
||||
rev=draft.rev,
|
||||
content_url=draft.get_href(),
|
||||
previous=f'{draft.name}-{(int(draft.rev)-1):02d}'
|
||||
))
|
||||
|
||||
received = self.getJson(dict(name=draft.name, rev='10'))
|
||||
self.assertEqual(received, dict(
|
||||
name=draft.name,
|
||||
rev='10',
|
||||
content_url=draft.history_set.get(rev='10').get_href(),
|
||||
previous=f'{draft.name}-09'
|
||||
))
|
||||
|
||||
received = self.getJson(dict(name=draft.name, rev='00'))
|
||||
self.assertNotIn('previous', received)
|
||||
|
||||
replaced = IndividualDraftFactory()
|
||||
RelatedDocument.objects.create(relationship_id='replaces',source=draft,target=replaced.docalias.first())
|
||||
received = self.getJson(dict(name=draft.name, rev='00'))
|
||||
self.assertEqual(received['previous'], f'{replaced.name}-{replaced.rev}')
|
||||
|
||||
|
||||
def test_draft_with_broken_history(self):
|
||||
draft = IndividualDraftFactory(rev='10')
|
||||
received = self.getJson(dict(name=draft.name,rev='09'))
|
||||
self.assertEqual(received['rev'],'09')
|
||||
self.assertEqual(received['previous'], f'{draft.name}-08')
|
||||
self.assertTrue('warning' in received)
|
||||
|
||||
|
||||
def test_draftname_with_numeric_suffix(self):
|
||||
draft = IndividualDraftFactory(name='draft-someone-did-something-01-02',rev='00')
|
||||
for r in range(0,4):
|
||||
e = NewRevisionDocEventFactory(doc=draft,rev=f'{r:02d}')
|
||||
draft.rev = f'{r:02d}'
|
||||
draft.save_with_history([e])
|
||||
|
||||
received = self.getJson(dict(name=draft.name))
|
||||
self.assertEqual(received['rev'],'03')
|
||||
self.assertIn('01-02-03',received['content_url'])
|
||||
self.assertIn('01-02-02',received['previous'])
|
||||
|
||||
received = self.getJson(dict(name=draft.name,rev='02'))
|
||||
self.assertEqual(received['rev'],'02')
|
||||
self.assertIn('01-02-02',received['content_url'])
|
||||
|
||||
def test_rfc(self):
|
||||
draft = WgDraftFactory()
|
||||
for r in range(0,2):
|
||||
e = NewRevisionDocEventFactory(doc=draft,rev=f'{r:02d}')
|
||||
draft.rev = f'{r:02d}'
|
||||
draft.save_with_history([e])
|
||||
|
||||
draft.docalias.create(name='rfc8000')
|
||||
draft.set_state(State.objects.get(type_id='draft',slug='rfc'))
|
||||
draft.set_state(State.objects.get(type_id='draft-iesg', slug='pub'))
|
||||
draft = reload_db_objects(draft)
|
||||
rfc = draft
|
||||
|
||||
number = rfc.rfc_number()
|
||||
received = self.getJson(dict(name=number))
|
||||
self.assertEqual(received, dict(
|
||||
content_url=rfc.get_href(),
|
||||
name=rfc.canonical_name(),
|
||||
previous=f'{draft.name}-{draft.rev}',
|
||||
))
|
||||
|
||||
num_received = received
|
||||
received = self.getJson(dict(name=rfc.canonical_name()))
|
||||
self.assertEqual(num_received, received)
|
||||
|
||||
received = self.getJson(dict(name=f'RfC {number}'))
|
||||
self.assertEqual(num_received, received)
|
||||
|
||||
def test_rfc_with_tombstone(self):
|
||||
draft = WgDraftFactory()
|
||||
for r in range(0,2):
|
||||
e = NewRevisionDocEventFactory(doc=draft,rev=f'{r:02d}')
|
||||
draft.rev = f'{r:02d}'
|
||||
draft.save_with_history([e])
|
||||
|
||||
draft.docalias.create(name='rfc3261') # See views_doc.HAS_TOMBSTONE
|
||||
draft.set_state(State.objects.get(type_id='draft',slug='rfc'))
|
||||
draft.set_state(State.objects.get(type_id='draft-iesg', slug='pub'))
|
||||
draft = reload_db_objects(draft)
|
||||
rfc = draft
|
||||
|
||||
# Some old rfcs had tombstones that shouldn't be used for comparisons
|
||||
received = self.getJson(dict(name=rfc.canonical_name()))
|
||||
self.assertTrue(received['previous'].endswith('00'))
|
||||
|
||||
|
||||
|
|
|
@ -71,6 +71,11 @@ urlpatterns = [
|
|||
url(r'^html/(?P<name>[Rr][Ff][Cc] [0-9]+?)(\.txt|\.html)?/?$', views_doc.document_html),
|
||||
url(r'^idnits2-rfcs-obsoleted/?$', views_doc.idnits2_rfcs_obsoleted),
|
||||
url(r'^idnits2-rfc-status/?$', views_doc.idnits2_rfc_status),
|
||||
# These two are proof-of-concept of a service that would redirect to the latest version
|
||||
# url(r'^rfcdiff-latest/%(name)s(?:-%(rev)s)?(\.txt|\.html)?/?$' % settings.URL_REGEXPS, views_doc.rfcdiff_latest),
|
||||
# url(r'^rfcdiff-latest/(?P<name>[Rr][Ff][Cc] [0-9]+?)(\.txt|\.html)?/?$', views_doc.rfcdiff_latest),
|
||||
url(r'^rfcdiff-latest-json/%(name)s(?:-%(rev)s)?(\.txt|\.html)?/?$' % settings.URL_REGEXPS, views_doc.rfcdiff_latest_json),
|
||||
url(r'^rfcdiff-latest-json/(?P<name>[Rr][Ff][Cc] [0-9]+?)(\.txt|\.html)?/?$', views_doc.rfcdiff_latest_json),
|
||||
|
||||
url(r'^all/?$', views_search.index_all_drafts),
|
||||
url(r'^active/?$', views_search.index_active_drafts),
|
||||
|
|
|
@ -1772,8 +1772,142 @@ def idnits2_state(request, name, rev=None):
|
|||
doc.deststatus="Unknown"
|
||||
return render(request, 'doc/idnits2-state.txt', context={'doc':doc}, content_type='text/plain;charset=utf-8')
|
||||
|
||||
def find_doc_for_rfcdiff(name, rev):
|
||||
if name.startswith('rfc0'):
|
||||
name = "rfc" + name[3:].lstrip('0')
|
||||
if name.startswith('review-') and re.search(r'-\d\d\d\d-\d\d$', name):
|
||||
name = "%s-%s" % (name, rev)
|
||||
if rev and not name.startswith('charter-') and re.search('[0-9]{1,2}-[0-9]{2}', rev):
|
||||
name = "%s-%s" % (name, rev[:-3])
|
||||
rev = rev[-2:]
|
||||
if re.match("^[0-9]+$", name):
|
||||
name = f'rfc{name}'
|
||||
if re.match("^[Rr][Ff][Cc] [0-9]+$",name):
|
||||
name = f'rfc{name[4:]}'
|
||||
|
||||
docs = Document.objects.filter(docalias__name=name, type_id='draft')
|
||||
if rev and not docs.exists():
|
||||
# handle some special cases, like draft-ietf-tsvwg-ieee-802-11
|
||||
name = '%s-%s' % (name, rev)
|
||||
rev=None
|
||||
docs = Document.objects.filter(docalias__name=name, type_id='draft')
|
||||
|
||||
condition = 'no such document'
|
||||
if not docs.exists() or docs.count() > 1:
|
||||
return (condition, None, None)
|
||||
doc = docs.get()
|
||||
if not rev or (rev and doc.rev==rev):
|
||||
condition = 'current version'
|
||||
return condition, doc, None
|
||||
else:
|
||||
candidate = None
|
||||
for h in doc.history_set.order_by("-time"):
|
||||
if rev == h.rev:
|
||||
candidate = h
|
||||
break
|
||||
if candidate:
|
||||
condition = 'historic version'
|
||||
return condition, doc, candidate
|
||||
else:
|
||||
condition = 'version dochistory not found'
|
||||
return condition, doc, None
|
||||
|
||||
# This is a proof of concept of a service that would redirect to the current revision
|
||||
# def rfcdiff_latest(request, name, rev=None):
|
||||
# condition, doc, history = find_doc_for_rfcdiff(name, rev)
|
||||
# if not doc:
|
||||
# raise Http404
|
||||
# if history:
|
||||
# return redirect(history.get_href())
|
||||
# else:
|
||||
# return redirect(doc.get_href())
|
||||
|
||||
HAS_TOMBSTONE = [
|
||||
2821, 2822, 2873, 2919, 2961, 3023, 3029, 3031, 3032, 3033, 3034, 3035, 3036,
|
||||
3037, 3038, 3042, 3044, 3050, 3052, 3054, 3055, 3056, 3057, 3059, 3060, 3061,
|
||||
3062, 3063, 3064, 3067, 3068, 3069, 3070, 3071, 3072, 3073, 3074, 3075, 3076,
|
||||
3077, 3078, 3080, 3081, 3082, 3084, 3085, 3086, 3087, 3088, 3089, 3090, 3094,
|
||||
3095, 3096, 3097, 3098, 3101, 3102, 3103, 3104, 3105, 3106, 3107, 3108, 3109,
|
||||
3110, 3111, 3112, 3113, 3114, 3115, 3116, 3117, 3118, 3119, 3120, 3121, 3123,
|
||||
3124, 3126, 3127, 3128, 3130, 3131, 3132, 3133, 3134, 3135, 3136, 3137, 3138,
|
||||
3139, 3140, 3141, 3142, 3143, 3144, 3145, 3147, 3149, 3150, 3151, 3152, 3153,
|
||||
3154, 3155, 3156, 3157, 3158, 3159, 3160, 3161, 3162, 3163, 3164, 3165, 3166,
|
||||
3167, 3168, 3169, 3170, 3171, 3172, 3173, 3174, 3176, 3179, 3180, 3181, 3182,
|
||||
3183, 3184, 3185, 3186, 3187, 3188, 3189, 3190, 3191, 3192, 3193, 3194, 3197,
|
||||
3198, 3201, 3202, 3203, 3204, 3205, 3206, 3207, 3208, 3209, 3210, 3211, 3212,
|
||||
3213, 3214, 3215, 3216, 3217, 3218, 3220, 3221, 3222, 3224, 3225, 3226, 3227,
|
||||
3228, 3229, 3230, 3231, 3232, 3233, 3234, 3235, 3236, 3237, 3238, 3240, 3241,
|
||||
3242, 3243, 3244, 3245, 3246, 3247, 3248, 3249, 3250, 3253, 3254, 3255, 3256,
|
||||
3257, 3258, 3259, 3260, 3261, 3262, 3263, 3264, 3265, 3266, 3267, 3268, 3269,
|
||||
3270, 3271, 3272, 3273, 3274, 3275, 3276, 3278, 3279, 3280, 3281, 3282, 3283,
|
||||
3284, 3285, 3286, 3287, 3288, 3289, 3290, 3291, 3292, 3293, 3294, 3295, 3296,
|
||||
3297, 3298, 3301, 3302, 3303, 3304, 3305, 3307, 3308, 3309, 3310, 3311, 3312,
|
||||
3313, 3315, 3317, 3318, 3319, 3320, 3321, 3322, 3323, 3324, 3325, 3326, 3327,
|
||||
3329, 3330, 3331, 3332, 3334, 3335, 3336, 3338, 3340, 3341, 3342, 3343, 3346,
|
||||
3348, 3349, 3351, 3352, 3353, 3354, 3355, 3356, 3360, 3361, 3362, 3363, 3364,
|
||||
3366, 3367, 3368, 3369, 3370, 3371, 3372, 3374, 3375, 3377, 3378, 3379, 3383,
|
||||
3384, 3385, 3386, 3387, 3388, 3389, 3390, 3391, 3394, 3395, 3396, 3397, 3398,
|
||||
3401, 3402, 3403, 3404, 3405, 3406, 3407, 3408, 3409, 3410, 3411, 3412, 3413,
|
||||
3414, 3415, 3416, 3417, 3418, 3419, 3420, 3421, 3422, 3423, 3424, 3425, 3426,
|
||||
3427, 3428, 3429, 3430, 3431, 3433, 3434, 3435, 3436, 3437, 3438, 3439, 3440,
|
||||
3441, 3443, 3444, 3445, 3446, 3447, 3448, 3449, 3450, 3451, 3452, 3453, 3454,
|
||||
3455, 3458, 3459, 3460, 3461, 3462, 3463, 3464, 3465, 3466, 3467, 3468, 3469,
|
||||
3470, 3471, 3472, 3473, 3474, 3475, 3476, 3477, 3480, 3481, 3483, 3485, 3488,
|
||||
3494, 3495, 3496, 3497, 3498, 3501, 3502, 3503, 3504, 3505, 3506, 3507, 3508,
|
||||
3509, 3511, 3512, 3515, 3516, 3517, 3518, 3520, 3521, 3522, 3523, 3524, 3525,
|
||||
3527, 3529, 3530, 3532, 3533, 3534, 3536, 3537, 3538, 3539, 3541, 3543, 3544,
|
||||
3545, 3546, 3547, 3548, 3549, 3550, 3551, 3552, 3555, 3556, 3557, 3558, 3559,
|
||||
3560, 3562, 3563, 3564, 3565, 3568, 3569, 3570, 3571, 3572, 3573, 3574, 3575,
|
||||
3576, 3577, 3578, 3579, 3580, 3581, 3582, 3583, 3584, 3588, 3589, 3590, 3591,
|
||||
3592, 3593, 3594, 3595, 3597, 3598, 3601, 3607, 3609, 3610, 3612, 3614, 3615,
|
||||
3616, 3625, 3627, 3630, 3635, 3636, 3637, 3638
|
||||
]
|
||||
|
||||
def rfcdiff_latest_json(request, name, rev=None):
|
||||
response = dict()
|
||||
condition, document, history = find_doc_for_rfcdiff(name, rev)
|
||||
|
||||
|
||||
if condition == 'no such document':
|
||||
raise Http404
|
||||
elif condition in ('historic version', 'current version'):
|
||||
doc = history if history else document
|
||||
if not rev and doc.is_rfc():
|
||||
response['content_url'] = doc.get_href()
|
||||
response['name']=doc.canonical_name()
|
||||
if doc.name != doc.canonical_name():
|
||||
prev_rev = doc.rev
|
||||
if int(doc.rfc_number()) in HAS_TOMBSTONE and prev_rev != '00':
|
||||
prev_rev = f'{(int(doc.rev)-1):02d}'
|
||||
response['previous'] = f'{doc.name}-{prev_rev}'
|
||||
else:
|
||||
doc.is_rfc = lambda: False
|
||||
response['content_url'] = doc.get_href()
|
||||
response['rev'] = doc.rev
|
||||
response['name'] = doc.name
|
||||
if doc.rev == '00':
|
||||
replaces_docs = (history.doc if condition=='historic version' else doc).related_that_doc('replaces')
|
||||
if replaces_docs:
|
||||
replaces = replaces_docs[0].document
|
||||
response['previous'] = f'{replaces.name}-{replaces.rev}'
|
||||
else:
|
||||
match = re.search("-(rfc)?([0-9][0-9][0-9]+)bis(-.*)?$", name)
|
||||
if match and match.group(2):
|
||||
response['previous'] = f'rfc{match.group(2)}'
|
||||
else:
|
||||
response['previous'] = f'{doc.name}-{(int(doc.rev)-1):02d}'
|
||||
elif condition == 'version dochistory not found':
|
||||
response['warning'] = 'History for this version not found - these results are speculation'
|
||||
response['name'] = document.name
|
||||
response['rev'] = rev
|
||||
document.rev = rev
|
||||
document.is_rfc = lambda: False
|
||||
response['content_url'] = document.get_href()
|
||||
if int(rev)>0:
|
||||
response['previous'] = f'{document.name}-{(int(rev)-1):02d}'
|
||||
else:
|
||||
match = re.search("-(rfc)?([0-9][0-9][0-9]+)bis(-.*)?$", name)
|
||||
if match and match.group(2):
|
||||
response['previous'] = f'rfc{match.group(2)}'
|
||||
if not response:
|
||||
raise Http404
|
||||
return HttpResponse(json.dumps(response), content_type='application/json')
|
||||
|
|
Loading…
Reference in a new issue