Merge ~alexmurray/ubuntu-cve-tracker:python3-12-deprecation-fixups into ubuntu-cve-tracker:master
- Git
- lp:~alexmurray/ubuntu-cve-tracker
- python3-12-deprecation-fixups
- Merge into master
Status: | Merged |
---|---|
Merge reported by: | Steve Beattie |
Merged at revision: | b50dcd7ffc132ad87b39990ead6d05694faead0d |
Proposed branch: | ~alexmurray/ubuntu-cve-tracker:python3-12-deprecation-fixups |
Merge into: | ubuntu-cve-tracker:master |
Diff against target: |
249 lines (+29/-30) 3 files modified
scripts/active_edit (+2/-2) scripts/check-cves (+9/-9) scripts/oval_lib.py (+18/-19) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Steve Beattie | Approve | ||
Review via email: mp+461222@code.launchpad.net |
Commit message
Description of the change
I suspect we have other scripts that will need similar fixes so will try and capture as many as I can here.
- 8683bc4... by Alex Murray
-
scripts/
oval_lib. py: update for Python 3.12 deprecations Signed-off-by: Alex Murray <email address hidden>
- b50dcd7... by Alex Murray
-
scripts/
active_ edit: update for Python 3.12 deprecations Signed-off-by: Alex Murray <email address hidden>
Steve Beattie (sbeattie) wrote : | # |
Steve Beattie (sbeattie) wrote : | # |
A couple more commits to include in https:/
Steve Beattie (sbeattie) wrote : | # |
I went ahead and fixed a bunch more and did the conversion to use datetime.
Unfortunately, I ended up needing to rebase on top of master due to a merge conflict, so launchpad is not autoclosing this merge request.
Steve Beattie (sbeattie) wrote : | # |
(I didn't squash the commits, all the individual ones are still there, that's just how cgit shows the merge request.)
Preview Diff
1 | diff --git a/scripts/active_edit b/scripts/active_edit | |||
2 | index dadaf35..b02c28e 100755 | |||
3 | --- a/scripts/active_edit | |||
4 | +++ b/scripts/active_edit | |||
5 | @@ -99,7 +99,7 @@ def fetch_kernel_fixes(url): | |||
6 | 99 | if re.match("commit [0-9a-f]{40} upstream.", line): | 99 | if re.match("commit [0-9a-f]{40} upstream.", line): |
7 | 100 | # This is an LTS backport, skip it | 100 | # This is an LTS backport, skip it |
8 | 101 | return [] | 101 | return [] |
10 | 102 | if re.match("\[ Upstream commit [0-9a-f]{40} \]", line): | 102 | if re.match(r"\[ Upstream commit [0-9a-f]{40} \]", line): |
11 | 103 | # This is an LTS backport, skip it | 103 | # This is an LTS backport, skip it |
12 | 104 | return [] | 104 | return [] |
13 | 105 | if not commit_hash and line.startswith("From "): | 105 | if not commit_hash and line.startswith("From "): |
14 | @@ -316,7 +316,7 @@ def create_or_update_cve(cve, packages, priority=None, bug_urls=None, | |||
15 | 316 | # Set a default public date only when the CVE isn't being added to the | 316 | # Set a default public date only when the CVE isn't being added to the |
16 | 317 | # embargoed tree | 317 | # embargoed tree |
17 | 318 | if not embargoed and not public_date: | 318 | if not embargoed and not public_date: |
19 | 319 | public_date = datetime.datetime.utcnow().strftime("%Y-%m-%d") | 319 | public_date = datetime.datetime.now(datetime.UTC).strftime("%Y-%m-%d") |
20 | 320 | 320 | ||
21 | 321 | if update: | 321 | if update: |
22 | 322 | mode = "a" | 322 | mode = "a" |
23 | diff --git a/scripts/check-cves b/scripts/check-cves | |||
24 | index 322f38b..0865e4a 100755 | |||
25 | --- a/scripts/check-cves | |||
26 | +++ b/scripts/check-cves | |||
27 | @@ -183,7 +183,7 @@ def convert_to_nvd(cves=[], desc=""): | |||
28 | 183 | nvd = {"CVE_data_type": "CVE", | 183 | nvd = {"CVE_data_type": "CVE", |
29 | 184 | "CVE_data_format": "MITRE", | 184 | "CVE_data_format": "MITRE", |
30 | 185 | "CVE_data_version": "4.0", | 185 | "CVE_data_version": "4.0", |
32 | 186 | "CVE_data_timestamp": datetime.datetime.utcnow().strftime("%Y-%m-%dT%H:%MZ"), | 186 | "CVE_data_timestamp": datetime.datetime.now(datetime.UTC).strftime("%Y-%m-%dT%H:%MZ"), |
33 | 187 | "CVE_Items": []} | 187 | "CVE_Items": []} |
34 | 188 | 188 | ||
35 | 189 | keys = list(cves.keys()) | 189 | keys = list(cves.keys()) |
36 | @@ -474,8 +474,8 @@ def read_locate_cves_output(f): | |||
37 | 474 | subject += " " + s.strip() | 474 | subject += " " + s.strip() |
38 | 475 | 475 | ||
39 | 476 | # Try to fake up some urls | 476 | # Try to fake up some urls |
42 | 477 | rhsa_regex = '\[RHSA-\d\d\d\d:\d+-\d+\]' | 477 | rhsa_regex = r'\[RHSA-\d\d\d\d:\d+-\d+\]' |
43 | 478 | osssec_regex = '\[oss-security\]' | 478 | osssec_regex = r'\[oss-security\]' |
44 | 479 | if re.search(r'' + rhsa_regex, subject): | 479 | if re.search(r'' + rhsa_regex, subject): |
45 | 480 | rhsa = re.sub(r'.*(%s).*' % rhsa_regex, r'\1', subject).strip('[|]') | 480 | rhsa = re.sub(r'.*(%s).*' % rhsa_regex, r'\1', subject).strip('[|]') |
46 | 481 | url = "https://rhn.redhat.com/errata/%s-%s.html" % (rhsa.split(':')[0], rhsa.split(':')[1].split('-')[0]) | 481 | url = "https://rhn.redhat.com/errata/%s-%s.html" % (rhsa.split(':')[0], rhsa.split(':')[1].split('-')[0]) |
47 | @@ -651,7 +651,7 @@ class CVEHandler(xml.sax.handler.ContentHandler): | |||
48 | 651 | raise KeyError("NVD JSON in '%s' seems invalid" % fp.name) | 651 | raise KeyError("NVD JSON in '%s' seems invalid" % fp.name) |
49 | 652 | 652 | ||
50 | 653 | metadata = cve["CVE_data_meta"] | 653 | metadata = cve["CVE_data_meta"] |
52 | 654 | if not re.match('^CVE-\d{4}-\d{4,}$', metadata["ID"]): | 654 | if not re.match(r'^CVE-\d{4}-\d{4,}$', metadata["ID"]): |
53 | 655 | print("Ignoring invalid CVE with ID '%s'" % metadata["ID"]) | 655 | print("Ignoring invalid CVE with ID '%s'" % metadata["ID"]) |
54 | 656 | return | 656 | return |
55 | 657 | self.curr_cve = metadata["ID"] | 657 | self.curr_cve = metadata["ID"] |
56 | @@ -850,8 +850,8 @@ class CVEHandler(xml.sax.handler.ContentHandler): | |||
57 | 850 | if suggestion.startswith('a ') and len(phrases) > 1: | 850 | if suggestion.startswith('a ') and len(phrases) > 1: |
58 | 851 | suggestion = phrases[-2] | 851 | suggestion = phrases[-2] |
59 | 852 | 852 | ||
62 | 853 | version_preps = '(\s+(before|through|prior to|versions?|[<>]=?))+\s*' | 853 | version_preps = r'(\s+(before|through|prior to|versions?|[<>]=?))+\s*' |
63 | 854 | version_regex = '\s+([a-zA-Z\._\-]*[0-9]+[a-zA-Z\._\-]*)+' | 854 | version_regex = r'\s+([a-zA-Z\._\-]*[0-9]+[a-zA-Z\._\-]*)+' |
64 | 855 | # prefer 'Apple iOS before <version>' or 'Apple Mac OS X through | 855 | # prefer 'Apple iOS before <version>' or 'Apple Mac OS X through |
65 | 856 | # <version' in the last phrase over other suggestions | 856 | # <version' in the last phrase over other suggestions |
66 | 857 | if not re.search(r'' + version_preps + version_regex, suggestion): | 857 | if not re.search(r'' + version_preps + version_regex, suggestion): |
67 | @@ -1405,7 +1405,7 @@ class CVEHandler(xml.sax.handler.ContentHandler): | |||
68 | 1405 | cmd = ['./scripts/active_edit', '-c', cve, '--yes', | 1405 | cmd = ['./scripts/active_edit', '-c', cve, '--yes', |
69 | 1406 | '--public', | 1406 | '--public', |
70 | 1407 | # set date as now | 1407 | # set date as now |
72 | 1408 | datetime.datetime.utcnow().strftime("%Y-%m-%d")] | 1408 | datetime.datetime.now(datetime.UTC).strftime("%Y-%m-%d")] |
73 | 1409 | if breakfix: | 1409 | if breakfix: |
74 | 1410 | cmd.extend(['-k']) | 1410 | cmd.extend(['-k']) |
75 | 1411 | for url in ref_urls: | 1411 | for url in ref_urls: |
76 | @@ -1750,7 +1750,7 @@ def refresh_cves(cve_refresh_list, full_refresh=True): | |||
77 | 1750 | debug("updated pubdate for %s" % (cvefile)) | 1750 | debug("updated pubdate for %s" % (cvefile)) |
78 | 1751 | 1751 | ||
79 | 1752 | # Add CVE Reference, if it's missing | 1752 | # Add CVE Reference, if it's missing |
81 | 1753 | if 'References' in data and re.match('^CVE-\d+-\d+$', cve): | 1753 | if 'References' in data and re.match(r'^CVE-\d+-\d+$', cve): |
82 | 1754 | mitre_ref = "https://cve.mitre.org/cgi-bin/cvename.cgi?name=" + cve | 1754 | mitre_ref = "https://cve.mitre.org/cgi-bin/cvename.cgi?name=" + cve |
83 | 1755 | if mitre_ref not in data['References']: | 1755 | if mitre_ref not in data['References']: |
84 | 1756 | cve_lib.add_reference(cvefile, mitre_ref) | 1756 | cve_lib.add_reference(cvefile, mitre_ref) |
85 | @@ -1808,7 +1808,7 @@ for cve in new_cves: | |||
86 | 1808 | # pick half as often, if year is 2 years ago we want to pick | 1808 | # pick half as often, if year is 2 years ago we want to pick |
87 | 1809 | # 1/4 as often etc - so do 1/2^(diff) | 1809 | # 1/4 as often etc - so do 1/2^(diff) |
88 | 1810 | year = int(re.split('-', cve)[1]) | 1810 | year = int(re.split('-', cve)[1]) |
90 | 1811 | now = datetime.datetime.utcnow().year | 1811 | now = datetime.datetime.now(datetime.UTC).year |
91 | 1812 | prob = 1.0 / math.pow(2, now - year) | 1812 | prob = 1.0 / math.pow(2, now - year) |
92 | 1813 | rand = random.random() | 1813 | rand = random.random() |
93 | 1814 | if rand > prob: | 1814 | if rand > prob: |
94 | diff --git a/scripts/oval_lib.py b/scripts/oval_lib.py | |||
95 | 1815 | old mode 100644 | 1815 | old mode 100644 |
96 | 1816 | new mode 100755 | 1816 | new mode 100755 |
97 | index d60c6dc..ace0cb3 | |||
98 | --- a/scripts/oval_lib.py | |||
99 | +++ b/scripts/oval_lib.py | |||
100 | @@ -29,7 +29,6 @@ import tempfile | |||
101 | 29 | import collections | 29 | import collections |
102 | 30 | import glob | 30 | import glob |
103 | 31 | import xml.etree.cElementTree as etree | 31 | import xml.etree.cElementTree as etree |
104 | 32 | import json | ||
105 | 33 | from xml.dom import minidom | 32 | from xml.dom import minidom |
106 | 34 | from typing import Tuple # Needed because of Python < 3.9 and to also support < 3.7 | 33 | from typing import Tuple # Needed because of Python < 3.9 and to also support < 3.7 |
107 | 35 | 34 | ||
108 | @@ -105,15 +104,15 @@ def is_kernel_binaries(binaries): | |||
109 | 105 | """ | 104 | """ |
110 | 106 | def process_kernel_binaries(binaries, oval_format): | 105 | def process_kernel_binaries(binaries, oval_format): |
111 | 107 | packages = ' '.join(binaries) | 106 | packages = ' '.join(binaries) |
113 | 108 | parts = re.findall('linux-image-[a-z]*-?([\d|\.]+-)\d+(-[\w|-]+)', packages) | 107 | parts = re.findall(r'linux-image-[a-z]*-?([\d|\.]+-)\d+(-[\w|-]+)', packages) |
114 | 109 | if parts: | 108 | if parts: |
115 | 110 | values = set(map(lambda x: x[0], parts)) | 109 | values = set(map(lambda x: x[0], parts)) |
116 | 111 | version = ''.join(values) | 110 | version = ''.join(values) |
117 | 112 | values = sorted(set(map(lambda x: x[1], parts))) | 111 | values = sorted(set(map(lambda x: x[1], parts))) |
118 | 113 | flavours = '|'.join(values) | 112 | flavours = '|'.join(values) |
120 | 114 | regex = version + '\d+(' + flavours + ')' | 113 | regex = version + r'\d+(' + flavours + ')' |
121 | 115 | if oval_format == 'oci': | 114 | if oval_format == 'oci': |
123 | 116 | regex = 'linux-image-(?:unsigned-)?' + version + '\d+(?:' + flavours + ')' | 115 | regex = 'linux-image-(?:unsigned-)?' + version + r'\d+(?:' + flavours + ')' |
124 | 117 | return regex | 116 | return regex |
125 | 118 | 117 | ||
126 | 119 | return None | 118 | return None |
127 | @@ -312,7 +311,7 @@ class CVE: | |||
128 | 312 | for url in info['References'].split('\n'): | 311 | for url in info['References'].split('\n'): |
129 | 313 | if 'https://ubuntu.com/security/notices/USN-' in url: | 312 | if 'https://ubuntu.com/security/notices/USN-' in url: |
130 | 314 | self.usns.append(url[40:]) | 313 | self.usns.append(url[40:]) |
132 | 315 | elif re.match("https?:\/\/(bugs\.)?launchpad\.net\/(.*\/\+bug|bugs)\/\d+", url): | 314 | elif re.match(r"https?:\/\/(bugs\.)?launchpad\.net\/(.*\/\+bug|bugs)\/\d+", url): |
133 | 316 | self.bugs.append(url) | 315 | self.bugs.append(url) |
134 | 317 | elif url: | 316 | elif url: |
135 | 318 | self.references.append(url) | 317 | self.references.append(url) |
136 | @@ -711,7 +710,7 @@ class OvalGenerator: | |||
137 | 711 | instance = etree.SubElement(object, "ind-def:instance",attrib={"datatype": "int"}) | 710 | instance = etree.SubElement(object, "ind-def:instance",attrib={"datatype": "int"}) |
138 | 712 | 711 | ||
139 | 713 | filepath.text = "/etc/lsb-release" | 712 | filepath.text = "/etc/lsb-release" |
141 | 714 | pattern.text = "^[\s\S]*DISTRIB_CODENAME=([a-z]+)$" | 713 | pattern.text = r"^[\s\S]*DISTRIB_CODENAME=([a-z]+)$" |
142 | 715 | instance.text = "1" | 714 | instance.text = "1" |
143 | 716 | else: | 715 | else: |
144 | 717 | family_object = etree.Element("") | 716 | family_object = etree.Element("") |
145 | @@ -1034,7 +1033,7 @@ class OvalGenerator: | |||
146 | 1034 | 1033 | ||
147 | 1035 | final_binaries = [] | 1034 | final_binaries = [] |
148 | 1036 | if self.oval_format == 'oci': | 1035 | if self.oval_format == 'oci': |
150 | 1037 | variable_values = '(?::\w+|)\s+(.*)$' | 1036 | variable_values = r'(?::\w+|)\s+(.*)$' |
151 | 1038 | for binary in binaries: | 1037 | for binary in binaries: |
152 | 1039 | final_binaries.append(f'^{binary}{variable_values}') | 1038 | final_binaries.append(f'^{binary}{variable_values}') |
153 | 1040 | else: | 1039 | else: |
154 | @@ -1060,9 +1059,9 @@ class OvalGenerator: | |||
155 | 1060 | if self.oval_format == 'oci': | 1059 | if self.oval_format == 'oci': |
156 | 1061 | if package.is_kernel_pkg: | 1060 | if package.is_kernel_pkg: |
157 | 1062 | regex = process_kernel_binaries(binaries, 'oci') | 1061 | regex = process_kernel_binaries(binaries, 'oci') |
159 | 1063 | final_binaries = [f'^{regex}(?::\w+|)\s+(.*)$'] | 1062 | final_binaries = [rf'^{regex}(?::\w+|)\s+(.*)$'] |
160 | 1064 | else: | 1063 | else: |
162 | 1065 | variable_values = '(?::\w+|)\s+(.*)$' | 1064 | variable_values = r'(?::\w+|)\s+(.*)$' |
163 | 1066 | 1065 | ||
164 | 1067 | final_binaries = [] | 1066 | final_binaries = [] |
165 | 1068 | for binary in binaries: | 1067 | for binary in binaries: |
166 | @@ -1098,7 +1097,7 @@ class OvalGenerator: | |||
167 | 1098 | concat = etree.SubElement(var, "concat") | 1097 | concat = etree.SubElement(var, "concat") |
168 | 1099 | component = etree.SubElement(concat, "literal_component") | 1098 | component = etree.SubElement(concat, "literal_component") |
169 | 1100 | regex = etree.SubElement(concat, "regex_capture", attrib={ | 1099 | regex = etree.SubElement(concat, "regex_capture", attrib={ |
171 | 1101 | "pattern": "^([\d|\.]+-\d+)[-|\w]+$" | 1100 | "pattern": r"^([\d|\.]+-\d+)[-|\w]+$" |
172 | 1102 | }) | 1101 | }) |
173 | 1103 | 1102 | ||
174 | 1104 | etree.SubElement(regex, "object_component", attrib={ | 1103 | etree.SubElement(regex, "object_component", attrib={ |
175 | @@ -1171,7 +1170,7 @@ class OvalGenerator: | |||
176 | 1171 | return object | 1170 | return object |
177 | 1172 | 1171 | ||
178 | 1173 | def _generate_state_kernel_element(self, comment, id, version) -> None: | 1172 | def _generate_state_kernel_element(self, comment, id, version) -> None: |
180 | 1174 | patched = re.search('([\d|\.]+-\d+)[\.|\d]+', version) | 1173 | patched = re.search(r'([\d|\.]+-\d+)[\.|\d]+', version) |
181 | 1175 | if patched: | 1174 | if patched: |
182 | 1176 | patched = patched.group(1) | 1175 | patched = patched.group(1) |
183 | 1177 | else: | 1176 | else: |
184 | @@ -1285,9 +1284,9 @@ class OvalGenerator: | |||
185 | 1285 | if self.oval_format == 'oci': | 1284 | if self.oval_format == 'oci': |
186 | 1286 | if package.is_kernel_pkg: | 1285 | if package.is_kernel_pkg: |
187 | 1287 | regex = process_kernel_binaries(binaries, 'oci') | 1286 | regex = process_kernel_binaries(binaries, 'oci') |
189 | 1288 | final_binaries = [f'^{regex}(?::\w+|)\s+(.*)$'] | 1287 | final_binaries = [rf'^{regex}(?::\w+|)\s+(.*)$'] |
190 | 1289 | else: | 1288 | else: |
192 | 1290 | variable_values = '(?::\w+|)\s+(.*)$' | 1289 | variable_values = r'(?::\w+|)\s+(.*)$' |
193 | 1291 | 1290 | ||
194 | 1292 | final_binaries = [] | 1291 | final_binaries = [] |
195 | 1293 | for binary in binaries: | 1292 | for binary in binaries: |
196 | @@ -2065,7 +2064,7 @@ class OvalGeneratorUSN(): | |||
197 | 2065 | def create_release_object(self): | 2064 | def create_release_object(self): |
198 | 2066 | if self.oval_format == 'dpkg': | 2065 | if self.oval_format == 'dpkg': |
199 | 2067 | _object =\ | 2066 | _object =\ |
201 | 2068 | f""" | 2067 | rf""" |
202 | 2069 | <ind:family_object id="{self.ns}:obj:{self.id}" version="1" comment="The singleton family object."/> | 2068 | <ind:family_object id="{self.ns}:obj:{self.id}" version="1" comment="The singleton family object."/> |
203 | 2070 | <ind:textfilecontent54_object id="{self.ns}:obj:{self.id+1}" version="1"> | 2069 | <ind:textfilecontent54_object id="{self.ns}:obj:{self.id+1}" version="1"> |
204 | 2071 | <ind:filepath datatype="string">/etc/lsb-release</ind:filepath> | 2070 | <ind:filepath datatype="string">/etc/lsb-release</ind:filepath> |
205 | @@ -2099,7 +2098,7 @@ class OvalGeneratorUSN(): | |||
206 | 2099 | bugs = "" | 2098 | bugs = "" |
207 | 2100 | 2099 | ||
208 | 2101 | for url in urls: | 2100 | for url in urls: |
210 | 2102 | is_bug = re.match("https?:\/\/(bugs\.)?launchpad\.net\/(.*\/\+bug|bugs)\/\d+", url) | 2101 | is_bug = re.match(r"https?:\/\/(bugs\.)?launchpad\.net\/(.*\/\+bug|bugs)\/\d+", url) |
211 | 2103 | 2102 | ||
212 | 2104 | if is_bug: | 2103 | if is_bug: |
213 | 2105 | bug_urls.append(url) | 2104 | bug_urls.append(url) |
214 | @@ -2373,7 +2372,7 @@ class OvalGeneratorUSN(): | |||
215 | 2373 | 2372 | ||
216 | 2374 | elif 'kernelobj' in test_ref: | 2373 | elif 'kernelobj' in test_ref: |
217 | 2375 | binary_version = test_ref['version'] | 2374 | binary_version = test_ref['version'] |
219 | 2376 | binary_version = re.search('([\d|\.]+-\d+)[\.|\d]+', binary_version) | 2375 | binary_version = re.search(r'([\d|\.]+-\d+)[\.|\d]+', binary_version) |
220 | 2377 | mapping['bversion'] = "0:" + binary_version.group(1) | 2376 | mapping['bversion'] = "0:" + binary_version.group(1) |
221 | 2378 | 2377 | ||
222 | 2379 | state = \ | 2378 | state = \ |
223 | @@ -2431,7 +2430,7 @@ class OvalGeneratorUSN(): | |||
224 | 2431 | if self.oval_format == 'dpkg': | 2430 | if self.oval_format == 'dpkg': |
225 | 2432 | if 'kernel' in test_ref: | 2431 | if 'kernel' in test_ref: |
226 | 2433 | variable = \ | 2432 | variable = \ |
228 | 2434 | """ | 2433 | r""" |
229 | 2435 | <local_variable id="{ns}:var:{id}" datatype="debian_evr_string" version="1" comment="kernel version in evr format"> | 2434 | <local_variable id="{ns}:var:{id}" datatype="debian_evr_string" version="1" comment="kernel version in evr format"> |
230 | 2436 | <concat> | 2435 | <concat> |
231 | 2437 | <literal_component>0:</literal_component> | 2436 | <literal_component>0:</literal_component> |
232 | @@ -2453,7 +2452,7 @@ class OvalGeneratorUSN(): | |||
233 | 2453 | else: | 2452 | else: |
234 | 2454 | for binary in binaries_list: | 2453 | for binary in binaries_list: |
235 | 2455 | values += \ | 2454 | values += \ |
237 | 2456 | """<value>^{}(?::\w+|)\s+(.*)$</value> | 2455 | r"""<value>^{}(?::\w+|)\s+(.*)$</value> |
238 | 2457 | """.format(binary) | 2456 | """.format(binary) |
239 | 2458 | 2457 | ||
240 | 2459 | mapping['values'] = values.strip() | 2458 | mapping['values'] = values.strip() |
241 | @@ -2504,7 +2503,7 @@ class OvalGeneratorUSN(): | |||
242 | 2504 | urls = [] | 2503 | urls = [] |
243 | 2505 | for cve in cves: | 2504 | for cve in cves: |
244 | 2506 | # Takes urls from the list | 2505 | # Takes urls from the list |
246 | 2507 | is_url = re.match('(www|http:|https:)+[^\s]+[\w]', cve) | 2506 | is_url = re.match(r'(www|http:|https:)+[^\s]+[\w]', cve) |
247 | 2508 | 2507 | ||
248 | 2509 | if is_url: | 2508 | if is_url: |
249 | 2510 | urls.append(cve) | 2509 | urls.append(cve) |
For the datetime changes,
- public_date = datetime. datetime. utcnow( ).strftime( "%Y-%m- %d") datetime. now(datetime. UTC).strftime( "%Y-%m- %d")
+ public_date = datetime.
datetime.UTC was introduced in python 3.11 (so ubuntu 23.10, mantic), so jammy and older won't have this. We'll want to use datetime. timezone. utc instead; while most people should be running mantic or newer, we do have team members and systems running older releases than that. Given that datetime. datetime. now(datetime. timezone. utc) is a bit unwieldy, we could do something like:
from datetime import datetime, timezone now(timezone. utc).strftime( "%Y-%m- %d")
public_date = datetime.
Thanks.