|
1 | 1 | # Copyright The IETF Trust 2007, All Rights Reserved |
2 | 2 |
|
3 | | -from django.conf import settings |
4 | | -from django.db.models import Q |
5 | | -from ietf.idtracker.models import InternetDraft, Rfc |
6 | | - |
7 | | -inverse = { |
8 | | - 'updates': 'is_updated_by', |
9 | | - 'is_updated_by': 'updates', |
10 | | - 'obsoletes': 'is_obsoleted_by', |
11 | | - 'is_obsoleted_by': 'obsoletes', |
12 | | - 'replaces': 'is_replaced_by', |
13 | | - 'is_replaced_by': 'replaces', |
14 | | - 'is_rfc_of': 'is_draft_of', |
15 | | - 'is_draft_of': 'is_rfc_of', |
16 | | - } |
17 | | - |
18 | | -display_relation = { |
19 | | - 'updates': 'that updated', |
20 | | - 'is_updated_by': 'that was updated by', |
21 | | - 'obsoletes': 'that obsoleted', |
22 | | - 'is_obsoleted_by': 'that was obsoleted by', |
23 | | - 'replaces': 'that replaced', |
24 | | - 'is_replaced_by': 'that was replaced by', |
25 | | - 'is_rfc_of': 'which came from', |
26 | | - 'is_draft_of': 'that was published as', |
27 | | - } |
28 | | - |
29 | | -def set_related(obj, rel, target): |
30 | | - #print obj, rel, target |
31 | | - # remember only the first relationship we find. |
32 | | - if not hasattr(obj, "related"): |
33 | | - obj.related = target |
34 | | - obj.relation = display_relation[rel] |
35 | | - return obj |
36 | | - |
37 | | -def set_relation(first, rel, second): |
38 | | - set_related(first, rel, second) |
39 | | - set_related(second, inverse[rel], first) |
40 | | - |
41 | | -def related_docs(doc, found = []): |
42 | | - """Get a list of document related to the given document. |
43 | | - """ |
44 | | - #print "\nrelated_docs(%s, %s)" % (doc, found) |
45 | | - found.append(doc) |
46 | | - if isinstance(doc, Rfc): |
47 | | - try: |
48 | | - item = InternetDraft.objects.get(rfc_number=doc.rfc_number) |
49 | | - if not item in found: |
50 | | - set_relation(doc, 'is_rfc_of', item) |
51 | | - found = related_docs(item, found) |
52 | | - except InternetDraft.DoesNotExist: |
53 | | - pass |
54 | | - for entry in doc.updated_or_obsoleted_by.all(): |
55 | | - item = entry.rfc |
56 | | - if not item in found: |
57 | | - action = inverse[entry.action.lower()] |
58 | | - set_relation(doc, action, item) |
59 | | - found = related_docs(item, found) |
60 | | - for entry in doc.updates_or_obsoletes.all(): |
61 | | - item = entry.rfc_acted_on |
62 | | - if not item in found: |
63 | | - action = entry.action.lower() |
64 | | - set_relation(doc, action, item) |
65 | | - found = related_docs(item, found) |
66 | | - if isinstance(doc, InternetDraft): |
67 | | - if doc.replaced_by_id: |
68 | | - item = doc.replaced_by |
69 | | - if not item in found: |
70 | | - set_relation(doc, 'is_replaced_by', item) |
71 | | - found = related_docs(item, found) |
72 | | - for item in doc.replaces_set.all(): |
73 | | - if not item in found: |
74 | | - set_relation(doc, 'replaces', item) |
75 | | - found = related_docs(item, found) |
76 | | - if doc.rfc_number: |
77 | | - item = Rfc.objects.get(rfc_number=doc.rfc_number) |
78 | | - if not item in found: |
79 | | - set_relation(doc, 'is_draft_of', item) |
80 | | - found = related_docs(item, found) |
81 | | - return found |
82 | | - |
83 | | -def related_docsREDESIGN(alias, _): |
84 | | - """Get related document aliases to given alias through depth-first search.""" |
85 | | - from ietf.doc.models import RelatedDocument |
86 | | - from ietf.doc.proxy import DraftLikeDocAlias |
87 | | - |
88 | | - mapping = dict( |
89 | | - updates='that updated', |
90 | | - obs='that obsoleted', |
91 | | - replaces='that replaced', |
92 | | - ) |
93 | | - inverse_mapping = dict( |
94 | | - updates='that was updated by', |
95 | | - obs='that was obsoleted by', |
96 | | - replaces='that was replaced by', |
97 | | - ) |
| 3 | +def related_docs(alias): |
| 4 | + results = list(alias.document.docalias_set.all()) |
98 | 5 |
|
99 | | - res = [ alias ] |
100 | | - remaining = [ alias ] |
101 | | - while remaining: |
102 | | - a = remaining.pop() |
103 | | - related = RelatedDocument.objects.filter(relationship__in=mapping.keys()).filter(Q(source=a.document) | Q(target=a)) |
104 | | - for r in related: |
105 | | - if r.source == a.document: |
106 | | - found = DraftLikeDocAlias.objects.filter(pk=r.target_id) |
107 | | - inverse = True |
108 | | - else: |
109 | | - found = DraftLikeDocAlias.objects.filter(document=r.source) |
110 | | - inverse = False |
111 | | - |
112 | | - for x in found: |
113 | | - if not x in res: |
114 | | - x.related = a |
115 | | - x.relation = (inverse_mapping if inverse else mapping)[r.relationship_id] |
116 | | - res.append(x) |
117 | | - remaining.append(x) |
118 | | - |
119 | | - # there's one more source of relatedness, a draft can have been published |
120 | | - aliases = DraftLikeDocAlias.objects.filter(document=a.document).exclude(pk__in=[x.pk for x in res]) |
121 | | - for oa in aliases: |
122 | | - rel = None |
123 | | - if a.name.startswith("rfc") and oa.name.startswith("draft"): |
124 | | - rel = "that was published as" |
125 | | - elif a.name.startswith("draft") and oa.name.startswith("rfc"): |
126 | | - rel = "which came from" |
127 | | - |
128 | | - if rel: |
129 | | - oa.related = a |
130 | | - oa.relation = rel |
131 | | - res.append(oa) |
132 | | - remaining.append(oa) |
133 | | - |
134 | | - return res |
135 | | - |
136 | | -if settings.USE_DB_REDESIGN_PROXY_CLASSES: |
137 | | - related_docs = related_docsREDESIGN |
| 6 | + rels = alias.document.all_relations_that_doc(['replaces','obs']) |
| 7 | + |
| 8 | + for rel in rels: |
| 9 | + rel_aliases = list(rel.target.document.docalias_set.all()) |
| 10 | + |
| 11 | + for x in rel_aliases: |
| 12 | + x.related = rel |
| 13 | + x.relation = rel.relationship.revname |
| 14 | + results += rel_aliases |
| 15 | + return list(set(results)) |
0 commit comments