Coverage for src/crawler/cmds/xml_cmds.py: 18%
79 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-09-23 14:47 +0000
« prev ^ index » next coverage.py v7.15.4, created at 2026-09-23 14:47 +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, disabled=True):
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(source=source, container=container, disabled=disabled)
35 logger.debug(f"Source {source_domain} successfully added to container {container.pid}")
36 return True
39def update_collection_years(pid):
40 collection = Collection.objects.get(pid=pid)
41 parent = collection.parent
43 if parent is None:
44 qs = Container.objects.filter(my_collection__pid=pid, origin__disabled=False)
45 collection_to_update = collection
46 else:
47 qs = Container.objects.filter(
48 Q(my_collection__pid=pid) | Q(my_collection__parent__pid=pid),
49 origin__disabled=False,
50 )
51 collection_to_update = parent
53 qs_member = CollectionMembership.objects.filter(collection__pid=collection_to_update.pid)
54 qs = [*(cm.container for cm in qs_member), *qs]
56 max_year = -math.inf
57 min_year = math.inf
58 for container in qs:
59 fyear = container.fyear
60 lyear = container.lyear or 0
61 max_year = max(lyear, max_year)
62 min_year = min(fyear, min_year)
63 if min_year == math.inf:
64 min_year = 0
65 if max_year == -math.inf:
66 max_year = 0
68 collection_to_update.fyear = int(min_year)
69 collection_to_update.lyear = int(max_year)
71 collection_to_update.save(update_fields=["fyear", "lyear"])
74class addOrUpdateGDMLIssueXmlCmd(addOrUpdateIssueXmlCmd):
75 def internal_do(self):
76 obj = super().internal_do()
77 if not obj or not self.xissue:
78 logger.debug("Skipping source insertion : database object or xissue is not set")
79 return obj
81 source_str = self.xissue.source
82 if not source_str:
83 if not self.add_link_to_source:
84 logger.debug(
85 "Skipping source insertion : add_link_to_source is false and xissue.source is None"
86 )
87 return obj
88 source_str = "NUMDAM"
90 add_source_to_container(source_str, obj)
91 self.update_collection_years(self.xissue.journal.pid)
92 return obj
95class addOrUpdateGDMLBookXmlCmd(addOrUpdateBookXmlCmd):
96 def internal_do(self):
97 obj = super().internal_do()
98 if not obj or not self.xbook:
99 logger.debug(
100 "Skipping source insertion : no database object was returned or xbook is None"
101 )
102 return obj
104 source_str = self.xbook.source
105 if not source_str:
106 if not self.add_link_to_source:
107 logger.debug(
108 "Skipping source insertion : add_link_to_source is false and xbook.source is None"
109 )
110 return obj
111 source_str = "NUMDAM"
113 add_source_to_container(source_str, obj)
114 return obj
117class addOrUpdateGDMLContainerXmlCmd(addOrUpdateContainerXmlCmd):
118 addOrUpdateIssueXmlCmdOverride = addOrUpdateGDMLIssueXmlCmd
119 addOrUpdateBookXmlCmdOverride = addOrUpdateGDMLBookXmlCmd
122importEntireCollectionXmlCmd.addOrUpdateContainerXmlCmdOverride = addOrUpdateGDMLContainerXmlCmd