|
1 | 1 | # Copyright The IETF Trust 2007, All Rights Reserved |
2 | 2 |
|
3 | | -import datetime, os |
| 3 | +import datetime |
| 4 | +import logging |
| 5 | +import os |
| 6 | +import re |
4 | 7 |
|
5 | 8 | from django.db import models |
6 | 9 | from django.core import checks |
|
19 | 22 | from ietf.person.models import Email, Person |
20 | 23 | from ietf.utils import log |
21 | 24 | from ietf.utils.admin import admin_link |
| 25 | +from ietf.utils.rfcmarkup import markup |
22 | 26 | from ietf.utils.validators import validate_no_control_chars |
23 | 27 |
|
| 28 | +logger = logging.getLogger('django') |
| 29 | + |
24 | 30 | class StateType(models.Model): |
25 | 31 | slug = models.CharField(primary_key=True, max_length=30) # draft, draft-iesg, charter, ... |
26 | 32 | label = models.CharField(max_length=255, help_text="Label that should be used (e.g. in admin) for state drop-down for this type of state") # State, IESG state, WG state, ... |
@@ -92,24 +98,53 @@ def file_extension(self): |
92 | 98 | return ext.lstrip(".").lower() |
93 | 99 |
|
94 | 100 | def get_file_path(self): |
95 | | - |
96 | | - if self.type_id == "draft": |
97 | | - return settings.INTERNET_DRAFT_PATH |
98 | | - elif self.type_id in ("agenda", "minutes", "slides", "bluesheets") and self.meeting_related(): |
99 | | - doc = self.doc if isinstance(self, DocHistory) else self |
100 | | - if doc.session_set.exists(): |
101 | | - meeting = doc.session_set.first().meeting |
102 | | - return os.path.join(meeting.get_materials_path(), self.type_id) + "/" |
| 101 | + if not hasattr(self, '_cached_file_path'): |
| 102 | + if self.type_id == "draft": |
| 103 | + if self.get_state_slug() == "rfc": |
| 104 | + self._cached_file_path = settings.RFC_PATH |
| 105 | + else: |
| 106 | + self._cached_file_path = settings.INTERNET_DRAFT_PATH |
| 107 | + elif self.type_id in ("agenda", "minutes", "slides", "bluesheets") and self.meeting_related(): |
| 108 | + doc = self.doc if isinstance(self, DocHistory) else self |
| 109 | + if doc.session_set.exists(): |
| 110 | + meeting = doc.session_set.first().meeting |
| 111 | + self._cached_file_path = os.path.join(meeting.get_materials_path(), self.type_id) + "/" |
| 112 | + else: |
| 113 | + self._cached_file_path = "" |
| 114 | + elif self.type_id == "charter": |
| 115 | + self._cached_file_path = settings.CHARTER_PATH |
| 116 | + elif self.type_id == "conflrev": |
| 117 | + self._cached_file_path = settings.CONFLICT_REVIEW_PATH |
| 118 | + elif self.type_id == "statchg": |
| 119 | + self._cached_file_path = settings.STATUS_CHANGE_PATH |
103 | 120 | else: |
104 | | - return "" |
105 | | - elif self.type_id == "charter": |
106 | | - return settings.CHARTER_PATH |
107 | | - elif self.type_id == "conflrev": |
108 | | - return settings.CONFLICT_REVIEW_PATH |
109 | | - elif self.type_id == "statchg": |
110 | | - return settings.STATUS_CHANGE_PATH |
111 | | - else: |
112 | | - return settings.DOCUMENT_PATH_PATTERN.format(doc=self) |
| 121 | + self._cached_file_path = settings.DOCUMENT_PATH_PATTERN.format(doc=self) |
| 122 | + return self._cached_file_path |
| 123 | + |
| 124 | + def get_base_name(self): |
| 125 | + if not hasattr(self, '_cached_base_name'): |
| 126 | + if self.type_id == 'draft': |
| 127 | + if self.get_state_slug() == 'rfc': |
| 128 | + self._cached_base_name = "%s.txt" % self.canonical_name() |
| 129 | + else: |
| 130 | + self._cached_base_name = "%s-%s.txt" % (self.name, self.rev) |
| 131 | + elif self.type_id in ["slides", "agenda", "minutes", "bluesheets", ] and self.meeting_related(): |
| 132 | + if self.external_url: |
| 133 | + # we need to remove the extension for the globbing below to work |
| 134 | + self._cached_base_name = self.external_url |
| 135 | + else: |
| 136 | + self._cached_base_name = "%s.txt" % self.canonical_name() # meeting materials are unversioned at the moment |
| 137 | + else: |
| 138 | + if self.rev: |
| 139 | + self._cached_base_name = "%s-%s.txt" % (self.canonical_name(), self.rev) |
| 140 | + else: |
| 141 | + self._cached_base_name = "%s.txt" % (self.canonical_name(), ) |
| 142 | + return self._cached_base_name |
| 143 | + |
| 144 | + def get_file_name(self): |
| 145 | + if not hasattr(self, '_cached_file_name'): |
| 146 | + self._cached_file_name = os.path.join(self.get_file_path(), self.get_base_name()) |
| 147 | + return self._cached_file_name |
113 | 148 |
|
114 | 149 | def href(self, meeting=None): |
115 | 150 | """ |
@@ -604,7 +639,26 @@ def pub_date(self): |
604 | 639 | else: |
605 | 640 | event = self.latest_event(type='new_revision') |
606 | 641 | return event.time |
607 | | - |
| 642 | + |
| 643 | + def text(self): |
| 644 | + path = self.get_file_name() |
| 645 | + try: |
| 646 | + with open(path, 'rb') as file: |
| 647 | + text = file.read().decode('utf-8') |
| 648 | + except (IOError, UnicodeDecodeError) as e: |
| 649 | + text = None |
| 650 | + logger.error("Failure to read document text for %s", self.name, exc_info=e) |
| 651 | + # |
| 652 | + return text |
| 653 | + |
| 654 | + |
| 655 | + def htmlized(self): |
| 656 | + text = self.text() |
| 657 | + html = None |
| 658 | + if text: |
| 659 | + html = markup(text, path="/doc") |
| 660 | + html = re.sub(r'<hr[^>]*/>','', html) |
| 661 | + return html |
608 | 662 |
|
609 | 663 | class RelatedDocHistory(models.Model): |
610 | 664 | source = models.ForeignKey('DocHistory') |
|
0 commit comments