From 2aba11601d44834464631163f0d7b4dfefdae3c4 Mon Sep 17 00:00:00 2001 From: Tianyi Zheng Date: Tue, 24 Dec 2024 06:03:23 -0800 Subject: [PATCH 1/3] Scrape categories and topics for news.py Replace existing hard-coded news categories and topics with helper functions that scrape these values. The values are scraped when the user calls a function from the news module for the first time, and the scraped values are reused in all subsequent function calls. --- Pipfile.lock | 20 +- pittapi/news.py | 121 +- requirements.txt | 4 +- tests/news_test.py | 70 +- tests/samples/news_features_articles.html | 1839 +++++++++++++++++++ tests/samples/news_pittwire.html | 1942 +++++++++++++++++++++ 6 files changed, 3933 insertions(+), 63 deletions(-) create mode 100644 tests/samples/news_features_articles.html create mode 100644 tests/samples/news_pittwire.html diff --git a/Pipfile.lock b/Pipfile.lock index fda3e41..0857dfe 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -955,11 +955,11 @@ }, "click": { "hashes": [ - "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", - "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de" + "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", + "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a" ], "markers": "python_version >= '3.7'", - "version": "==8.1.7" + "version": "==8.1.8" }, "coverage": { "extras": [ @@ -1099,11 +1099,11 @@ }, "jinja2": { "hashes": [ - "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369", - "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d" + "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb", + "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb" ], "markers": "python_version >= '3.7'", - "version": "==3.1.4" + "version": "==3.1.5" }, "markupsafe": { "hashes": [ @@ -1412,11 +1412,11 @@ }, "urllib3": { "hashes": [ - "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac", - "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9" + "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df", + "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d" ], - "markers": "python_version >= '3.8'", - "version": "==2.2.3" + "markers": "python_version >= '3.9'", + "version": "==2.3.0" }, "virtualenv": { "hashes": [ diff --git a/pittapi/news.py b/pittapi/news.py index ae1462c..e97c911 100644 --- a/pittapi/news.py +++ b/pittapi/news.py @@ -21,48 +21,20 @@ import math from requests_html import Element, HTMLResponse, HTMLSession -from typing import Literal, NamedTuple +from typing import NamedTuple NUM_ARTICLES_PER_PAGE = 20 -NEWS_BY_CATEGORY_URL = ( - "https://www.pitt.edu/pittwire/news/{category}?field_topics_target_id={topic_id}&field_article_date_value={year}" +PITT_BASE_URL = "https://www.pitt.edu" +PITTWIRE_URL = PITT_BASE_URL + "/pittwire" +FEATURES_ARTICLES_URL = PITTWIRE_URL + "/news/features-articles" +NEWS_BY_CATEGORY_URL = PITTWIRE_URL + ( + "/news/{category}?field_topics_target_id={topic_id}&field_article_date_value={year}" "&title={query}&field_category_target_id=All&page={page_num}" ) -PITT_BASE_URL = "https://www.pitt.edu" -Category = Literal["features-articles", "accolades-honors", "ones-to-watch", "announcements-and-updates"] -Topic = Literal[ - "university-news", - "health-and-wellness", - "technology-and-science", - "arts-and-humanities", - "community-impact", - "innovation-and-research", - "global", - "diversity-equity-and-inclusion", - "our-city-our-campus", - "teaching-and-learning", - "space", - "ukraine", - "sustainability", -] - -TOPIC_ID_MAP: dict[Topic, int] = { - "university-news": 432, - "health-and-wellness": 2, - "technology-and-science": 391, - "arts-and-humanities": 4, - "community-impact": 6, - "innovation-and-research": 1, - "global": 9, - "diversity-equity-and-inclusion": 8, - "our-city-our-campus": 12, - "teaching-and-learning": 7, - "space": 440, - "ukraine": 441, - "sustainability": 470, -} +CATEGORY_URL_NAME_MAP: dict[str, str] | None = None +TOPIC_ID_MAP: dict[str, int] | None = None sess = HTMLSession() @@ -87,18 +59,49 @@ def from_html(cls, article_html: Element) -> Article: return cls(title=article_title, description=article_description, url=article_url, tags=article_tags) -def _get_page_articles( - topic: Topic, - category: Category, - query: str, - year: int | None, - page_num: int, -) -> list[Article]: +def _scrape_categories() -> dict[str, str]: + response: HTMLResponse = sess.get(PITTWIRE_URL) + category_menu: Element = response.html.find("div#block-views-block-category-menu-category-menu", first=True) + category_list: list[Element] = category_menu.find("ul.hamburger-menu-list li") + category_map: dict[str, str] = {} + for category in category_list: + category_link: Element = category.find("a", first=True) + category_url_name = category_link.attrs["href"].split("/")[-1] + category_map[category.text.strip()] = category_url_name + if not category_map: + raise RuntimeError("No categories found, please open a GitHub issue") + return category_map + + +def _scrape_topics() -> dict[str, int]: + response: HTMLResponse = sess.get(FEATURES_ARTICLES_URL) + main_content: Element = response.html.xpath("/html/body/div/main/div/section", first=True) + topic_fieldset: Element = main_content.find("fieldset.form-item-field-topics-target-id", first=True) + topic_options: list[Element] = topic_fieldset.find("option") + topic_map: dict[str, int] = {} + for topic_option in topic_options: + if (topic_id := topic_option.attrs["value"].strip()) == "All": # Skip placeholder "Topics" option + continue + topic_name = topic_option.text.strip() + topic_map[topic_name] = int(topic_id) + if not topic_map: + raise RuntimeError("No topics found, please open a GitHub issue") + return topic_map + + +def _get_page_articles(topic: str, category: str, query: str, year: int | None, page_num: int) -> list[Article]: + assert CATEGORY_URL_NAME_MAP is not None + assert TOPIC_ID_MAP is not None year_str = str(year) if year else "" page_num_str = str(page_num) if page_num else "" + response: HTMLResponse = sess.get( NEWS_BY_CATEGORY_URL.format( - category=category, topic_id=TOPIC_ID_MAP[topic], year=year_str, query=query, page_num=page_num_str + category=CATEGORY_URL_NAME_MAP[category], + topic_id=TOPIC_ID_MAP[topic], + year=year_str, + query=query, + page_num=page_num_str, ) ) main_content: Element = response.html.xpath("/html/body/div/main/div/section", first=True) @@ -107,13 +110,39 @@ def _get_page_articles( return page_articles +def get_categories() -> list[str]: + global CATEGORY_URL_NAME_MAP + if not CATEGORY_URL_NAME_MAP: + CATEGORY_URL_NAME_MAP = _scrape_categories() + return list(CATEGORY_URL_NAME_MAP.keys()) + + +def get_topics() -> list[str]: + global TOPIC_ID_MAP + if not TOPIC_ID_MAP: + TOPIC_ID_MAP = _scrape_topics() + return list(TOPIC_ID_MAP.keys()) + + def get_articles_by_topic( - topic: Topic, - category: Category = "features-articles", + topic: str, + category: str = "Features & Articles", query: str = "", year: int | None = None, max_num_results: int = NUM_ARTICLES_PER_PAGE, ) -> list[Article]: + global TOPIC_ID_MAP + if not TOPIC_ID_MAP: + TOPIC_ID_MAP = _scrape_topics() + if topic not in TOPIC_ID_MAP: + raise ValueError(f"'{topic}' is not a valid topic, must be one of the following: {get_topics()}") + + global CATEGORY_URL_NAME_MAP + if not CATEGORY_URL_NAME_MAP: + CATEGORY_URL_NAME_MAP = _scrape_categories() + if category not in CATEGORY_URL_NAME_MAP: + raise ValueError(f"'{category}' is not a valid category, must be one of the following: {get_categories()}") + num_pages = math.ceil(max_num_results / NUM_ARTICLES_PER_PAGE) # Get articles sequentially and synchronously (i.e., not using grequests) because the news pages must stay in order diff --git a/requirements.txt b/requirements.txt index a5fdee1..ec14c9e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ black==24.10.0 certifi==2024.12.14 cfgv==3.4.0 charset-normalizer==3.4.0 -click==8.1.7 +click==8.1.8 coverage[toml]==7.6.9 distlib==0.3.9 docutils==0.21.2 @@ -14,7 +14,7 @@ identify==2.6.3 idna==3.10 imagesize==1.4.1 iniconfig==2.0.0 -jinja2==3.1.4 +jinja2==3.1.5 markupsafe==3.0.2 mccabe==0.7.0 mypy-extensions==1.0.0 diff --git a/tests/news_test.py b/tests/news_test.py index 203b684..eb08935 100644 --- a/tests/news_test.py +++ b/tests/news_test.py @@ -30,6 +30,10 @@ class NewsTest(unittest.TestCase): def __init__(self, *args, **kwargs): unittest.TestCase.__init__(self, *args, **kwargs) + with (SAMPLE_PATH / "news_pittwire.html").open() as f: + self.pittwire = f.read() + with (SAMPLE_PATH / "news_features_articles.html").open() as f: + self.features_articles = f.read() with (SAMPLE_PATH / "news_university_news_features_articles_page_0.html").open() as f: self.university_news_features_articles_page_0 = f.read() with (SAMPLE_PATH / "news_university_news_features_articles_page_1.html").open() as f: @@ -39,8 +43,30 @@ def __init__(self, *args, **kwargs): with (SAMPLE_PATH / "news_university_news_features_articles_2020.html").open() as f: self.university_news_features_articles_2020 = f.read() + @responses.activate + def test_get_categories(self): + if not news.CATEGORY_URL_NAME_MAP: + responses.add(responses.GET, news.PITTWIRE_URL, body=self.pittwire) + + categories = news.get_categories() + + self.assertEqual(len(categories), 4) + + @responses.activate + def test_get_topics(self): + if not news.TOPIC_ID_MAP: + responses.add(responses.GET, news.FEATURES_ARTICLES_URL, body=self.features_articles) + + topics = news.get_topics() + + self.assertEqual(len(topics), 13) + @responses.activate def test_get_articles_by_topic(self): + if not news.CATEGORY_URL_NAME_MAP: + responses.add(responses.GET, news.PITTWIRE_URL, body=self.pittwire) + if not news.TOPIC_ID_MAP: + responses.add(responses.GET, news.FEATURES_ARTICLES_URL, body=self.features_articles) responses.add( responses.GET, "https://www.pitt.edu/pittwire/news/features-articles?field_topics_target_id=432&field_article_date_value=&title=" @@ -48,7 +74,7 @@ def test_get_articles_by_topic(self): body=self.university_news_features_articles_page_0, ) - university_news_articles = news.get_articles_by_topic("university-news") + university_news_articles = news.get_articles_by_topic("University News") self.assertEqual(len(university_news_articles), news.NUM_ARTICLES_PER_PAGE) self.assertEqual( @@ -75,6 +101,10 @@ def test_get_articles_by_topic(self): @responses.activate def test_get_articles_by_topic_query(self): query = "fulbright" + if not news.CATEGORY_URL_NAME_MAP: + responses.add(responses.GET, news.PITTWIRE_URL, body=self.pittwire) + if not news.TOPIC_ID_MAP: + responses.add(responses.GET, news.FEATURES_ARTICLES_URL, body=self.features_articles) responses.add( responses.GET, "https://www.pitt.edu/pittwire/news/features-articles?field_topics_target_id=432&field_article_date_value=" @@ -82,7 +112,7 @@ def test_get_articles_by_topic_query(self): body=self.university_news_features_articles_fulbright, ) - university_news_articles = news.get_articles_by_topic("university-news", query=query) + university_news_articles = news.get_articles_by_topic("University News", query=query) self.assertEqual(len(university_news_articles), 3) self.assertEqual( @@ -115,6 +145,10 @@ def test_get_articles_by_topic_query(self): @responses.activate def test_get_articles_by_topic_year(self): year = 2020 + if not news.CATEGORY_URL_NAME_MAP: + responses.add(responses.GET, news.PITTWIRE_URL, body=self.pittwire) + if not news.TOPIC_ID_MAP: + responses.add(responses.GET, news.FEATURES_ARTICLES_URL, body=self.features_articles) responses.add( responses.GET, f"https://www.pitt.edu/pittwire/news/features-articles?field_topics_target_id=432&field_article_date_value={year}" @@ -122,7 +156,7 @@ def test_get_articles_by_topic_year(self): body=self.university_news_features_articles_2020, ) - university_news_articles = news.get_articles_by_topic("university-news", year=year) + university_news_articles = news.get_articles_by_topic("University News", year=year) self.assertEqual(len(university_news_articles), 5) self.assertEqual( @@ -152,6 +186,10 @@ def test_get_articles_by_topic_year(self): @responses.activate def test_get_articles_by_topic_less_than_one_page(self): num_results = 5 + if not news.CATEGORY_URL_NAME_MAP: + responses.add(responses.GET, news.PITTWIRE_URL, body=self.pittwire) + if not news.TOPIC_ID_MAP: + responses.add(responses.GET, news.FEATURES_ARTICLES_URL, body=self.features_articles) responses.add( responses.GET, "https://www.pitt.edu/pittwire/news/features-articles?field_topics_target_id=432&field_article_date_value=&title=" @@ -159,7 +197,7 @@ def test_get_articles_by_topic_less_than_one_page(self): body=self.university_news_features_articles_page_0, ) - university_news_articles = news.get_articles_by_topic("university-news", max_num_results=num_results) + university_news_articles = news.get_articles_by_topic("University News", max_num_results=num_results) self.assertEqual(len(university_news_articles), num_results) self.assertEqual( @@ -186,6 +224,10 @@ def test_get_articles_by_topic_less_than_one_page(self): @responses.activate def test_get_articles_by_topic_multiple_pages(self): num_results = news.NUM_ARTICLES_PER_PAGE + 5 + if not news.CATEGORY_URL_NAME_MAP: + responses.add(responses.GET, news.PITTWIRE_URL, body=self.pittwire) + if not news.TOPIC_ID_MAP: + responses.add(responses.GET, news.FEATURES_ARTICLES_URL, body=self.features_articles) responses.add( responses.GET, "https://www.pitt.edu/pittwire/news/features-articles?field_topics_target_id=432&field_article_date_value=&title=" @@ -199,7 +241,7 @@ def test_get_articles_by_topic_multiple_pages(self): body=self.university_news_features_articles_page_1, ) - university_news_articles = news.get_articles_by_topic("university-news", max_num_results=num_results) + university_news_articles = news.get_articles_by_topic("University News", max_num_results=num_results) self.assertEqual(len(university_news_articles), num_results) self.assertEqual( @@ -227,3 +269,21 @@ def test_get_articles_by_topic_multiple_pages(self): ], ), ) + + @responses.activate + def test_get_articles_by_topic_invalid_category(self): + if not news.CATEGORY_URL_NAME_MAP: + responses.add(responses.GET, news.PITTWIRE_URL, body=self.pittwire) + if not news.TOPIC_ID_MAP: + responses.add(responses.GET, news.FEATURES_ARTICLES_URL, body=self.features_articles) + + self.assertRaises(ValueError, news.get_articles_by_topic, "University News", "Invalid Category") + + @responses.activate + def test_get_articles_by_topic_invalid_topic(self): + if not news.CATEGORY_URL_NAME_MAP: + responses.add(responses.GET, news.PITTWIRE_URL, body=self.pittwire) + if not news.TOPIC_ID_MAP: + responses.add(responses.GET, news.FEATURES_ARTICLES_URL, body=self.features_articles) + + self.assertRaises(ValueError, news.get_articles_by_topic, "Invalid Topic") diff --git a/tests/samples/news_features_articles.html b/tests/samples/news_features_articles.html new file mode 100644 index 0000000..7dce0c4 --- /dev/null +++ b/tests/samples/news_features_articles.html @@ -0,0 +1,1839 @@ + + + + + + + + + + + + + + + + Pittwire News | University of Pittsburgh + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + + +
+
+
+
+
+ +
+
+ + +
+
+
+
+
+ + + + + + + + + + + +
+ +
+ +
+
+
+ + +
+
+ +
+
+
+

Filter By

+
+
+ +
+ + +
+ + + + + +
+
+ + +
+ +
+ +
+
+
+ +
+
+ + +
+
+ + Baseball player throwing a pitch in a crowded stadium. + + + + + +
+

This Pittsburgh Pirates pitcher is taking a swing at raising mental health awareness +

+

+ A family trauma almost toppled Pitt alum Isaac Mattson’s dream. A career roadblock may have saved it. +

+ +
    +
  • + Health and Wellness +
  • +
  • + Community Impact +
  • +
+ +
+ + +
+
+ + Pitt-Greensburg graduates pose for a portrait during the campus' first-ever winter commencement celebration. + + + + + +
+

Pitt-Greensburg held its first winter commencement ceremony +

+

+ President Robert Gregerson and other campus leaders recognized the 39 students who completed their degree requirements in the summer and fall semesters. +

+ +
    +
  • + University News +
  • +
  • + Community Impact +
  • +
  • + Pitt-Greensburg +
  • +
  • + Cultivate student success +
  • +
  • + Commencement +
  • +
+ +
+ + +
+
+ + Confetti falls over winter commencement graduates and attendees. + + + + + +
+

Pitt celebrated its newest Class of 2024 graduates at winter commencement +

+

+ See a gallery of the ceremony, which included speeches by Holden Thorp and Mihika Shah. +

+ +
    +
  • + University News +
  • +
  • + Cultivate student success +
  • +
  • + Commencement +
  • +
+ +
+ + +
+
+ + Charles Rinaldo poses for a portrait in the lab with a colleague. + + + + + +
+

40 years later, the Pitt Men’s Study is still breaking ground in the fight against AIDS +

+

+ We spoke with principal investigator Charles Rinaldo and longtime participant and volunteer Marc Wagner about how the study has impacted their lives over the decades. +

+ +
    +
  • + Community Impact +
  • +
  • + Innovation and Research +
  • +
  • + Propel scholarship, creativity and innovation +
  • +
  • + Promote accountability and trust +
  • +
  • + School of Medicine +
  • +
  • + School of Public Health +
  • +
+ +
+ + +
+
+ + MLS participants smile and engage during the program's December retreat. + + + + + +
+

Nearly half of new moms in STEM leave their full-time positions. This Pitt program wants to change that. +

+

+ Mothers Leading Science is helping health sciences faculty find a supportive community, strategies for work-life integration and renewed passion for their research. +

+ +
    +
  • + Innovation and Research +
  • +
  • + Diversity, Equity, and Inclusion +
  • +
  • + Propel scholarship, creativity and innovation +
  • +
  • + Be welcoming and engaged +
  • +
  • + School of Medicine +
  • +
+ +
+ + +
+
+ + Students in Jennifer Hirsch’s Social Psychology of Reality TV course deliberate. + + + + + +
+

This Pitt professor designed a ‘Survivor’-style game to teach social psychology lessons +

+

+ Jennifer Hirsch’s unique course lets students get in the heads of reality stars — and learn some lessons while they’re in there. +

+ +
    +
  • + Arts and Humanities +
  • +
  • + Teaching & Learning +
  • +
  • + Cultivate student success +
  • +
  • + Kenneth P. Dietrich School of Arts and Sciences +
  • +
+ +
+ + +
+
+ + The Cathedral of Learning + + + + + +
+

5 Pitt students received Gilman Scholarships +

+

+ The undergraduates will travel to South America, Taiwan and more through the program, which supports Federal Pell Grant recipients with up to $5,000 during their study abroad experience. +

+ +
    +
  • + University News +
  • +
  • + Global +
  • +
+ +
+ + +
+
+ + A person in blue doctoral regalia hugs someone in a grey shawl + + + + + +
+

A guest’s guide to commencement at the University of Pittsburgh +

+

+ Everything you need to know about parking, pictures, accessibility and more for your time on the Pittsburgh campus. +

+ +
    +
  • + University News +
  • +
  • + Pittsburgh Campus +
  • +
  • + Commencement +
  • +
+ +
+ + +
+
+ + Portrait of Charles “Chas” Bonasorte at The Pittsburgh Stop Inc. + + + + + +
+

Chas Bonasorte, Pitt football’s ‘Kamikaze Kid’ and owner of famed Pitt apparel kiosk, died at 70 +

+

+ After his career on the field, Bonasorte became a fixture on the Pittsburgh campus with his clothing kiosk at Forbes and Bigelow. +

+ +
    +
  • + Community Impact +
  • +
  • + Alumni +
  • +
  • + Be welcoming and engaged +
  • +
+ +
+ + +
+
+ + Students embrace on the field of the Acrisure Stadium during a Homecoming Football game. + + + + + +
+

2024 at Pitt, in photos +

+

+ Our photographers shared their 10 favorite images of innovative researchers, major developments and more from the year. +

+ +
    +
  • + Technology & Science +
  • +
  • + Community Impact +
  • +
  • + Innovation and Research +
  • +
  • + Promote accountability and trust +
  • +
+ +
+ + +
+
+ + Man with dark hair sits in a wooded area and smiles for camera. + + + + + +
+

Live from New York, it’s Ben Asciutto +

+

+ This Pitt alum’s childhood aspirations of working in the entertainment industry are coming true on the set of ‘Saturday Night Live.’ +

+ +
    +
  • + Arts and Humanities +
  • +
  • + Cultivate student success +
  • +
  • + Kenneth P. Dietrich School of Arts and Sciences +
  • +
+ +
+ + +
+
+ + Three researchers in a lab + + + + + +
+

Chronic pain treatments can be dangerous and ineffective. These Pitt researchers are working on a solution. +

+

+ Supported by NIH funding, the Vanish Therapeutics team is working to bring a bioabsorbable nerve stimulator to market. +

+ +
    +
  • + Health and Wellness +
  • +
  • + Innovation and Research +
  • +
+ +
+ + +
+
+ + A branded Pitt flag with the University shield is framed by fall leaves. + + + + + +
+

ICYMI: Pitt contributed $6.6 billion to Pennsylvania in FY23 +

+

+ The latest Economic Impact Report showed the University supported nearly 49,000 jobs and contributed $356.2 million in state and local taxes. +

+ +
    +
  • + University News +
  • +
  • + Community Impact +
  • +
  • + Propel scholarship, creativity and innovation +
  • +
  • + Promote accountability and trust +
  • +
+ +
+ + +
+
+ + Fang on a staircase in the Honors College + + + + + +
+

This Pitt senior and cancer researcher is one to keep watching +

+

+ Here’s what’s next for Richard Su Fang, a Goldwater scholar who has already received interview invitations from 17 MD/PhD programs. +

+ +
    +
  • + Health and Wellness +
  • +
  • + Community Impact +
  • +
  • + Innovation and Research +
  • +
  • + Cultivate student success +
  • +
  • + David C. Frederick Honors College +
  • +
+ +
+ + +
+
+ + An adult and child volunteer help prepare meals for Christmas Day at Pitt. + + + + + +
+

Volunteers will spread cheer, presents and thousands of meals for Christmas Day at Pitt +

+

+ 156 people will serve at the University’s 19th annual celebration on Dec. 25. +

+ +
    +
  • + Community Impact +
  • +
  • + Our City/Our Campus +
  • +
  • + Be welcoming and engaged +
  • +
+ +
+ + +
+
+ + The Nonprofit Capacity Building Program cohort poses for a group photo at Café Momentum. + + + + + +
+

Nonprofits are scaling up their regional impact with support from Pitt +

+

+ The Nonprofit Capacity Building Program connects local organizations working to improve economic stability with University training and resources. +

+ +
    +
  • + Health and Wellness +
  • +
  • + Community Impact +
  • +
  • + Innovation and Research +
  • +
  • + Diversity, Equity, and Inclusion +
  • +
  • + Our City/Our Campus +
  • +
  • + Propel scholarship, creativity and innovation +
  • +
+ +
+ + +
+
+ + People stand in front of a Pitt health sciences backdrop + + + + + +
+

A new Pitt center will use AI to accelerate women’s health research globally +

+

+ The Vijayalakshmi Innovation Center is funded by a gift from siblings and health care entrepreneurs Vishnu Vardhan and Harsha Vardhini, along with a significant investment from the School of Medicine. +

+ +
    +
  • + Health and Wellness +
  • +
  • + Innovation and Research +
  • +
  • + Global +
  • +
  • + Propel scholarship, creativity and innovation +
  • +
  • + It's Possible at Pitt +
  • +
  • + School of Medicine +
  • +
+ +
+ + +
+
+ + People in yellow vests tour a construction site + + + + + +
+

Pitt’s new building at Fifth and Halket will support health sciences, medicine and online learning +

+

+ The University’s Property and Facilities Committee and Board of Trustees approved interior fit out projects for the Department of Computational and Systems Biology and Pitt EDGE on Dec. 5. +

+ +
    +
  • + University News +
  • +
  • + Our City/Our Campus +
  • +
  • + School of Health and Rehabilitation Sciences +
  • +
  • + School of Medicine +
  • +
+ +
+ + +
+
+ + Alexander Deiters and Jason Lohmueller in the lab + + + + + +
+

How this Pitt duo’s startup plans to attack the ‘tricky beast’ that is cancer +

+

+ A platform developed by Jason Lohmueller and Alex Dieters could allow immunotherapies to be delivered to tumors with more flexibility and precision. +

+ +
    +
  • + Innovation and Research +
  • +
  • + Innovation Institute +
  • +
  • + It's Possible at Pitt +
  • +
  • + Kenneth P. Dietrich School of Arts and Sciences +
  • +
  • + School of Medicine +
  • +
+ +
+ + +
+
+ + Applied Physiology Lab researchers conduct a spaceflight hibernation study on a volunteer. + + + + + +
+

A NASA-funded Pitt team is exploring the benefits of sleeping in space +

+

+ Kate Flickinger’s research on lower metabolic rates could help astronauts safely undergo long-duration spaceflights one day. It could also help ICU patients here on Earth. +

+ +
    +
  • + Technology & Science +
  • +
  • + Innovation and Research +
  • +
  • + Propel scholarship, creativity and innovation +
  • +
  • + School of Medicine +
  • +
+ +
+ +
+
+ + + + +
+
+ +
+ +
+ +
+ +
+
+ + +
+
+
+ +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/samples/news_pittwire.html b/tests/samples/news_pittwire.html new file mode 100644 index 0000000..74dc749 --- /dev/null +++ b/tests/samples/news_pittwire.html @@ -0,0 +1,1942 @@ + + + + + + + + + + + + + + + + Pittwire | University of Pittsburgh + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + +
+
+
+
+
+ +
+
+ + +
+
+
+
+
+ + + + + + + + + + + +
+ + +
+ + + + +
+
+ + + + + + +
+ + +
+ +
+
+ +
Explore Sections
+ + + + + + + + + + + + + +
+
+ +
+ + + + +
+
Features & Articles +
+ + + +
+ + + +
+
+
+

This Pittsburgh Pirates pitcher is taking a swing at raising mental health awareness +

+

+ A family trauma almost toppled Pitt alum Isaac Mattson’s dream. A career roadblock may have saved it. +

+ + +
+
+
+
+

Pitt celebrated its newest Class of 2024 graduates at winter commencement +

+

+ See a gallery of the ceremony, which included speeches by Holden Thorp and Mihika Shah. +

+ + +
+
+
+
+

40 years later, the Pitt Men’s Study is still breaking ground in the fight against AIDS +

+

+ We spoke with principal investigator Charles Rinaldo and longtime participant and volunteer Marc Wagner about how the study has impacted their lives over the decades. +

+ + +
+
+
+
+

Pitt-Greensburg held its first winter commencement ceremony +

+

+ President Robert Gregerson and other campus leaders recognized the 39 students who completed their degree requirements in the summer and fall semesters. +

+ + +
+
+ +
+ +
+
+ + +
+ + View All Articles + +
+
+ + + +
+
Announcements and Updates +
+ + + + + + +
+ + View All Articles + +
+
+ + + +
+
Accolades & Honors +
+ + + + + + +
+ + View All Articles + +
+
+ + + +
+ + +
+ +
+
+ + + +
+ +
+ + +
+ +
+ +
+ + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 6809d0a62ca2cef0ec657108c43b61e6dcf197dd Mon Sep 17 00:00:00 2001 From: Tianyi Zheng Date: Tue, 24 Dec 2024 22:10:27 -0800 Subject: [PATCH 2/3] Cache categories and topics using @cache Rewrite news.py to cache categories and topics using the functools @cache decorator rather than global variables --- Pipfile.lock | 406 ++-- pittapi/news.py | 40 +- requirements.txt | 2 +- tests/news_test.py | 123 +- .../news_features_articles_no_topics.html | 1838 ++++++++++++++++ .../samples/news_pittwire_no_categories.html | 1935 +++++++++++++++++ 6 files changed, 4070 insertions(+), 274 deletions(-) create mode 100644 tests/samples/news_features_articles_no_topics.html create mode 100644 tests/samples/news_pittwire_no_categories.html diff --git a/Pipfile.lock b/Pipfile.lock index 0857dfe..c8b053f 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -48,114 +48,101 @@ }, "charset-normalizer": { "hashes": [ - "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621", - "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6", - "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8", - "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912", - "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c", - "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b", - "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d", - "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d", - "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95", - "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e", - "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565", - "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64", - "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab", - "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be", - "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e", - "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907", - "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0", - "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2", - "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62", - "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62", - "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23", - "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc", - "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284", - "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca", - "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455", - "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858", - "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b", - "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594", - "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc", - "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db", - "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b", - "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea", - "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6", - "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920", - "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749", - "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7", - "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd", - "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99", - "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242", - "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee", - "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129", - "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2", - "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51", - "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee", - "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8", - "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b", - "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613", - "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742", - "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe", - "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3", - "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5", - "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631", - "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7", - "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15", - "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c", - "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea", - "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417", - "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250", - "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88", - "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca", - "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa", - "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99", - "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149", - "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41", - "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574", - "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0", - "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f", - "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d", - "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654", - "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3", - "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19", - "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90", - "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578", - "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9", - "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1", - "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51", - "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719", - "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236", - "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a", - "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c", - "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade", - "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944", - "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc", - "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6", - "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6", - "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27", - "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6", - "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2", - "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12", - "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf", - "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114", - "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7", - "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf", - "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d", - "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b", - "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed", - "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03", - "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4", - "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67", - "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365", - "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a", - "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748", - "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b", - "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079", - "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482" - ], - "markers": "python_full_version >= '3.7.0'", - "version": "==3.4.0" + "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537", + "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa", + "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a", + "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294", + "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b", + "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd", + "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601", + "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd", + "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4", + "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d", + "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2", + "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313", + "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd", + "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa", + "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8", + "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1", + "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2", + "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496", + "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d", + "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b", + "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e", + "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a", + "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4", + "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca", + "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78", + "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408", + "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5", + "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3", + "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f", + "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a", + "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765", + "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6", + "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146", + "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6", + "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9", + "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd", + "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c", + "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f", + "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545", + "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176", + "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770", + "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824", + "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f", + "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf", + "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487", + "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d", + "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd", + "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b", + "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534", + "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f", + "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b", + "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9", + "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd", + "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125", + "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9", + "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de", + "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11", + "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d", + "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35", + "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f", + "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda", + "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7", + "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a", + "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971", + "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8", + "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41", + "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d", + "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f", + "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757", + "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a", + "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886", + "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77", + "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76", + "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247", + "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", + "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb", + "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7", + "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e", + "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6", + "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037", + "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1", + "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e", + "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807", + "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407", + "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c", + "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12", + "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3", + "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089", + "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd", + "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e", + "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00", + "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616" + ], + "markers": "python_version >= '3.7'", + "version": "==3.4.1" }, "cssselect": { "hashes": [ @@ -844,114 +831,101 @@ }, "charset-normalizer": { "hashes": [ - "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621", - "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6", - "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8", - "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912", - "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c", - "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b", - "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d", - "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d", - "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95", - "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e", - "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565", - "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64", - "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab", - "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be", - "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e", - "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907", - "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0", - "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2", - "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62", - "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62", - "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23", - "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc", - "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284", - "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca", - "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455", - "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858", - "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b", - "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594", - "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc", - "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db", - "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b", - "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea", - "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6", - "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920", - "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749", - "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7", - "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd", - "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99", - "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242", - "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee", - "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129", - "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2", - "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51", - "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee", - "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8", - "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b", - "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613", - "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742", - "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe", - "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3", - "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5", - "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631", - "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7", - "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15", - "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c", - "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea", - "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417", - "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250", - "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88", - "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca", - "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa", - "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99", - "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149", - "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41", - "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574", - "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0", - "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f", - "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d", - "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654", - "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3", - "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19", - "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90", - "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578", - "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9", - "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1", - "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51", - "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719", - "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236", - "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a", - "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c", - "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade", - "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944", - "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc", - "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6", - "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6", - "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27", - "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6", - "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2", - "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12", - "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf", - "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114", - "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7", - "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf", - "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d", - "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b", - "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed", - "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03", - "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4", - "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67", - "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365", - "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a", - "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748", - "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b", - "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079", - "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482" - ], - "markers": "python_full_version >= '3.7.0'", - "version": "==3.4.0" + "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537", + "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa", + "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a", + "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294", + "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b", + "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd", + "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601", + "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd", + "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4", + "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d", + "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2", + "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313", + "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd", + "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa", + "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8", + "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1", + "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2", + "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496", + "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d", + "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b", + "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e", + "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a", + "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4", + "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca", + "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78", + "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408", + "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5", + "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3", + "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f", + "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a", + "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765", + "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6", + "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146", + "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6", + "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9", + "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd", + "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c", + "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f", + "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545", + "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176", + "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770", + "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824", + "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f", + "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf", + "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487", + "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d", + "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd", + "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b", + "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534", + "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f", + "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b", + "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9", + "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd", + "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125", + "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9", + "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de", + "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11", + "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d", + "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35", + "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f", + "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda", + "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7", + "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a", + "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971", + "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8", + "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41", + "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d", + "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f", + "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757", + "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a", + "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886", + "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77", + "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76", + "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247", + "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", + "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb", + "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7", + "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e", + "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6", + "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037", + "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1", + "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e", + "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807", + "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407", + "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c", + "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12", + "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3", + "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089", + "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd", + "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e", + "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00", + "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616" + ], + "markers": "python_version >= '3.7'", + "version": "==3.4.1" }, "click": { "hashes": [ diff --git a/pittapi/news.py b/pittapi/news.py index e97c911..76fbdea 100644 --- a/pittapi/news.py +++ b/pittapi/news.py @@ -19,6 +19,7 @@ from __future__ import annotations +from functools import cache import math from requests_html import Element, HTMLResponse, HTMLSession from typing import NamedTuple @@ -33,9 +34,6 @@ "&title={query}&field_category_target_id=All&page={page_num}" ) -CATEGORY_URL_NAME_MAP: dict[str, str] | None = None -TOPIC_ID_MAP: dict[str, int] | None = None - sess = HTMLSession() @@ -59,6 +57,7 @@ def from_html(cls, article_html: Element) -> Article: return cls(title=article_title, description=article_description, url=article_url, tags=article_tags) +@cache def _scrape_categories() -> dict[str, str]: response: HTMLResponse = sess.get(PITTWIRE_URL) category_menu: Element = response.html.find("div#block-views-block-category-menu-category-menu", first=True) @@ -73,6 +72,7 @@ def _scrape_categories() -> dict[str, str]: return category_map +@cache def _scrape_topics() -> dict[str, int]: response: HTMLResponse = sess.get(FEATURES_ARTICLES_URL) main_content: Element = response.html.xpath("/html/body/div/main/div/section", first=True) @@ -90,15 +90,15 @@ def _scrape_topics() -> dict[str, int]: def _get_page_articles(topic: str, category: str, query: str, year: int | None, page_num: int) -> list[Article]: - assert CATEGORY_URL_NAME_MAP is not None - assert TOPIC_ID_MAP is not None + topic_id_map = _scrape_topics() + category_url_name_map = _scrape_categories() year_str = str(year) if year else "" page_num_str = str(page_num) if page_num else "" response: HTMLResponse = sess.get( NEWS_BY_CATEGORY_URL.format( - category=CATEGORY_URL_NAME_MAP[category], - topic_id=TOPIC_ID_MAP[topic], + category=category_url_name_map[category], + topic_id=topic_id_map[topic], year=year_str, query=query, page_num=page_num_str, @@ -110,18 +110,16 @@ def _get_page_articles(topic: str, category: str, query: str, year: int | None, return page_articles +@cache def get_categories() -> list[str]: - global CATEGORY_URL_NAME_MAP - if not CATEGORY_URL_NAME_MAP: - CATEGORY_URL_NAME_MAP = _scrape_categories() - return list(CATEGORY_URL_NAME_MAP.keys()) + category_url_name_map = _scrape_categories() + return list(category_url_name_map.keys()) +@cache def get_topics() -> list[str]: - global TOPIC_ID_MAP - if not TOPIC_ID_MAP: - TOPIC_ID_MAP = _scrape_topics() - return list(TOPIC_ID_MAP.keys()) + topic_id_map = _scrape_topics() + return list(topic_id_map.keys()) def get_articles_by_topic( @@ -131,16 +129,12 @@ def get_articles_by_topic( year: int | None = None, max_num_results: int = NUM_ARTICLES_PER_PAGE, ) -> list[Article]: - global TOPIC_ID_MAP - if not TOPIC_ID_MAP: - TOPIC_ID_MAP = _scrape_topics() - if topic not in TOPIC_ID_MAP: + topic_id_map = _scrape_topics() + if topic not in topic_id_map: raise ValueError(f"'{topic}' is not a valid topic, must be one of the following: {get_topics()}") - global CATEGORY_URL_NAME_MAP - if not CATEGORY_URL_NAME_MAP: - CATEGORY_URL_NAME_MAP = _scrape_categories() - if category not in CATEGORY_URL_NAME_MAP: + category_url_name_map = _scrape_categories() + if category not in category_url_name_map: raise ValueError(f"'{category}' is not a valid category, must be one of the following: {get_categories()}") num_pages = math.ceil(max_num_results / NUM_ARTICLES_PER_PAGE) diff --git a/requirements.txt b/requirements.txt index ec14c9e..00b3081 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,7 @@ babel==2.16.0 black==24.10.0 certifi==2024.12.14 cfgv==3.4.0 -charset-normalizer==3.4.0 +charset-normalizer==3.4.1 click==8.1.8 coverage[toml]==7.6.9 distlib==0.3.9 diff --git a/tests/news_test.py b/tests/news_test.py index eb08935..44de365 100644 --- a/tests/news_test.py +++ b/tests/news_test.py @@ -32,8 +32,12 @@ def __init__(self, *args, **kwargs): unittest.TestCase.__init__(self, *args, **kwargs) with (SAMPLE_PATH / "news_pittwire.html").open() as f: self.pittwire = f.read() + with (SAMPLE_PATH / "news_pittwire_no_categories.html").open() as f: + self.pittwire_no_categories = f.read() with (SAMPLE_PATH / "news_features_articles.html").open() as f: self.features_articles = f.read() + with (SAMPLE_PATH / "news_features_articles_no_topics.html").open() as f: + self.features_articles_no_topics = f.read() with (SAMPLE_PATH / "news_university_news_features_articles_page_0.html").open() as f: self.university_news_features_articles_page_0 = f.read() with (SAMPLE_PATH / "news_university_news_features_articles_page_1.html").open() as f: @@ -45,28 +49,67 @@ def __init__(self, *args, **kwargs): @responses.activate def test_get_categories(self): - if not news.CATEGORY_URL_NAME_MAP: - responses.add(responses.GET, news.PITTWIRE_URL, body=self.pittwire) + news.get_categories.cache_clear() + news._scrape_categories.cache_clear() + responses.add(responses.GET, news.PITTWIRE_URL, body=self.pittwire) categories = news.get_categories() - self.assertEqual(len(categories), 4) + self.assertCountEqual( + categories, ["Features & Articles", "Accolades & Honors", "Ones to Watch", "Announcements and Updates"] + ) + + @responses.activate + def test_get_categories_missing(self): + news.get_categories.cache_clear() + news._scrape_categories.cache_clear() + responses.add(responses.GET, news.PITTWIRE_URL, body=self.pittwire_no_categories) + + self.assertRaises(RuntimeError, news.get_categories) @responses.activate def test_get_topics(self): - if not news.TOPIC_ID_MAP: - responses.add(responses.GET, news.FEATURES_ARTICLES_URL, body=self.features_articles) + news.get_topics.cache_clear() + news._scrape_topics.cache_clear() + responses.add(responses.GET, news.FEATURES_ARTICLES_URL, body=self.features_articles) topics = news.get_topics() - self.assertEqual(len(topics), 13) + self.assertCountEqual( + topics, + [ + "University News", + "Health and Wellness", + "Technology & Science", + "Arts and Humanities", + "Community Impact", + "Innovation and Research", + "Global", + "Diversity, Equity, and Inclusion", + "Our City/Our Campus", + "Teaching & Learning", + "Space", + "Ukraine", + "Sustainability", + ], + ) + + @responses.activate + def test_get_topics_missing(self): + news.get_topics.cache_clear() + news._scrape_topics.cache_clear() + responses.add(responses.GET, news.FEATURES_ARTICLES_URL, body=self.features_articles_no_topics) + + self.assertRaises(RuntimeError, news.get_topics) @responses.activate def test_get_articles_by_topic(self): - if not news.CATEGORY_URL_NAME_MAP: - responses.add(responses.GET, news.PITTWIRE_URL, body=self.pittwire) - if not news.TOPIC_ID_MAP: - responses.add(responses.GET, news.FEATURES_ARTICLES_URL, body=self.features_articles) + news.get_categories.cache_clear() + news.get_topics.cache_clear() + news._scrape_categories.cache_clear() + news._scrape_topics.cache_clear() + responses.add(responses.GET, news.PITTWIRE_URL, body=self.pittwire) + responses.add(responses.GET, news.FEATURES_ARTICLES_URL, body=self.features_articles) responses.add( responses.GET, "https://www.pitt.edu/pittwire/news/features-articles?field_topics_target_id=432&field_article_date_value=&title=" @@ -101,10 +144,12 @@ def test_get_articles_by_topic(self): @responses.activate def test_get_articles_by_topic_query(self): query = "fulbright" - if not news.CATEGORY_URL_NAME_MAP: - responses.add(responses.GET, news.PITTWIRE_URL, body=self.pittwire) - if not news.TOPIC_ID_MAP: - responses.add(responses.GET, news.FEATURES_ARTICLES_URL, body=self.features_articles) + news.get_categories.cache_clear() + news.get_topics.cache_clear() + news._scrape_categories.cache_clear() + news._scrape_topics.cache_clear() + responses.add(responses.GET, news.PITTWIRE_URL, body=self.pittwire) + responses.add(responses.GET, news.FEATURES_ARTICLES_URL, body=self.features_articles) responses.add( responses.GET, "https://www.pitt.edu/pittwire/news/features-articles?field_topics_target_id=432&field_article_date_value=" @@ -145,10 +190,12 @@ def test_get_articles_by_topic_query(self): @responses.activate def test_get_articles_by_topic_year(self): year = 2020 - if not news.CATEGORY_URL_NAME_MAP: - responses.add(responses.GET, news.PITTWIRE_URL, body=self.pittwire) - if not news.TOPIC_ID_MAP: - responses.add(responses.GET, news.FEATURES_ARTICLES_URL, body=self.features_articles) + news.get_categories.cache_clear() + news.get_topics.cache_clear() + news._scrape_categories.cache_clear() + news._scrape_topics.cache_clear() + responses.add(responses.GET, news.PITTWIRE_URL, body=self.pittwire) + responses.add(responses.GET, news.FEATURES_ARTICLES_URL, body=self.features_articles) responses.add( responses.GET, f"https://www.pitt.edu/pittwire/news/features-articles?field_topics_target_id=432&field_article_date_value={year}" @@ -186,10 +233,12 @@ def test_get_articles_by_topic_year(self): @responses.activate def test_get_articles_by_topic_less_than_one_page(self): num_results = 5 - if not news.CATEGORY_URL_NAME_MAP: - responses.add(responses.GET, news.PITTWIRE_URL, body=self.pittwire) - if not news.TOPIC_ID_MAP: - responses.add(responses.GET, news.FEATURES_ARTICLES_URL, body=self.features_articles) + news.get_categories.cache_clear() + news.get_topics.cache_clear() + news._scrape_categories.cache_clear() + news._scrape_topics.cache_clear() + responses.add(responses.GET, news.PITTWIRE_URL, body=self.pittwire) + responses.add(responses.GET, news.FEATURES_ARTICLES_URL, body=self.features_articles) responses.add( responses.GET, "https://www.pitt.edu/pittwire/news/features-articles?field_topics_target_id=432&field_article_date_value=&title=" @@ -224,10 +273,12 @@ def test_get_articles_by_topic_less_than_one_page(self): @responses.activate def test_get_articles_by_topic_multiple_pages(self): num_results = news.NUM_ARTICLES_PER_PAGE + 5 - if not news.CATEGORY_URL_NAME_MAP: - responses.add(responses.GET, news.PITTWIRE_URL, body=self.pittwire) - if not news.TOPIC_ID_MAP: - responses.add(responses.GET, news.FEATURES_ARTICLES_URL, body=self.features_articles) + news.get_categories.cache_clear() + news.get_topics.cache_clear() + news._scrape_categories.cache_clear() + news._scrape_topics.cache_clear() + responses.add(responses.GET, news.PITTWIRE_URL, body=self.pittwire) + responses.add(responses.GET, news.FEATURES_ARTICLES_URL, body=self.features_articles) responses.add( responses.GET, "https://www.pitt.edu/pittwire/news/features-articles?field_topics_target_id=432&field_article_date_value=&title=" @@ -272,18 +323,22 @@ def test_get_articles_by_topic_multiple_pages(self): @responses.activate def test_get_articles_by_topic_invalid_category(self): - if not news.CATEGORY_URL_NAME_MAP: - responses.add(responses.GET, news.PITTWIRE_URL, body=self.pittwire) - if not news.TOPIC_ID_MAP: - responses.add(responses.GET, news.FEATURES_ARTICLES_URL, body=self.features_articles) + news.get_categories.cache_clear() + news.get_topics.cache_clear() + news._scrape_categories.cache_clear() + news._scrape_topics.cache_clear() + responses.add(responses.GET, news.PITTWIRE_URL, body=self.pittwire) + responses.add(responses.GET, news.FEATURES_ARTICLES_URL, body=self.features_articles) self.assertRaises(ValueError, news.get_articles_by_topic, "University News", "Invalid Category") @responses.activate def test_get_articles_by_topic_invalid_topic(self): - if not news.CATEGORY_URL_NAME_MAP: - responses.add(responses.GET, news.PITTWIRE_URL, body=self.pittwire) - if not news.TOPIC_ID_MAP: - responses.add(responses.GET, news.FEATURES_ARTICLES_URL, body=self.features_articles) + news.get_categories.cache_clear() + news.get_topics.cache_clear() + news._scrape_categories.cache_clear() + news._scrape_topics.cache_clear() + responses.add(responses.GET, news.PITTWIRE_URL, body=self.pittwire) + responses.add(responses.GET, news.FEATURES_ARTICLES_URL, body=self.features_articles) self.assertRaises(ValueError, news.get_articles_by_topic, "Invalid Topic") diff --git a/tests/samples/news_features_articles_no_topics.html b/tests/samples/news_features_articles_no_topics.html new file mode 100644 index 0000000..bb7410e --- /dev/null +++ b/tests/samples/news_features_articles_no_topics.html @@ -0,0 +1,1838 @@ + + + + + + + + + + + + + + + + Pittwire News | University of Pittsburgh + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + + +
+
+
+
+
+ +
+
+ + +
+
+
+
+
+ + + + + + + + + + + +
+ +
+ +
+
+
+ + +
+
+ +
+
+
+

Filter By

+
+
+ +
+ +
+ + + + + +
+
+ + +
+ +
+ +
+
+
+ +
+
+ + +
+
+ + Baseball player throwing a pitch in a crowded stadium. + + + + + +
+

This Pittsburgh Pirates pitcher is taking a swing at raising mental health awareness +

+

+ A family trauma almost toppled Pitt alum Isaac Mattson’s dream. A career roadblock may have saved it. +

+ +
    +
  • + Health and Wellness +
  • +
  • + Community Impact +
  • +
+ +
+ + +
+
+ + Pitt-Greensburg graduates pose for a portrait during the campus' first-ever winter commencement celebration. + + + + + +
+

Pitt-Greensburg held its first winter commencement ceremony +

+

+ President Robert Gregerson and other campus leaders recognized the 39 students who completed their degree requirements in the summer and fall semesters. +

+ +
    +
  • + University News +
  • +
  • + Community Impact +
  • +
  • + Pitt-Greensburg +
  • +
  • + Cultivate student success +
  • +
  • + Commencement +
  • +
+ +
+ + +
+
+ + Confetti falls over winter commencement graduates and attendees. + + + + + +
+

Pitt celebrated its newest Class of 2024 graduates at winter commencement +

+

+ See a gallery of the ceremony, which included speeches by Holden Thorp and Mihika Shah. +

+ +
    +
  • + University News +
  • +
  • + Cultivate student success +
  • +
  • + Commencement +
  • +
+ +
+ + +
+
+ + Charles Rinaldo poses for a portrait in the lab with a colleague. + + + + + +
+

40 years later, the Pitt Men’s Study is still breaking ground in the fight against AIDS +

+

+ We spoke with principal investigator Charles Rinaldo and longtime participant and volunteer Marc Wagner about how the study has impacted their lives over the decades. +

+ +
    +
  • + Community Impact +
  • +
  • + Innovation and Research +
  • +
  • + Propel scholarship, creativity and innovation +
  • +
  • + Promote accountability and trust +
  • +
  • + School of Medicine +
  • +
  • + School of Public Health +
  • +
+ +
+ + +
+
+ + MLS participants smile and engage during the program's December retreat. + + + + + +
+

Nearly half of new moms in STEM leave their full-time positions. This Pitt program wants to change that. +

+

+ Mothers Leading Science is helping health sciences faculty find a supportive community, strategies for work-life integration and renewed passion for their research. +

+ +
    +
  • + Innovation and Research +
  • +
  • + Diversity, Equity, and Inclusion +
  • +
  • + Propel scholarship, creativity and innovation +
  • +
  • + Be welcoming and engaged +
  • +
  • + School of Medicine +
  • +
+ +
+ + +
+
+ + Students in Jennifer Hirsch’s Social Psychology of Reality TV course deliberate. + + + + + +
+

This Pitt professor designed a ‘Survivor’-style game to teach social psychology lessons +

+

+ Jennifer Hirsch’s unique course lets students get in the heads of reality stars — and learn some lessons while they’re in there. +

+ +
    +
  • + Arts and Humanities +
  • +
  • + Teaching & Learning +
  • +
  • + Cultivate student success +
  • +
  • + Kenneth P. Dietrich School of Arts and Sciences +
  • +
+ +
+ + +
+
+ + The Cathedral of Learning + + + + + +
+

5 Pitt students received Gilman Scholarships +

+

+ The undergraduates will travel to South America, Taiwan and more through the program, which supports Federal Pell Grant recipients with up to $5,000 during their study abroad experience. +

+ +
    +
  • + University News +
  • +
  • + Global +
  • +
+ +
+ + +
+
+ + A person in blue doctoral regalia hugs someone in a grey shawl + + + + + +
+

A guest’s guide to commencement at the University of Pittsburgh +

+

+ Everything you need to know about parking, pictures, accessibility and more for your time on the Pittsburgh campus. +

+ +
    +
  • + University News +
  • +
  • + Pittsburgh Campus +
  • +
  • + Commencement +
  • +
+ +
+ + +
+
+ + Portrait of Charles “Chas” Bonasorte at The Pittsburgh Stop Inc. + + + + + +
+

Chas Bonasorte, Pitt football’s ‘Kamikaze Kid’ and owner of famed Pitt apparel kiosk, died at 70 +

+

+ After his career on the field, Bonasorte became a fixture on the Pittsburgh campus with his clothing kiosk at Forbes and Bigelow. +

+ +
    +
  • + Community Impact +
  • +
  • + Alumni +
  • +
  • + Be welcoming and engaged +
  • +
+ +
+ + +
+
+ + Students embrace on the field of the Acrisure Stadium during a Homecoming Football game. + + + + + +
+

2024 at Pitt, in photos +

+

+ Our photographers shared their 10 favorite images of innovative researchers, major developments and more from the year. +

+ +
    +
  • + Technology & Science +
  • +
  • + Community Impact +
  • +
  • + Innovation and Research +
  • +
  • + Promote accountability and trust +
  • +
+ +
+ + +
+
+ + Man with dark hair sits in a wooded area and smiles for camera. + + + + + +
+

Live from New York, it’s Ben Asciutto +

+

+ This Pitt alum’s childhood aspirations of working in the entertainment industry are coming true on the set of ‘Saturday Night Live.’ +

+ +
    +
  • + Arts and Humanities +
  • +
  • + Cultivate student success +
  • +
  • + Kenneth P. Dietrich School of Arts and Sciences +
  • +
+ +
+ + +
+
+ + Three researchers in a lab + + + + + +
+

Chronic pain treatments can be dangerous and ineffective. These Pitt researchers are working on a solution. +

+

+ Supported by NIH funding, the Vanish Therapeutics team is working to bring a bioabsorbable nerve stimulator to market. +

+ +
    +
  • + Health and Wellness +
  • +
  • + Innovation and Research +
  • +
+ +
+ + +
+
+ + A branded Pitt flag with the University shield is framed by fall leaves. + + + + + +
+

ICYMI: Pitt contributed $6.6 billion to Pennsylvania in FY23 +

+

+ The latest Economic Impact Report showed the University supported nearly 49,000 jobs and contributed $356.2 million in state and local taxes. +

+ +
    +
  • + University News +
  • +
  • + Community Impact +
  • +
  • + Propel scholarship, creativity and innovation +
  • +
  • + Promote accountability and trust +
  • +
+ +
+ + +
+
+ + Fang on a staircase in the Honors College + + + + + +
+

This Pitt senior and cancer researcher is one to keep watching +

+

+ Here’s what’s next for Richard Su Fang, a Goldwater scholar who has already received interview invitations from 17 MD/PhD programs. +

+ +
    +
  • + Health and Wellness +
  • +
  • + Community Impact +
  • +
  • + Innovation and Research +
  • +
  • + Cultivate student success +
  • +
  • + David C. Frederick Honors College +
  • +
+ +
+ + +
+
+ + An adult and child volunteer help prepare meals for Christmas Day at Pitt. + + + + + +
+

Volunteers will spread cheer, presents and thousands of meals for Christmas Day at Pitt +

+

+ 156 people will serve at the University’s 19th annual celebration on Dec. 25. +

+ +
    +
  • + Community Impact +
  • +
  • + Our City/Our Campus +
  • +
  • + Be welcoming and engaged +
  • +
+ +
+ + +
+
+ + The Nonprofit Capacity Building Program cohort poses for a group photo at Café Momentum. + + + + + +
+

Nonprofits are scaling up their regional impact with support from Pitt +

+

+ The Nonprofit Capacity Building Program connects local organizations working to improve economic stability with University training and resources. +

+ +
    +
  • + Health and Wellness +
  • +
  • + Community Impact +
  • +
  • + Innovation and Research +
  • +
  • + Diversity, Equity, and Inclusion +
  • +
  • + Our City/Our Campus +
  • +
  • + Propel scholarship, creativity and innovation +
  • +
+ +
+ + +
+
+ + People stand in front of a Pitt health sciences backdrop + + + + + +
+

A new Pitt center will use AI to accelerate women’s health research globally +

+

+ The Vijayalakshmi Innovation Center is funded by a gift from siblings and health care entrepreneurs Vishnu Vardhan and Harsha Vardhini, along with a significant investment from the School of Medicine. +

+ +
    +
  • + Health and Wellness +
  • +
  • + Innovation and Research +
  • +
  • + Global +
  • +
  • + Propel scholarship, creativity and innovation +
  • +
  • + It's Possible at Pitt +
  • +
  • + School of Medicine +
  • +
+ +
+ + +
+
+ + People in yellow vests tour a construction site + + + + + +
+

Pitt’s new building at Fifth and Halket will support health sciences, medicine and online learning +

+

+ The University’s Property and Facilities Committee and Board of Trustees approved interior fit out projects for the Department of Computational and Systems Biology and Pitt EDGE on Dec. 5. +

+ +
    +
  • + University News +
  • +
  • + Our City/Our Campus +
  • +
  • + School of Health and Rehabilitation Sciences +
  • +
  • + School of Medicine +
  • +
+ +
+ + +
+
+ + Alexander Deiters and Jason Lohmueller in the lab + + + + + +
+

How this Pitt duo’s startup plans to attack the ‘tricky beast’ that is cancer +

+

+ A platform developed by Jason Lohmueller and Alex Dieters could allow immunotherapies to be delivered to tumors with more flexibility and precision. +

+ +
    +
  • + Innovation and Research +
  • +
  • + Innovation Institute +
  • +
  • + It's Possible at Pitt +
  • +
  • + Kenneth P. Dietrich School of Arts and Sciences +
  • +
  • + School of Medicine +
  • +
+ +
+ + +
+
+ + Applied Physiology Lab researchers conduct a spaceflight hibernation study on a volunteer. + + + + + +
+

A NASA-funded Pitt team is exploring the benefits of sleeping in space +

+

+ Kate Flickinger’s research on lower metabolic rates could help astronauts safely undergo long-duration spaceflights one day. It could also help ICU patients here on Earth. +

+ +
    +
  • + Technology & Science +
  • +
  • + Innovation and Research +
  • +
  • + Propel scholarship, creativity and innovation +
  • +
  • + School of Medicine +
  • +
+ +
+ +
+
+ + + + +
+
+ +
+ +
+ +
+ +
+
+ + +
+
+
+ +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/samples/news_pittwire_no_categories.html b/tests/samples/news_pittwire_no_categories.html new file mode 100644 index 0000000..aed5fa4 --- /dev/null +++ b/tests/samples/news_pittwire_no_categories.html @@ -0,0 +1,1935 @@ + + + + + + + + + + + + + + + + Pittwire | University of Pittsburgh + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + +
+
+
+
+
+ +
+
+ + +
+
+
+
+
+ + + + + + + + + + + +
+ + +
+ + + + +
+
+ + + + + + +
+ + +
+ +
+
+ +
Explore Sections
+ + + + + + + + + + + + + +
+
+ +
+ + + + +
+
Features & Articles +
+ + + +
+ + + +
+
+
+

This Pittsburgh Pirates pitcher is taking a swing at raising mental health awareness +

+

+ A family trauma almost toppled Pitt alum Isaac Mattson’s dream. A career roadblock may have saved it. +

+ + +
+
+
+
+

Pitt celebrated its newest Class of 2024 graduates at winter commencement +

+

+ See a gallery of the ceremony, which included speeches by Holden Thorp and Mihika Shah. +

+ + +
+
+
+
+

40 years later, the Pitt Men’s Study is still breaking ground in the fight against AIDS +

+

+ We spoke with principal investigator Charles Rinaldo and longtime participant and volunteer Marc Wagner about how the study has impacted their lives over the decades. +

+ + +
+
+
+
+

Pitt-Greensburg held its first winter commencement ceremony +

+

+ President Robert Gregerson and other campus leaders recognized the 39 students who completed their degree requirements in the summer and fall semesters. +

+ + +
+
+ +
+ +
+
+ + +
+ + View All Articles + +
+
+ + + +
+
Announcements and Updates +
+ + + + + + +
+ + View All Articles + +
+
+ + + +
+
Accolades & Honors +
+ + + + + + +
+ + View All Articles + +
+
+ + + +
+ + +
+ +
+
+ + + +
+ +
+ + +
+ +
+ +
+ + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 97d95b993a31c5bd7511ec73e22f5925c8e5cd13 Mon Sep 17 00:00:00 2001 From: Tianyi Zheng Date: Sun, 29 Dec 2024 15:02:42 -0800 Subject: [PATCH 3/3] Revert dependency updates Revert dependency updates in Pipfile.lock and requirements.txt. The updates will be left for a separate PR. --- Pipfile.lock | 426 +++++++++++++++++++++++++---------------------- requirements.txt | 6 +- 2 files changed, 229 insertions(+), 203 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index c8b053f..fda3e41 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -48,101 +48,114 @@ }, "charset-normalizer": { "hashes": [ - "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537", - "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa", - "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a", - "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294", - "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b", - "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd", - "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601", - "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd", - "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4", - "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d", - "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2", - "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313", - "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd", - "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa", - "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8", - "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1", - "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2", - "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496", - "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d", - "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b", - "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e", - "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a", - "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4", - "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca", - "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78", - "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408", - "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5", - "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3", - "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f", - "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a", - "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765", - "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6", - "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146", - "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6", - "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9", - "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd", - "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c", - "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f", - "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545", - "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176", - "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770", - "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824", - "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f", - "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf", - "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487", - "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d", - "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd", - "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b", - "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534", - "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f", - "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b", - "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9", - "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd", - "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125", - "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9", - "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de", - "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11", - "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d", - "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35", - "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f", - "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda", - "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7", - "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a", - "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971", - "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8", - "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41", - "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d", - "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f", - "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757", - "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a", - "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886", - "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77", - "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76", - "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247", - "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", - "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb", - "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7", - "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e", - "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6", - "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037", - "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1", - "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e", - "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807", - "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407", - "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c", - "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12", - "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3", - "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089", - "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd", - "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e", - "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00", - "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616" - ], - "markers": "python_version >= '3.7'", - "version": "==3.4.1" + "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621", + "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6", + "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8", + "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912", + "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c", + "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b", + "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d", + "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d", + "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95", + "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e", + "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565", + "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64", + "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab", + "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be", + "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e", + "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907", + "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0", + "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2", + "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62", + "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62", + "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23", + "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc", + "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284", + "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca", + "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455", + "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858", + "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b", + "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594", + "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc", + "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db", + "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b", + "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea", + "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6", + "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920", + "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749", + "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7", + "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd", + "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99", + "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242", + "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee", + "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129", + "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2", + "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51", + "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee", + "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8", + "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b", + "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613", + "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742", + "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe", + "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3", + "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5", + "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631", + "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7", + "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15", + "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c", + "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea", + "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417", + "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250", + "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88", + "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca", + "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa", + "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99", + "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149", + "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41", + "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574", + "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0", + "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f", + "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d", + "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654", + "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3", + "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19", + "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90", + "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578", + "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9", + "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1", + "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51", + "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719", + "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236", + "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a", + "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c", + "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade", + "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944", + "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc", + "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6", + "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6", + "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27", + "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6", + "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2", + "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12", + "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf", + "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114", + "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7", + "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf", + "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d", + "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b", + "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed", + "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03", + "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4", + "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67", + "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365", + "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a", + "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748", + "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b", + "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079", + "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482" + ], + "markers": "python_full_version >= '3.7.0'", + "version": "==3.4.0" }, "cssselect": { "hashes": [ @@ -831,109 +844,122 @@ }, "charset-normalizer": { "hashes": [ - "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537", - "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa", - "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a", - "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294", - "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b", - "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd", - "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601", - "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd", - "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4", - "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d", - "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2", - "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313", - "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd", - "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa", - "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8", - "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1", - "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2", - "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496", - "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d", - "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b", - "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e", - "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a", - "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4", - "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca", - "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78", - "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408", - "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5", - "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3", - "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f", - "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a", - "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765", - "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6", - "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146", - "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6", - "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9", - "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd", - "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c", - "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f", - "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545", - "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176", - "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770", - "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824", - "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f", - "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf", - "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487", - "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d", - "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd", - "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b", - "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534", - "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f", - "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b", - "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9", - "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd", - "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125", - "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9", - "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de", - "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11", - "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d", - "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35", - "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f", - "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda", - "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7", - "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a", - "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971", - "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8", - "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41", - "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d", - "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f", - "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757", - "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a", - "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886", - "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77", - "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76", - "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247", - "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", - "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb", - "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7", - "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e", - "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6", - "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037", - "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1", - "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e", - "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807", - "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407", - "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c", - "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12", - "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3", - "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089", - "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd", - "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e", - "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00", - "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616" - ], - "markers": "python_version >= '3.7'", - "version": "==3.4.1" + "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621", + "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6", + "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8", + "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912", + "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c", + "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b", + "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d", + "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d", + "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95", + "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e", + "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565", + "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64", + "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab", + "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be", + "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e", + "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907", + "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0", + "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2", + "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62", + "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62", + "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23", + "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc", + "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284", + "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca", + "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455", + "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858", + "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b", + "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594", + "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc", + "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db", + "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b", + "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea", + "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6", + "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920", + "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749", + "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7", + "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd", + "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99", + "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242", + "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee", + "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129", + "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2", + "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51", + "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee", + "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8", + "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b", + "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613", + "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742", + "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe", + "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3", + "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5", + "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631", + "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7", + "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15", + "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c", + "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea", + "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417", + "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250", + "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88", + "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca", + "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa", + "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99", + "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149", + "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41", + "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574", + "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0", + "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f", + "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d", + "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654", + "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3", + "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19", + "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90", + "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578", + "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9", + "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1", + "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51", + "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719", + "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236", + "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a", + "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c", + "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade", + "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944", + "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc", + "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6", + "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6", + "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27", + "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6", + "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2", + "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12", + "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf", + "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114", + "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7", + "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf", + "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d", + "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b", + "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed", + "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03", + "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4", + "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67", + "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365", + "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a", + "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748", + "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b", + "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079", + "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482" + ], + "markers": "python_full_version >= '3.7.0'", + "version": "==3.4.0" }, "click": { "hashes": [ - "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", - "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a" + "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", + "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de" ], "markers": "python_version >= '3.7'", - "version": "==8.1.8" + "version": "==8.1.7" }, "coverage": { "extras": [ @@ -1073,11 +1099,11 @@ }, "jinja2": { "hashes": [ - "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb", - "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb" + "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369", + "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d" ], "markers": "python_version >= '3.7'", - "version": "==3.1.5" + "version": "==3.1.4" }, "markupsafe": { "hashes": [ @@ -1386,11 +1412,11 @@ }, "urllib3": { "hashes": [ - "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df", - "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d" + "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac", + "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9" ], - "markers": "python_version >= '3.9'", - "version": "==2.3.0" + "markers": "python_version >= '3.8'", + "version": "==2.2.3" }, "virtualenv": { "hashes": [ diff --git a/requirements.txt b/requirements.txt index 00b3081..a5fdee1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,8 +3,8 @@ babel==2.16.0 black==24.10.0 certifi==2024.12.14 cfgv==3.4.0 -charset-normalizer==3.4.1 -click==8.1.8 +charset-normalizer==3.4.0 +click==8.1.7 coverage[toml]==7.6.9 distlib==0.3.9 docutils==0.21.2 @@ -14,7 +14,7 @@ identify==2.6.3 idna==3.10 imagesize==1.4.1 iniconfig==2.0.0 -jinja2==3.1.5 +jinja2==3.1.4 markupsafe==3.0.2 mccabe==0.7.0 mypy-extensions==1.0.0