|
12 | 12 | from django.utils.html import escape |
13 | 13 | from django.core.urlresolvers import reverse as urlreverse |
14 | 14 |
|
| 15 | +import debug # pyflakes:ignore |
| 16 | + |
15 | 17 | from ietf.doc.models import Document, DocHistory, State, DocumentAuthor, DocHistoryAuthor |
16 | 18 | from ietf.doc.models import DocAlias, RelatedDocument, RelatedDocHistory, BallotType, DocReminder |
17 | 19 | from ietf.doc.models import DocEvent, ConsensusDocEvent, BallotDocEvent, NewRevisionDocEvent, StateDocEvent |
@@ -705,3 +707,130 @@ def get_search_cache_key(params): |
705 | 707 | key = "doc:document:search:" + hashlib.sha512(json.dumps(kwargs, sort_keys=True)).hexdigest() |
706 | 708 | return key |
707 | 709 |
|
| 710 | +def label_wrap(label, items, joiner=',', max=50): |
| 711 | + lines = [] |
| 712 | + if not items: |
| 713 | + return lines |
| 714 | + line = '%s: %s' % (label, items[0]) |
| 715 | + for item in items[1:]: |
| 716 | + if len(line)+len(joiner+' ')+len(item) > max: |
| 717 | + lines.append(line+joiner) |
| 718 | + line = ' '*(len(label)+len(': ')) + item |
| 719 | + else: |
| 720 | + line += joiner+' '+item |
| 721 | + if line: |
| 722 | + lines.append(line) |
| 723 | + return lines |
| 724 | + |
| 725 | +def join_justified(left, right, width=72): |
| 726 | + count = max(len(left), len(right)) |
| 727 | + left = left + ['']*(count-len(left)) |
| 728 | + right = right + ['']*(count-len(right)) |
| 729 | + lines = [] |
| 730 | + i = 0 |
| 731 | + while True: |
| 732 | + l = left[i] |
| 733 | + r = right[i] |
| 734 | + if len(l)+1+len(r) > width: |
| 735 | + left = left + [''] |
| 736 | + right = right[:i] + [''] + right[i:] |
| 737 | + r = right[i] |
| 738 | + count += 1 |
| 739 | + lines.append( l + ' ' + r.rjust(width-len(l)-1) ) |
| 740 | + i += 1 |
| 741 | + if i >= count: |
| 742 | + break |
| 743 | + return lines |
| 744 | + |
| 745 | +def build_doc_meta_block(doc, path): |
| 746 | + def add_markup(path, doc, lines): |
| 747 | + is_hst = doc.is_dochistory() |
| 748 | + rev = doc.rev |
| 749 | + if is_hst: |
| 750 | + doc = doc.doc |
| 751 | + name = doc.name |
| 752 | + rfcnum = doc.rfc_number() |
| 753 | + errata_url = settings.RFC_EDITOR_ERRATA_URL.format(rfc_number=rfcnum) if not is_hst else "" |
| 754 | + ipr_url = "%s?submit=draft&id=%s" % (urlreverse('ietf.ipr.views.search'), name) |
| 755 | + for i, line in enumerate(lines): |
| 756 | + # add draft links |
| 757 | + line = re.sub(r'\b(draft-[-a-z0-9]+)\b', '<a href="%s/\g<1>">\g<1></a>'%(path, ), line) |
| 758 | + # add rfcXXXX to RFC links |
| 759 | + line = re.sub(r' (rfc[0-9]+)\b', ' <a href="%s/\g<1>">\g<1></a>'%(path, ), line) |
| 760 | + # add XXXX to RFC links |
| 761 | + line = re.sub(r' ([0-9]{3,5})\b', ' <a href="%s/rfc\g<1>">\g<1></a>'%(path, ), line) |
| 762 | + # add draft revision links |
| 763 | + line = re.sub(r' ([0-9]{2})\b', ' <a href="%s/%s-\g<1>">\g<1></a>'%(path, name, ), line) |
| 764 | + if rfcnum: |
| 765 | + # add errata link |
| 766 | + line = re.sub(r'Errata exist', '<a class="text-warning" href="%s">Errata exist</a>'%(errata_url, ), line) |
| 767 | + if is_hst or not rfcnum: |
| 768 | + # make current draft rev bold |
| 769 | + line = re.sub(r'>(%s)<'%rev, '><b>\g<1></b><', line) |
| 770 | + line = re.sub(r'IPR declarations', '<a class="text-warning" href="%s">IPR declarations</a>'%(ipr_url, ), line) |
| 771 | + line = line.replace(r'[txt]', '[<a href="%s">txt</a>]' % doc.href()) |
| 772 | + lines[i] = line |
| 773 | + return lines |
| 774 | + # |
| 775 | + now = datetime.datetime.now() |
| 776 | + draft_state = doc.get_state('draft') |
| 777 | + block = '' |
| 778 | + meta = {} |
| 779 | + if doc.type_id == 'draft': |
| 780 | + revisions = [] |
| 781 | + ipr = doc.related_ipr() |
| 782 | + if ipr: |
| 783 | + meta['ipr'] = [ "IPR declarations" ] |
| 784 | + if doc.is_rfc() and not doc.is_dochistory(): |
| 785 | + if not doc.name.startswith('rfc'): |
| 786 | + meta['from'] = [ "%s-%s"%(doc.name, doc.rev) ] |
| 787 | + meta['errata'] = [ "Errata exist" ] if doc.tags.filter(slug='errata').exists() else [] |
| 788 | + meta['obsoletedby'] = [ alias.document.rfc_number() for alias in doc.related_that('obs') ] |
| 789 | + meta['obsoletedby'].sort() |
| 790 | + meta['updatedby'] = [ alias.document.rfc_number() for alias in doc.related_that('updates') ] |
| 791 | + meta['updatedby'].sort() |
| 792 | + meta['stdstatus'] = [ doc.std_level.name ] |
| 793 | + else: |
| 794 | + dd = doc.doc if doc.is_dochistory() else doc |
| 795 | + revisions += [ '(%s)%s'%(d.name, ' '*(2-((len(d.name)-1)%3))) for d in dd.replaces() ] |
| 796 | + revisions += doc.revisions() |
| 797 | + if doc.is_dochistory() and doc.doc.is_rfc(): |
| 798 | + revisions += [ doc.doc.canonical_name() ] |
| 799 | + else: |
| 800 | + revisions += [ d.name for d in doc.replaced_by() ] |
| 801 | + meta['versions'] = revisions |
| 802 | + if not doc.is_dochistory and draft_state.slug == 'active' and now > doc.expires: |
| 803 | + # Active past expiration date |
| 804 | + meta['active'] = [ 'Document is active' ] |
| 805 | + meta['state' ] = [ doc.friendly_state() ] |
| 806 | + intended_std = doc.intended_std_level if doc.intended_std_level else None |
| 807 | + if intended_std: |
| 808 | + if intended_std.slug in ['ps', 'ds', 'std']: |
| 809 | + meta['stdstatus'] = [ "Standards Track" ] |
| 810 | + else: |
| 811 | + meta['stdstatus'] = [ intended_std.name ] |
| 812 | + elif doc.type_id == 'charter': |
| 813 | + meta['versions'] = doc.revisions() |
| 814 | + # |
| 815 | + # Add markup to items that needs it. |
| 816 | + if 'versions' in meta: |
| 817 | + meta['versions'] = label_wrap('Versions', meta['versions'], joiner="") |
| 818 | + for label in ['Obsoleted by', 'Updated by', 'From' ]: |
| 819 | + item = label.replace(' ','').lower() |
| 820 | + if item in meta and meta[item]: |
| 821 | + meta[item] = label_wrap(label, meta[item]) |
| 822 | + # |
| 823 | + left = [] |
| 824 | + right = [] |
| 825 | + #right = [ '[txt]'] |
| 826 | + for item in [ 'from', 'versions', 'obsoletedby', 'updatedby', ]: |
| 827 | + if item in meta and meta[item]: |
| 828 | + left += meta[item] |
| 829 | + for item in ['stdstatus', 'active', 'state', 'ipr', 'errata', ]: |
| 830 | + if item in meta and meta[item]: |
| 831 | + right += meta[item] |
| 832 | + lines = join_justified(left, right) |
| 833 | + block = '\n'.join(add_markup(path, doc, lines)) |
| 834 | + # |
| 835 | + return block |
| 836 | + |
0 commit comments