diff --git a/searx/engines/acfun.py b/searx/engines/acfun.py index 90922680f..6f4045085 100644 --- a/searx/engines/acfun.py +++ b/searx/engines/acfun.py @@ -83,7 +83,7 @@ def extract_video_data(video_block): published_date = None if create_time: try: - published_date = datetime.strptime(create_time.strip(), "%Y-%m-%d") + published_date = datetime.fromisoformat(create_time.strip()) except (ValueError, TypeError): pass diff --git a/searx/engines/arxiv.py b/searx/engines/arxiv.py index c6fbb71a7..5789a6a10 100644 --- a/searx/engines/arxiv.py +++ b/searx/engines/arxiv.py @@ -109,7 +109,7 @@ def response(resp: "SXNG_Response") -> EngineResults: comments_elements = eval_xpath_getindex(entry, xpath_comment, 0, default=None) comments: str = "" if comments_elements is None else comments_elements.text - publishedDate = datetime.strptime(eval_xpath_getindex(entry, xpath_published, 0).text, "%Y-%m-%dT%H:%M:%SZ") + publishedDate = datetime.fromisoformat(eval_xpath_getindex(entry, xpath_published, 0).text.rstrip("Z")) res.add( res.types.Paper( diff --git a/searx/engines/baidu.py b/searx/engines/baidu.py index fad3ababa..8aa2f2f6f 100644 --- a/searx/engines/baidu.py +++ b/searx/engines/baidu.py @@ -186,7 +186,7 @@ def parse_images(data): img_date = item.get("bdImgnewsDate") publishedDate = None if img_date: - publishedDate = datetime.strptime(img_date, "%Y-%m-%d %H:%M") + publishedDate = datetime.fromisoformat(img_date) results.append( { "template": "images.html", diff --git a/searx/engines/bitchute.py b/searx/engines/bitchute.py index 88170c949..ef1de1308 100644 --- a/searx/engines/bitchute.py +++ b/searx/engines/bitchute.py @@ -44,7 +44,7 @@ def response(resp): "url": 'https://www.bitchute.com/video/' + item['video_id'], "content": html_to_text(item['description']), "author": item['channel']['channel_name'], - "publishedDate": datetime.strptime(item["date_published"], "%Y-%m-%dT%H:%M:%S.%fZ"), + "publishedDate": datetime.fromisoformat(item["date_published"].rstrip("Z")), "length": item['duration'], "views": item['view_count'], "thumbnail": item['thumbnail_url'], diff --git a/searx/engines/boardreader.py b/searx/engines/boardreader.py index 9b56295b3..b5baa5c3f 100644 --- a/searx/engines/boardreader.py +++ b/searx/engines/boardreader.py @@ -104,7 +104,7 @@ def response(resp: "SXNG_Response") -> EngineResults: title=_remove_keyword_marker(result["Subject"]), content=_remove_keyword_marker(result["Text"]), url=result["Url"], - publishedDate=datetime.strptime(result["Published"], "%Y-%m-%d %H:%M:%S"), + publishedDate=datetime.fromisoformat(result["Published"]), metadata=gettext.gettext("Posted by {author}").format(author=result["Author"]), ) ) diff --git a/searx/engines/chefkoch.py b/searx/engines/chefkoch.py index 99dd5b918..fcebdc517 100644 --- a/searx/engines/chefkoch.py +++ b/searx/engines/chefkoch.py @@ -43,7 +43,7 @@ def response(resp): publishedDate = None if recipe['submissionDate']: - publishedDate = datetime.strptime(result['recipe']['submissionDate'][:19], "%Y-%m-%dT%H:%M:%S") + publishedDate = datetime.fromisoformat(result['recipe']['submissionDate'][:19]) content = [ f"Schwierigkeitsstufe (1-3): {recipe['difficulty']}", diff --git a/searx/engines/findthatmeme.py b/searx/engines/findthatmeme.py index adfb347a7..dba9c0584 100644 --- a/searx/engines/findthatmeme.py +++ b/searx/engines/findthatmeme.py @@ -37,7 +37,7 @@ def response(resp): for item in search_res: img = 'https://s3.thehackerblog.com/findthatmeme/' + item['image_path'] thumb = 'https://s3.thehackerblog.com/findthatmeme/thumb/' + item.get('thumbnail', '') - date = datetime.strptime(item["updated_at"].split("T")[0], "%Y-%m-%d") + date = datetime.fromisoformat(item["updated_at"].split("T")[0]) formatted_date = datetime.fromtimestamp(date.timestamp()) results.append( diff --git a/searx/engines/fyyd.py b/searx/engines/fyyd.py index ad96c9d57..e80f861a6 100644 --- a/searx/engines/fyyd.py +++ b/searx/engines/fyyd.py @@ -47,7 +47,7 @@ def response(resp: "SXNG_Response"): title=result["title"], content=result["description"], thumbnail=result["smallImageURL"], - publishedDate=datetime.strptime(result["status_since"], "%Y-%m-%d %H:%M:%S"), + publishedDate=datetime.fromisoformat(result["status_since"]), metadata=f"Rank: {result['rank']} || {result['episode_count']} episodes", ) ) diff --git a/searx/engines/huggingface.py b/searx/engines/huggingface.py index b49bb3f21..908eb2052 100644 --- a/searx/engines/huggingface.py +++ b/searx/engines/huggingface.py @@ -91,7 +91,7 @@ def response(resp) -> EngineResults: published_date = None try: - published_date = datetime.strptime(entry["createdAt"], "%Y-%m-%dT%H:%M:%S.%fZ") + published_date = datetime.fromisoformat(entry["createdAt"].rstrip("Z")) except (ValueError, TypeError): pass diff --git a/searx/engines/iqiyi.py b/searx/engines/iqiyi.py index b0bb38535..9dc483c69 100644 --- a/searx/engines/iqiyi.py +++ b/searx/engines/iqiyi.py @@ -43,7 +43,7 @@ def _result(video: dict[str, typing.Any], album_info: dict[str, typing.Any]): release_time = album_info.get("releaseTime", {}).get("value") if release_time: try: - published_date = datetime.strptime(release_time, "%Y-%m-%d") + published_date = datetime.fromisoformat(release_time) except (ValueError, TypeError): pass diff --git a/searx/engines/lemmy.py b/searx/engines/lemmy.py index d301de4c6..8cbc7f00d 100644 --- a/searx/engines/lemmy.py +++ b/searx/engines/lemmy.py @@ -92,7 +92,7 @@ def _get_communities(json): 'title': result['community']['title'], 'content': markdown_to_text(result['community'].get('description', '')), 'thumbnail': result['community'].get('icon', result['community'].get('banner')), - 'publishedDate': datetime.strptime(counts['published'][:19], '%Y-%m-%dT%H:%M:%S'), + 'publishedDate': datetime.fromisoformat(counts['published'][:19]), 'metadata': metadata, } ) @@ -141,7 +141,7 @@ def _get_posts(json): 'title': result['post']['name'], 'content': content, 'thumbnail': thumbnail, - 'publishedDate': datetime.strptime(result['post']['published'][:19], '%Y-%m-%dT%H:%M:%S'), + 'publishedDate': datetime.fromisoformat(result['post']['published'][:19]), 'metadata': metadata, } ) @@ -170,7 +170,7 @@ def _get_comments(json): 'url': result['comment']['ap_id'], 'title': result['post']['name'], 'content': markdown_to_text(result['comment']['content']), - 'publishedDate': datetime.strptime(result['comment']['published'][:19], '%Y-%m-%dT%H:%M:%S'), + 'publishedDate': datetime.fromisoformat(result['comment']['published'][:19]), 'metadata': metadata, } ) diff --git a/searx/engines/mastodon.py b/searx/engines/mastodon.py index b7b05cfb5..57e42d1fa 100644 --- a/searx/engines/mastodon.py +++ b/searx/engines/mastodon.py @@ -60,7 +60,7 @@ def response(resp): 'title': result['username'] + f" ({result['followers_count']} followers)", 'content': result['note'], 'thumbnail': result.get('avatar'), - 'publishedDate': datetime.strptime(result['created_at'][:10], "%Y-%m-%d"), + 'publishedDate': datetime.fromisoformat(result['created_at'][:10]), } ) elif mastodon_type == "hashtags": diff --git a/searx/engines/nvd.py b/searx/engines/nvd.py index a6abbc2a9..43d40cd19 100644 --- a/searx/engines/nvd.py +++ b/searx/engines/nvd.py @@ -44,7 +44,7 @@ def response(resp) -> EngineResults: cve_id = item["cve"]["id"] description = item["cve"]["descriptions"][0]["value"] - date = datetime.strptime(item["cve"]["published"], "%Y-%m-%dT%H:%M:%S.%f") + date = datetime.fromisoformat(item["cve"]["published"]) # Extract severity (Low, Medium, High, or Critical) and CVSS score, if available info = item["cve"].get("metrics", {}).get("cvssMetricV31", [{}])[0].get("cvssData", {}) diff --git a/searx/engines/odysee.py b/searx/engines/odysee.py index 1e2a61f75..e7d222370 100644 --- a/searx/engines/odysee.py +++ b/searx/engines/odysee.py @@ -76,7 +76,7 @@ def response(resp): release_time = item["release_time"] duration = item["duration"] - release_date = datetime.strptime(release_time.split("T")[0], "%Y-%m-%d") + release_date = datetime.fromisoformat(release_time.split("T")[0]) formatted_date = datetime.fromtimestamp(release_date.timestamp()) url = f"https://odysee.com/{name}:{claim_id}" diff --git a/searx/engines/podchaser.py b/searx/engines/podchaser.py index b95de7e85..2e2266a01 100644 --- a/searx/engines/podchaser.py +++ b/searx/engines/podchaser.py @@ -54,7 +54,7 @@ def response(resp: "SXNG_Response"): title=result["title"], content=result["description"], thumbnail=result["image_url"], - publishedDate=datetime.strptime(result["created_at"], "%Y-%m-%d %H:%M:%S"), + publishedDate=datetime.fromisoformat(result["created_at"]), metadata=" | ".join(metadata), ) ) diff --git a/searx/engines/quark.py b/searx/engines/quark.py index 889f1dbae..e51fb7a26 100644 --- a/searx/engines/quark.py +++ b/searx/engines/quark.py @@ -292,7 +292,7 @@ def parse_news_uchq(data): results = [] for item in data.get('feed', []): try: - published_date = datetime.strptime(item.get('time'), "%Y-%m-%d") + published_date = datetime.fromisoformat(item.get('time')) except (ValueError, TypeError): # Sometime Quark will return non-standard format like "1天前", set published_date as None published_date = None diff --git a/searx/engines/rumble.py b/searx/engines/rumble.py index 8f84aa269..3215c13db 100644 --- a/searx/engines/rumble.py +++ b/searx/engines/rumble.py @@ -58,7 +58,7 @@ def response(resp): title = extract_text(result_dom.xpath(title_xpath)) p_date = extract_text(result_dom.xpath(published_date)) # fix offset date for line 644 webapp.py check - fixed_date = datetime.strptime(p_date, '%Y-%m-%dT%H:%M:%S%z') + fixed_date = datetime.fromisoformat(p_date) earned = extract_text(result_dom.xpath(earned_xpath)) views = extract_text(result_dom.xpath(views_xpath)) rumbles = extract_text(result_dom.xpath(rumbles_xpath)) diff --git a/searx/engines/semantic_scholar.py b/searx/engines/semantic_scholar.py index 390eccff3..473b6d04f 100644 --- a/searx/engines/semantic_scholar.py +++ b/searx/engines/semantic_scholar.py @@ -120,7 +120,7 @@ def response(resp: "SXNG_Response") -> EngineResults: publishedDate: datetime | None if "pubDate" in result: - publishedDate = datetime.strptime(result["pubDate"], "%Y-%m-%d") + publishedDate = datetime.fromisoformat(result["pubDate"]) else: publishedDate = None diff --git a/searx/engines/sogou.py b/searx/engines/sogou.py index 0eb1affa8..026f3dea7 100644 --- a/searx/engines/sogou.py +++ b/searx/engines/sogou.py @@ -95,7 +95,8 @@ def _parse_date(text): date_match = re.search(r"(\d{4}-\d{1,2}-\d{1,2})", text) if date_match: try: - return datetime.strptime(date_match.group(1), "%Y-%m-%d") + y, m, d = date_match.group(1).split("-") + return datetime(year=int(y), month=int(m), day=int(d)) except (ValueError, TypeError): pass return None diff --git a/searx/engines/sogou_videos.py b/searx/engines/sogou_videos.py index 7da7a9edb..559a3436c 100644 --- a/searx/engines/sogou_videos.py +++ b/searx/engines/sogou_videos.py @@ -54,7 +54,7 @@ def response(resp): published_date = None if entry.get("date") and entry.get("duration"): try: - published_date = datetime.strptime(entry['date'], "%Y-%m-%d") + published_date = datetime.fromisoformat(entry['date']) except (ValueError, TypeError): published_date = None diff --git a/searx/engines/springer.py b/searx/engines/springer.py index 0eba93d09..ff19f60fb 100644 --- a/searx/engines/springer.py +++ b/searx/engines/springer.py @@ -134,7 +134,7 @@ def response(resp: "SXNG_Response") -> EngineResults: return str(record.get(k, "")) for record in json_data["records"]: - published = datetime.strptime(record["publicationDate"], "%Y-%m-%d") + published = datetime.fromisoformat(record["publicationDate"]) authors: list[str] = [" ".join(author["creator"].split(", ")[::-1]) for author in record["creators"]] pdf_url = "" diff --git a/searx/engines/tagesschau.py b/searx/engines/tagesschau.py index 12d999593..94561d42e 100644 --- a/searx/engines/tagesschau.py +++ b/searx/engines/tagesschau.py @@ -81,7 +81,7 @@ def _story(item): return { 'title': item['title'], 'thumbnail': item.get('teaserImage', {}).get('imageVariants', {}).get('16x9-256'), - 'publishedDate': datetime.strptime(item['date'][:19], '%Y-%m-%dT%H:%M:%S'), + 'publishedDate': datetime.fromisoformat(item['date'][:19]), 'content': item.get('firstSentence'), 'url': item['shareURL'] if use_source_url else item['detailsweb'], } @@ -103,7 +103,7 @@ def _video(item): 'template': 'videos.html', 'title': title, 'thumbnail': item.get('teaserImage', {}).get('imageVariants', {}).get('16x9-256'), - 'publishedDate': datetime.strptime(item['date'][:19], '%Y-%m-%dT%H:%M:%S'), + 'publishedDate': datetime.fromisoformat(item['date'][:19]), 'content': item.get('firstSentence', ''), 'iframe_src': video_url, 'url': url, diff --git a/searx/engines/tineye.py b/searx/engines/tineye.py index 53c0f2861..37dfec05e 100644 --- a/searx/engines/tineye.py +++ b/searx/engines/tineye.py @@ -121,7 +121,7 @@ def parse_tineye_match(match_json): crawl_date = backlink_json.get("crawl_date") if crawl_date: - crawl_date = datetime.strptime(crawl_date, '%Y-%m-%d') + crawl_date = datetime.fromisoformat(crawl_date) else: crawl_date = datetime.min diff --git a/searx/engines/tootfinder.py b/searx/engines/tootfinder.py index bbfb7e4a0..314e3cb6e 100644 --- a/searx/engines/tootfinder.py +++ b/searx/engines/tootfinder.py @@ -51,7 +51,7 @@ def response(resp): 'title': title, 'content': html_to_text(result['content']), 'thumbnail': thumbnail, - 'publishedDate': datetime.strptime(result['created_at'], '%Y-%m-%d %H:%M:%S'), + 'publishedDate': datetime.fromisoformat(result['created_at']), } ) diff --git a/searx/engines/wallhaven.py b/searx/engines/wallhaven.py index 4ab83a562..609b9d822 100644 --- a/searx/engines/wallhaven.py +++ b/searx/engines/wallhaven.py @@ -79,7 +79,7 @@ def response(resp): 'img_src': result['path'], 'thumbnail_src': result['thumbs']['small'], 'resolution': result['resolution'].replace('x', ' x '), - 'publishedDate': datetime.strptime(result['created_at'], '%Y-%m-%d %H:%M:%S'), + 'publishedDate': datetime.fromisoformat(result['created_at']), 'img_format': result['file_type'], 'filesize': humanize_bytes(result['file_size']), }