|
1 from ldt.ldt_utils.models import Project |
|
2 |
|
3 from django.contrib.auth import get_user_model |
|
4 import lxml.etree |
|
5 |
|
6 import logging |
|
7 |
|
8 # pylint: disable=C0103 |
|
9 logger = logging.getLogger(__name__) |
|
10 |
|
11 # pylint: disable=C0103 |
|
12 User = get_user_model() |
|
13 |
|
14 """ |
|
15 Merge several projects in one for a given content. All ensembles are copied into one project |
|
16 """ |
|
17 # pylint: disable=R0903 |
|
18 class ProjectMerger(object): |
|
19 |
|
20 def __init__(self, content, projects): |
|
21 self.content = content |
|
22 self.projects = projects |
|
23 |
|
24 # pylint: disable=R0914 |
|
25 def get_merged_project(self, shot_by_shot=True, only_visible=True): |
|
26 |
|
27 # New project |
|
28 contents = [self.content,] |
|
29 # Get user |
|
30 user = User.objects.get(username="admin") |
|
31 |
|
32 proj = Project.create_project(title="Merged project", |
|
33 user=user, contents=contents, |
|
34 description=u"", set_icon=False) |
|
35 |
|
36 doc = lxml.etree.fromstring(proj.ldt_encoded) |
|
37 annot_node = doc.xpath("/iri/annotations")[0] |
|
38 content_node = lxml.etree.SubElement(annot_node, 'content') |
|
39 content_node.set('id', self.content.iri_id) |
|
40 display_node = doc.xpath('/iri/displays/display')[0] |
|
41 ctt_disp_node = display_node.xpath('content[@id="' + self.content.iri_id + '"]')[0] |
|
42 # remove shot by shot from display |
|
43 if not shot_by_shot: |
|
44 dec_node = ctt_disp_node.xpath('decoupage[@id="de_PPP"]') |
|
45 if len(dec_node) > 0: |
|
46 dec_node = dec_node[0] |
|
47 if dec_node is not None: |
|
48 ctt_disp_node.remove(dec_node) |
|
49 |
|
50 # Parse all projects |
|
51 for p in self.projects: |
|
52 p_xml = lxml.etree.fromstring(p.ldt_encoded) |
|
53 # We only keep the decoupages (cuttings) visible in the default |
|
54 # view, which means the first display. |
|
55 first_display = p_xml.xpath('/iri/displays/display')[0] |
|
56 disp_node_list = first_display.xpath('content[@id="' + self.content.iri_id + '"]') |
|
57 if len(disp_node_list) == 0: |
|
58 # project seems broken passing |
|
59 logger.info( |
|
60 "Get merged project : this project display %s does not contains the content %s", |
|
61 p.ldt_id, |
|
62 self.content.iri_id) |
|
63 continue |
|
64 current_disp_node = disp_node_list[0] |
|
65 # First version of ensemble |
|
66 ens = p_xml.xpath( |
|
67 '/iri/annotations/content[@id="' + |
|
68 self.content.iri_id + |
|
69 '"]/ensemble') |
|
70 for e in ens: |
|
71 content_node.append(e) |
|
72 # Update display |
|
73 for c in e.xpath('decoupage'): |
|
74 if not only_visible or \ |
|
75 (only_visible and \ |
|
76 len(current_disp_node.xpath('decoupage[@id="' + c.get('id') + '"]')) > 0): |
|
77 c_node = lxml.etree.SubElement(ctt_disp_node, 'decoupage') |
|
78 c_node.set(u'idens', e.get('id')) |
|
79 c_node.set(u'id', c.get('id')) |
|
80 # Second version of ensemble |
|
81 ens = p_xml.xpath('/iri/annotations/content[@id="' + |
|
82 self.content.iri_id + |
|
83 '"]/ensembles/ensemble') |
|
84 for e in ens: |
|
85 content_node.append(e) |
|
86 # Update display |
|
87 for c in e.xpath('decoupage'): |
|
88 if not only_visible or \ |
|
89 (only_visible and \ |
|
90 len(current_disp_node.xpath('decoupage[@id="' + |
|
91 c.get('id') + |
|
92 '"]')) > 0): |
|
93 c_node = lxml.etree.SubElement(ctt_disp_node, 'decoupage') |
|
94 c_node.set(u'idens', e.get('id')) |
|
95 c_node.set(u'id', c.get('id')) |
|
96 |
|
97 proj.ldt = lxml.etree.tostring(doc, pretty_print=True) |
|
98 |
|
99 return proj |