Coverage for src / crawler / cmds / xml_cmds.py: 18%
79 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-07-15 13:33 +0000
« prev ^ index » next coverage.py v7.13.1, created at 2026-07-15 13:33 +0000
1import logging
2import math
4from django.core.exceptions import ObjectDoesNotExist
5from django.db.models import Q
6from ptf.cmds.xml_cmds import (
7 addOrUpdateBookXmlCmd,
8 addOrUpdateContainerXmlCmd,
9 addOrUpdateIssueXmlCmd,
10 importEntireCollectionXmlCmd,
11)
12from ptf.models import Collection, CollectionMembership, Container
14from crawler.models import ContainerSource
16logger = logging.getLogger(__name__)
19def add_source_to_container(source_domain: str, container: Container):
20 from crawler import factory
22 source_cls = factory.get_crawler_class(source_domain)
23 if not source_cls:
24 logger.warning(
25 f"Couldn't insert source {source_domain} to container : source not implemented"
26 )
27 return False
29 source = source_cls.get_or_create_source()
30 try:
31 container.origin.delete()
32 except ObjectDoesNotExist:
33 pass
34 ContainerSource.objects.get_or_create(
35 source=source,
36 container=container,
37 )
38 logger.debug(f"Source {source_domain} successfully added to container {container.pid}")
39 return True
42def update_collection_years(pid):
43 collection = Collection.objects.get(pid=pid)
44 parent = collection.parent
46 if parent is None:
47 qs = Container.objects.filter(my_collection__pid=pid, origin__disabled=False)
48 collection_to_update = collection
49 else:
50 qs = Container.objects.filter(
51 Q(my_collection__pid=pid) | Q(my_collection__parent__pid=pid),
52 origin__disabled=False,
53 )
54 collection_to_update = parent
56 qs_member = CollectionMembership.objects.filter(collection__pid=collection_to_update.pid)
57 qs = [*(cm.container for cm in qs_member), *qs]
59 max_year = -math.inf
60 min_year = math.inf
61 for container in qs:
62 fyear = container.fyear
63 lyear = container.lyear or 0
64 max_year = max(lyear, max_year)
65 min_year = min(fyear, min_year)
66 if min_year == math.inf:
67 min_year = 0
68 if max_year == -math.inf:
69 max_year = 0
71 collection_to_update.fyear = int(min_year)
72 collection_to_update.lyear = int(max_year)
74 collection_to_update.save(update_fields=["fyear", "lyear"])
77class addOrUpdateGDMLIssueXmlCmd(addOrUpdateIssueXmlCmd):
78 def internal_do(self):
79 obj = super().internal_do()
80 if not obj or not self.xissue:
81 logger.debug("Skipping source insertion : database object or xissue is not set")
82 return obj
84 source_str = self.xissue.source
85 if not source_str:
86 if not self.add_link_to_source:
87 logger.debug(
88 "Skipping source insertion : add_link_to_source is false and xissue.source is None"
89 )
90 return obj
91 source_str = "NUMDAM"
93 add_source_to_container(source_str, obj)
94 self.update_collection_years(self.xissue.journal.pid)
95 return obj
98class addOrUpdateGDMLBookXmlCmd(addOrUpdateBookXmlCmd):
99 def internal_do(self):
100 obj = super().internal_do()
101 if not obj or not self.xbook:
102 logger.debug(
103 "Skipping source insertion : no database object was returned or xbook is None"
104 )
105 return obj
107 source_str = self.xbook.source
108 if not source_str:
109 if not self.add_link_to_source:
110 logger.debug(
111 "Skipping source insertion : add_link_to_source is false and xbook.source is None"
112 )
113 return obj
114 source_str = "NUMDAM"
116 add_source_to_container(source_str, obj)
117 return obj
120class addOrUpdateGDMLContainerXmlCmd(addOrUpdateContainerXmlCmd):
121 addOrUpdateIssueXmlCmdOverride = addOrUpdateGDMLIssueXmlCmd
122 addOrUpdateBookXmlCmdOverride = addOrUpdateGDMLBookXmlCmd
125importEntireCollectionXmlCmd.addOrUpdateContainerXmlCmdOverride = addOrUpdateGDMLContainerXmlCmd