From 85b73b0c68476fa6c6844dcac5e89a9769afd279 Mon Sep 17 00:00:00 2001 From: Gordon Shumway <39967334+oddluck@users.noreply.github.com> Date: Sat, 11 Jan 2025 03:11:39 -0500 Subject: [PATCH] Delete Corona directory Fuck this shit --- Corona/README.md | 9 - Corona/__init__.py | 67 ------ Corona/codes.py | 312 -------------------------- Corona/config.py | 66 ------ Corona/plugin.py | 475 ---------------------------------------- Corona/requirements.txt | 2 - Corona/setup.py | 9 - 7 files changed, 940 deletions(-) delete mode 100644 Corona/README.md delete mode 100644 Corona/__init__.py delete mode 100644 Corona/codes.py delete mode 100644 Corona/config.py delete mode 100644 Corona/plugin.py delete mode 100644 Corona/requirements.txt delete mode 100644 Corona/setup.py diff --git a/Corona/README.md b/Corona/README.md deleted file mode 100644 index 3563cdf..0000000 --- a/Corona/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Return the latest Coronavirus (COVID-19) statistics globally or by country/state. - -[![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=T8E56M6SP9JH2) - -Plugin has been rewritten to use https://www.worldometers.info/coronavirus/ as data source. - -`config plugins.corona.countryFirst` - Country name abbreviations take precedence over USA state name abbreviations when `True` - -countryFirst default: `False` diff --git a/Corona/__init__.py b/Corona/__init__.py deleted file mode 100644 index fdc994e..0000000 --- a/Corona/__init__.py +++ /dev/null @@ -1,67 +0,0 @@ -### -# Copyright (c) 2020, Hoaas -# Copyright (c) 2020, oddluck -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, -# this list of conditions, and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions, and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# * Neither the name of the author of this software nor the name of -# contributors to this software may be used to endorse or promote products -# derived from this software without specific prior written consent. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -### - -""" -Corona: Return coronavirus information -""" - -import supybot -import supybot.world as world -import imp - -# Use this for the version of this plugin. You may wish to put a CVS keyword -# in here if you're keeping the plugin in CVS or some similar system. -__version__ = "2020.02.24+git" - -# XXX Replace this with an appropriate author or supybot.Author instance. -__author__ = supybot.Author("oddluck", "oddluck", "oddluck@riseup.net") -__maintainer__ = supybot.authors.unknown - -# This is a dictionary mapping supybot.Author instances to lists of -# contributions. -__contributors__ = {} - -# This is a url where the most recent plugin package can be downloaded. -__url__ = "https://github.com/oddluck/limnoria-plugins/" - -from . import config -from . import plugin -from importlib import reload - -reload(plugin) -reload(config) -# Add more reloads here if you add third-party modules and want them to be -# reloaded when this plugin is reloaded. Don't forget to import them as well! - -if world.testing: - from . import test - -Class = plugin.Class -configure = config.configure diff --git a/Corona/codes.py b/Corona/codes.py deleted file mode 100644 index a81b8cc..0000000 --- a/Corona/codes.py +++ /dev/null @@ -1,312 +0,0 @@ -countries = { - "AF": "AFGHANISTAN", - "AX": "ÅLAND ISLANDS", - "AL": "ALBANIA", - "DZ": "ALGERIA", - "AS": "AMERICAN SAMOA", - "AD": "ANDORRA", - "AO": "ANGOLA", - "AI": "ANGUILLA", - "AQ": "ANTARCTICA", - "AG": "ANTIGUA AND BARBUDA", - "AR": "ARGENTINA", - "AM": "ARMENIA", - "AW": "ARUBA", - "AU": "AUSTRALIA", - "AT": "AUSTRIA", - "AZ": "AZERBAIJAN", - "BS": "BAHAMAS", - "BH": "BAHRAIN", - "BD": "BANGLADESH", - "BB": "BARBADOS", - "BY": "BELARUS", - "BE": "BELGIUM", - "BZ": "BELIZE", - "BJ": "BENIN", - "BM": "BERMUDA", - "BT": "BHUTAN", - "BO": "BOLIVIA", - "BQ": "BONAIRE", - "BA": "BOSNIA AND HERZEGOVINA", - "BW": "BOTSWANA", - "BV": "BOUVET ISLAND", - "BR": "BRAZIL", - "IO": "BRITISH INDIAN OCEAN TERRITORY", - "BN": "BRUNEI", - "BG": "BULGARIA", - "BF": "BURKINA FASO", - "BI": "BURUNDI", - "KH": "CAMBODIA", - "CM": "CAMEROON", - "CA": "CANADA", - "CV": "CABO VERDE", - "KY": "CAYMAN ISLANDS", - "CF": "CAR", - "TD": "CHAD", - "CL": "CHILE", - "CN": "CHINA", - "CX": "CHRISTMAS ISLAND", - "CC": "COCOS ISLANDS", - "CO": "COLOMBIA", - "KM": "COMOROS", - "CG": "CONGO", - "CD": "CONGO", - "CK": "COOK ISLANDS", - "CR": "COSTA RICA", - "CI": "CÔTE D'IVOIRE", - "HR": "CROATIA", - "CU": "CUBA", - "CW": "CURAÇAO", - "CY": "CYPRUS", - "CZ": "CZECHIA", - "DK": "DENMARK", - "DJ": "DJIBOUTI", - "DM": "DOMINICA", - "DO": "DOMINICAN REPUBLIC", - "EC": "ECUADOR", - "EG": "EGYPT", - "SV": "EL SALVADOR", - "GQ": "EQUATORIAL GUINEA", - "ER": "ERITREA", - "EE": "ESTONIA", - "ET": "ETHIOPIA", - "FK": "FALKLAND ISLANDS", - "FO": "FAROE ISLANDS", - "FJ": "FIJI", - "FI": "FINLAND", - "FR": "FRANCE", - "GF": "FRENCH GUIANA", - "PF": "FRENCH POLYNESIA", - "TF": "FRENCH SOUTHERN TERRITORIES", - "GA": "GABON", - "GM": "GAMBIA", - "GE": "GEORGIA", - "DE": "GERMANY", - "GH": "GHANA", - "GI": "GIBRALTAR", - "GR": "GREECE", - "GL": "GREENLAND", - "GD": "GRENADA", - "GP": "GUADELOUPE", - "GU": "GUAM", - "GT": "GUATEMALA", - "GG": "GUERNSEY", - "GN": "GUINEA", - "GW": "GUINEA", - "GY": "GUYANA", - "HT": "HAITI", - "HM": "HEARD ISLAND AND MCDONALD ISLANDS", - "VA": "VATICAN CITY", - "HN": "HONDURAS", - "HK": "HONG KONG", - "HU": "HUNGARY", - "IS": "ICELAND", - "IN": "INDIA", - "ID": "INDONESIA", - "IR": "IRAN", - "IQ": "IRAQ", - "IE": "IRELAND", - "IM": "ISLE OF MAN", - "IL": "ISRAEL", - "IT": "ITALY", - "JM": "JAMAICA", - "JP": "JAPAN", - "JE": "JERSEY", - "JO": "JORDAN", - "KZ": "KAZAKHSTAN", - "KE": "KENYA", - "KI": "KIRIBATI", - "KP": "N. KOREA", - "KR": "S. KOREA", - "KW": "KUWAIT", - "KG": "KYRGYZSTAN", - "LA": "LAOS", - "LV": "LATVIA", - "LB": "LEBANON", - "LS": "LESOTHO", - "LR": "LIBERIA", - "LY": "LIBYA", - "LI": "LIECHTENSTEIN", - "LT": "LITHUANIA", - "LU": "LUXEMBOURG", - "MO": "MACAO", - "MK": "NORTH MACEDONIA", - "MG": "MADAGASCAR", - "MW": "MALAWI", - "MY": "MALAYSIA", - "MV": "MALDIVES", - "ML": "MALI", - "MT": "MALTA", - "MH": "MARSHALL ISLANDS", - "MQ": "MARTINIQUE", - "MR": "MAURITANIA", - "MU": "MAURITIUS", - "YT": "MAYOTTE", - "MX": "MEXICO", - "FM": "MICRONESIA", - "MD": "MOLDOVA", - "MC": "MONACO", - "MN": "MONGOLIA", - "ME": "MONTENEGRO", - "MS": "MONTSERRAT", - "MA": "MOROCCO", - "MZ": "MOZAMBIQUE", - "MM": "MYANMAR", - "NA": "NAMIBIA", - "NR": "NAURU", - "NP": "NEPAL", - "NL": "NETHERLANDS", - "NC": "NEW CALEDONIA", - "NZ": "NEW ZEALAND", - "NI": "NICARAGUA", - "NE": "NIGER", - "NG": "NIGERIA", - "NU": "NIUE", - "NF": "NORFOLK ISLAND", - "MP": "NORTHERN MARIANA ISLANDS", - "NO": "NORWAY", - "OM": "OMAN", - "PK": "PAKISTAN", - "PW": "PALAU", - "PS": "PALESTINE", - "PA": "PANAMA", - "PG": "PAPUA NEW GUINEA", - "PY": "PARAGUAY", - "PE": "PERU", - "PH": "PHILIPPINES", - "PN": "PITCAIRN", - "PL": "POLAND", - "PT": "PORTUGAL", - "PR": "PUERTO RICO", - "QA": "QATAR", - "RE": "RÉUNION", - "RO": "ROMANIA", - "RU": "RUSSIA", - "RW": "RWANDA", - "BL": "ST. BARTH", - "SH": "SAINT HELENA", - "KN": "SAINT KITTS AND NEVIS", - "LC": "SAINT LUCIA", - "MF": "SAINT MARTIN", - "PM": "SAINT PIERRE AND MIQUELON", - "VC": "ST. VINCENT GRENADINES", - "WS": "SAMOA", - "SM": "SAN MARINO", - "ST": "SAO TOME AND PRINCIPE", - "SA": "SAUDI ARABIA", - "SN": "SENEGAL", - "RS": "SERBIA", - "SC": "SEYCHELLES", - "SL": "SIERRA LEONE", - "SG": "SINGAPORE", - "SX": "SINT MAARTEN", - "SK": "SLOVAKIA", - "SI": "SLOVENIA", - "SB": "SOLOMON ISLANDS", - "SO": "SOMALIA", - "ZA": "SOUTH AFRICA", - "GS": "GEORGIA", - "SS": "SUDAN", - "ES": "SPAIN", - "LK": "SRI LANKA", - "SD": "SUDAN", - "SR": "SURINAME", - "SJ": "SVALBARD AND JAN MAYEN", - "SZ": "SWAZILAND", - "SE": "SWEDEN", - "CH": "SWITZERLAND", - "SY": "SYRIA", - "TW": "TAIWAN", - "TJ": "TAJIKISTAN", - "TZ": "TANZANIA", - "TH": "THAILAND", - "TL": "TIMOR-LESTE", - "TG": "TOGO", - "TK": "TOKELAU", - "TO": "TONGA", - "TT": "TRINIDAD AND TOBAGO", - "TN": "TUNISIA", - "TR": "TURKEY", - "TM": "TURKMENISTAN", - "TC": "TURKS AND CAICOS", - "TV": "TUVALU", - "UG": "UGANDA", - "UA": "UKRAINE", - "AE": "UNITED ARAB EMIRATES", - "GB": "UK", - "UK": "UK", - "US": "USA", - "UM": "UNITED STATES MINOR OUTLYING ISLANDS", - "UY": "URUGUAY", - "UZ": "UZBEKISTAN", - "VU": "VANUATU", - "VE": "VENEZUELA", - "VN": "VIETNAM", - "VG": "U.S. VIRGIN ISLANDS", - "VI": "U.S. VIRGIN ISLANDS", - "WF": "WALLIS AND FUTUNA", - "EH": "WESTERN SAHARA", - "YE": "YEMEN", - "ZM": "ZAMBIA", - "ZW": "ZIMBABWE", -} - -states = { - "AK": "ALASKA", - "AL": "ALABAMA", - "AR": "ARKANSAS", - "AS": "AMERICAN SAMOA", - "AZ": "ARIZONA", - "CA": "CALIFORNIA", - "CO": "COLORADO", - "CT": "CONNECTICUT", - "DC": "DISTRICT OF COLUMBIA", - "DE": "DELAWARE", - "FL": "FLORIDA", - "GA": "GEORGIA", - "GU": "GUAM", - "HI": "HAWAII", - "IA": "IOWA", - "ID": "IDAHO", - "IL": "ILLINOIS", - "IN": "INDIANA", - "KS": "KANSAS", - "KY": "KENTUCKY", - "LA": "LOUISIANA", - "MA": "MASSACHUSETTS", - "MD": "MARYLAND", - "ME": "MAINE", - "MI": "MICHIGAN", - "MN": "MINNESOTA", - "MO": "MISSOURI", - "MP": "NORTHERN MARIANA ISLANDS", - "MS": "MISSISSIPPI", - "MT": "MONTANA", - "NA": "NATIONAL", - "NC": "NORTH CAROLINA", - "ND": "NORTH DAKOTA", - "NE": "NEBRASKA", - "NH": "NEW HAMPSHIRE", - "NJ": "NEW JERSEY", - "NM": "NEW MEXICO", - "NV": "NEVADA", - "NY": "NEW YORK", - "OH": "OHIO", - "OK": "OKLAHOMA", - "OR": "OREGON", - "PA": "PENNSYLVANIA", - "PR": "PUERTO RICO", - "RI": "RHODE ISLAND", - "SC": "SOUTH CAROLINA", - "SD": "SOUTH DAKOTA", - "TN": "TENNESSEE", - "TX": "TEXAS", - "UT": "UTAH", - "VA": "VIRGINIA", - "VI": "VIRGIN ISLANDS", - "VT": "VERMONT", - "WA": "WASHINGTON", - "WI": "WISCONSIN", - "WV": "WEST VIRGINIA", - "WY": "WYOMING", -} diff --git a/Corona/config.py b/Corona/config.py deleted file mode 100644 index 03d5319..0000000 --- a/Corona/config.py +++ /dev/null @@ -1,66 +0,0 @@ -### -# Copyright (c) 2020, Hoaas -# Copyright (c) 2020, oddluck -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, -# this list of conditions, and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions, and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# * Neither the name of the author of this software nor the name of -# contributors to this software may be used to endorse or promote products -# derived from this software without specific prior written consent. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -### - -import supybot.conf as conf -import supybot.registry as registry - -try: - from supybot.i18n import PluginInternationalization - - _ = PluginInternationalization("Corona") -except: - # Placeholder that allows to run the plugin on a bot - # without the i18n module - _ = lambda x: x - - -def configure(advanced): - # This will be called by supybot to configure this module. advanced is - # a bool that specifies whether the user identified themself as an advanced - # user or not. You should effect your configuration by manipulating the - # registry as appropriate. - from supybot.questions import expect, anything, something, yn - - conf.registerPlugin("Corona", True) - - -Corona = conf.registerPlugin("Corona") - -conf.registerChannelValue( - Corona, - "countryFirst", - registry.Boolean( - False, - _( - "Give preference to country name abbreviations over USA state name" - " abbreviations" - ), - ), -) diff --git a/Corona/plugin.py b/Corona/plugin.py deleted file mode 100644 index d51e374..0000000 --- a/Corona/plugin.py +++ /dev/null @@ -1,475 +0,0 @@ -### -# Copyright (c) 2020, Hoaas -# Copyright (c) 2020, oddluck -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, -# this list of conditions, and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions, and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# * Neither the name of the author of this software nor the name of -# contributors to this software may be used to endorse or promote products -# derived from this software without specific prior written consent. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -### - -import requests -import datetime -import re -from bs4 import BeautifulSoup -from .codes import states, countries -from supybot import utils, plugins, ircutils, callbacks, log -from supybot.commands import * - -try: - from supybot.i18n import PluginInternationalization - - _ = PluginInternationalization("Corona") -except ImportError: - # Placeholder that allows to run the plugin on a bot - # without the i18n module - _ = lambda x: x - - -class Corona(callbacks.Plugin): - """Displays current stats of the Coronavirus outbreak""" - - threaded = True - - def __init__(self, irc): - self.__parent = super(Corona, self) - self.__parent.__init__(irc) - self.countries = requests.structures.CaseInsensitiveDict() - self.states = requests.structures.CaseInsensitiveDict() - self.updated = None - self.top = {} - self.top["countries"] = [] - self.top["states"] = [] - - def time_created(self, time): - """ - Return relative time delta between now and s (dt string). - """ - d = datetime.datetime.utcnow() - time - if d.days: - rel_time = "{:1d}d ago".format(abs(d.days)) - elif d.seconds > 3600: - rel_time = "{:.1f}h ago".format(round((abs(d.seconds) / 3600), 1)) - elif 60 <= d.seconds < 3600: - rel_time = "{:.1f}m ago".format(round((abs(d.seconds) / 60), 1)) - else: - rel_time = "%ss ago" % (abs(d.seconds)) - return rel_time - - def get_data(self): - headers = {} - headers["countries"] = [] - headers["states"] = [] - OK = False - try: - r = requests.get("https://www.worldometers.info/coronavirus/", timeout=10) - r.raise_for_status() - OK = True - except ( - requests.exceptions.RequestException, - requests.exceptions.HTTPError, - ) as e: - log.error("Corona: error retrieving World data from API: {0}".format(e)) - OK = False - return - soup = BeautifulSoup(r.content) - update = soup.find("div", text=re.compile("Last updated:")) - update = update.text.split(":", 1)[1].replace("GMT", "UTC").strip() - updated = datetime.datetime.strptime(update, "%B %d, %Y, %H:%M %Z") - if OK and not self.updated or OK and updated > self.updated: - self.updated = updated - table = soup.find("table", {"id": "main_table_countries_today"}) - headers["countries"] = [header.text for header in table.find_all("th")] - results = [ - { - headers["countries"][i]: cell.text.strip() - for i, cell in enumerate(row.find_all("td")) - } - for row in table.find_all("tr", {"style": ""}) - ] - results = sorted( - results, - key=lambda k_v: int(re.sub(r"[^\d]", "", k_v["TotalCases"])) - if len(k_v) == len(headers["countries"]) - else 0, - reverse=True, - ) - top = [] - for item in results: - if len(item) == len(headers["countries"]): - i = 0 - while i < len(headers["countries"]): - if i < 8 and not item[headers["countries"][i]]: - item[headers["countries"][i]] = "0" - elif not item[headers["countries"][i]]: - item[headers["countries"][i]] = "N/A" - if re.sub( - r"[^\w. ]", "", item[headers["countries"][i]] - ).isdigit(): - item[headers["countries"][i]] = int( - re.sub(r"[^\d]", "", item[headers["countries"][i]]) - ) - i += 1 - self.countries[item["Country,Other"]] = item - rank = results.index(item) - 1 - self.countries[item["Country,Other"]]["rank"] = rank - if rank > 0 and rank <= 10: - top.append( - "#{0}: \x1F{1}\x1F (\x0307{2}\x03/\x0304{3}\x03)".format( - rank, - item["Country,Other"], - "{:,}".format(item["TotalCases"]), - "{:,}".format(item["TotalDeaths"]), - ) - ) - self.top["countries"] = top - for item in self.countries: - try: - self.countries[item]["ratio_new_cases"] = "{0:.1%}".format( - self.countries[item]["NewCases"] - / ( - self.countries[item]["TotalCases"] - - self.countries[item]["NewCases"] - ) - ) - except: - self.countries[item]["ratio_new_cases"] = "0%" - try: - self.countries[item]["ratio_new_dead"] = "{0:.1%}".format( - self.countries[item]["NewDeaths"] - / ( - self.countries[item]["TotalDeaths"] - - self.countries[item]["NewDeaths"] - ) - ) - except: - self.countries[item]["ratio_new_dead"] = "0%" - try: - self.countries[item]["ratio_dead"] = "{0:.1%}".format( - self.countries[item]["TotalDeaths"] - / self.countries[item]["TotalCases"] - ) - except: - self.countries[item]["ratio_dead"] = "N/A" - try: - self.countries[item]["ratio_recovered"] = "{0:.1%}".format( - self.countries[item]["TotalRecovered"] - / self.countries[item]["TotalCases"] - ) - except: - self.countries[item]["ratio_recovered"] = "N/A" - try: - self.countries[item]["mild"] = ( - self.countries[item]["ActiveCases"] - - self.countries[item]["Serious,Critical"] - ) - except: - self.countries[item]["mild"] = "N/A" - try: - self.countries[item]["ratio_mild"] = "{0:.1%}".format( - self.countries[item]["mild"] - / self.countries[item]["ActiveCases"] - ) - except: - self.countries[item]["ratio_mild"] = "N/A" - try: - self.countries[item]["ratio_serious"] = "{0:.1%}".format( - self.countries[item]["Serious,Critical"] - / self.countries[item]["ActiveCases"] - ) - except: - self.countries[item]["ratio_serious"] = "N/A" - for value in self.countries[item]: - if isinstance(self.countries[item][value], int): - self.countries[item][value] = "{:,}".format( - self.countries[item][value] - ) - try: - r = requests.get( - "https://www.worldometers.info/coronavirus/country/us/", timeout=10 - ) - r.raise_for_status() - OK = True - except ( - requests.exceptions.RequestException, - requests.exceptions.HTTPError, - ) as e: - log.error("Corona: error retrieving USA data from API: {0}".format(e)) - OK = False - return - if OK: - soup = BeautifulSoup(r.content) - table = soup.find("table", {"id": "usa_table_countries_today"}) - headers["states"] = [header.text for header in table.find_all("th")] - results = [ - { - headers["states"][i]: cell.text.strip() - for i, cell in enumerate(row.find_all("td")) - } - for row in table.find_all("tr") - ] - results = sorted( - results, - key=lambda k_v: int(re.sub(r"[^\d]", "", k_v["TotalCases"])) - if len(k_v) == len(headers["states"]) - else 0, - reverse=True, - ) - top = [] - for item in results: - if len(item) == len(headers["states"]): - i = 0 - while i < len(headers["states"]): - if not item[headers["states"][i]]: - item[headers["states"][i]] = "0" - if re.sub( - r"[^\w. ]", "", item[headers["states"][i]] - ).isdigit(): - item[headers["states"][i]] = int( - re.sub(r"[^\d]", "", item[headers["states"][i]]) - ) - i += 1 - self.states[item["USAState"]] = item - rank = results.index(item) - self.states[item["USAState"]]["rank"] = rank - if rank > 0 and rank <= 10: - top.append( - "#{0}: \x1F{1}\x1F (\x0307{2}\x03/\x0304{3}\x03)" - .format( - rank, - item["USAState"], - "{:,}".format(item["TotalCases"]), - "{:,}".format(item["TotalDeaths"]), - ) - ) - self.top["states"] = top - for item in self.states: - try: - self.states[item]["ratio_new_cases"] = "{0:.1%}".format( - self.states[item]["NewCases"] - / ( - self.states[item]["TotalCases"] - - self.states[item]["NewCases"] - ) - ) - except: - self.states[item]["ratio_new_cases"] = "0%" - try: - self.states[item]["ratio_new_dead"] = "{0:.1%}".format( - self.states[item]["NewDeaths"] - / ( - self.states[item]["TotalDeaths"] - - self.states[item]["NewDeaths"] - ) - ) - except: - self.states[item]["ratio_new_dead"] = "0%" - try: - self.states[item]["ratio_dead"] = "{0:.1%}".format( - self.states[item]["TotalDeaths"] - / self.states[item]["TotalCases"] - ) - except: - self.states[item]["ratio_dead"] = "N/A" - for value in self.states[item]: - if isinstance(self.states[item][value], int): - self.states[item][value] = "{:,}".format( - self.states[item][value] - ) - return True - else: - log.error("Corona: unable to retrieve latest USA data") - return - elif len(self.countries) > 0 and len(self.states) > 0: - log.info("Corona: data not yet updated, using cache") - return True - else: - log.error("Corona: Error. Unable to retrieve data.") - return - - @wrap([getopts({"top10": ""}), optional("text")]) - def corona(self, irc, msg, args, optlist, search): - """[region] - Return Coronavirus statistics from https://www.worldometers.info/coronavirus/. - Search accepts full country/state names or ISO 3166-1 alpha-2 (two character) - country abbreviations and US Postal (two character) state abbreviations. - Invalid region names or search terms without data return global results. - """ - optlist = dict(optlist) - if "top10" in optlist: - self.top10(irc, msg, args, None) - return - if search: - search = search.strip() - if not self.get_data(): - irc.reply( - "Error retrieving data from https://www.worldometers.info/coronavirus/" - ) - return - if search and len(search) == 2: - if self.registryValue("countryFirst", msg.channel): - try: - search = countries[search.upper()] - except KeyError: - try: - search = states[search.upper()] - except KeyError: - pass - else: - try: - search = states[search.upper()] - except KeyError: - try: - search = countries[search.upper()] - except KeyError: - pass - - def reply_country(): - irc.reply( - "\x02\x1F{0}\x1F: World Rank: #{1} | Cases: \x0307{2}\x03 " - "(\x0307+{3}\x03) (\x0307+{4}\x03) | Deaths: \x0304{5}\x03 " - "(\x0304{6}\x03) (\x0304+{7}\x03) (\x0304+{8}\x03) | Recovered: " - "\x0309{9}\x03 (\x0309{10}\x03) | Active: \x0307{11}\x03 " - "(\x0310{12}\x03 Mild) (\x0313{13}\x03 Serious) (\x0310{14}\x03/" - "\x0313{15}\x03) | Cases/1M: \x0307{16}\x03 | Deaths/1M: \x0304{17}" - "\x03 | Updated: {18}".format( - self.countries[search]["Country,Other"], - self.countries[search]["rank"], - self.countries[search]["TotalCases"], - self.countries[search]["NewCases"], - self.countries[search]["ratio_new_cases"], - self.countries[search]["TotalDeaths"], - self.countries[search]["ratio_dead"], - self.countries[search]["NewDeaths"], - self.countries[search]["ratio_new_dead"], - self.countries[search]["TotalRecovered"], - self.countries[search]["ratio_recovered"], - self.countries[search]["ActiveCases"], - self.countries[search]["mild"], - self.countries[search]["Serious,Critical"], - self.countries[search]["ratio_mild"], - self.countries[search]["ratio_serious"], - self.countries[search]["Tot\xa0Cases/1M pop"], - self.countries[search]["Deaths/1M pop"], - self.time_created(self.updated), - ) - ) - - def reply_state(): - irc.reply( - "\x02\x1F{0}\x1F: USA Rank: #{1} | Cases: \x0307{2}\x03 " - "(\x0307+{3}\x03) (\x0307+{4}\x03) | Deaths: \x0304{5}\x03 " - "(\x0304{6}\x03) (\x0304+{7}\x03) (\x0304+{8}\x03) | Active: " - "\x0307{9}\x03 | Cases/1M: \x0307{10}\x03 | Deaths/1M: " - "\x0304{11}\x03 | Updated: {12}".format( - self.states[search]["USAState"], - self.states[search]["rank"], - self.states[search]["TotalCases"], - self.states[search]["NewCases"], - self.states[search]["ratio_new_cases"], - self.states[search]["TotalDeaths"], - self.states[search]["ratio_dead"], - self.states[search]["NewDeaths"], - self.states[search]["ratio_new_dead"], - self.states[search]["ActiveCases"], - self.states[search]["Tot\xa0Cases/1M pop"], - self.states[search]["Deaths/1M pop"], - self.time_created(self.updated), - ) - ) - - def reply_global(): - irc.reply( - "\x02\x1F{0}\x1F: Cases: \x0307{1}\x03 (\x0307+{2}\x03) " - "(\x0307+{3}\x03) | Deaths: \x0304{4}\x03 (\x0304{5}\x03) " - "(\x0304+{6}\x03) (\x0304+{7}\x03) | Recovered: \x0309{8}\x03 " - "(\x0309{9}\x03) | Active: \x0307{10}\x03 (\x0310{11}\x03 Mild) " - "(\x0313{12}\x03 Serious) (\x0310{13}\x03/\x0313{14}\x03) | " - "Cases/1M: \x0307{15}\x03 | Deaths/1M: \x0304{16}\x03 | " - "Updated: {17}".format( - "Global", - self.countries[list(self.countries)[0]]["TotalCases"], - self.countries[list(self.countries)[0]]["NewCases"], - self.countries[list(self.countries)[0]]["ratio_new_cases"], - self.countries[list(self.countries)[0]]["TotalDeaths"], - self.countries[list(self.countries)[0]]["ratio_dead"], - self.countries[list(self.countries)[0]]["NewDeaths"], - self.countries[list(self.countries)[0]]["ratio_new_dead"], - self.countries[list(self.countries)[0]]["TotalRecovered"], - self.countries[list(self.countries)[0]]["ratio_recovered"], - self.countries[list(self.countries)[0]]["ActiveCases"], - self.countries[list(self.countries)[0]]["mild"], - self.countries[list(self.countries)[0]]["Serious,Critical"], - self.countries[list(self.countries)[0]]["ratio_mild"], - self.countries[list(self.countries)[0]]["ratio_serious"], - self.countries[list(self.countries)[0]]["Tot\xa0Cases/1M pop"], - self.countries[list(self.countries)[0]]["Deaths/1M pop"], - self.time_created(self.updated), - ) - ) - - if self.registryValue("countryFirst", msg.channel): - if search and self.countries.get(search): - reply_country() - elif search and self.states.get(search): - reply_state() - else: - reply_global() - else: - if search and self.states.get(search): - reply_state() - elif search and self.countries.get(search): - reply_country() - else: - reply_global() - - @wrap([optional("text")]) - def top10(self, irc, msg, args, search): - """[usa|global] - Return the countries with the most confirmed cases. Valid options are USA or - global. Returns global list if no option given. - """ - if not self.get_data(): - irc.reply( - "Error retrieving data from https://www.worldometers.info/coronavirus/" - ) - return - if search: - search = search.strip().lower() - else: - search = "global" - if not search.startswith("us"): - irc.reply( - "{0} | Updated: {1}".format( - ", ".join(self.top["countries"]), self.time_created(self.updated) - ) - ) - else: - irc.reply( - "{0} | Updated: {1}".format( - ", ".join(self.top["states"]), self.time_created(self.updated) - ) - ) - - -Class = Corona diff --git a/Corona/requirements.txt b/Corona/requirements.txt deleted file mode 100644 index 1190bd8..0000000 --- a/Corona/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -requests -beautifulsoup4 diff --git a/Corona/setup.py b/Corona/setup.py deleted file mode 100644 index d98dd00..0000000 --- a/Corona/setup.py +++ /dev/null @@ -1,9 +0,0 @@ -from supybot.setup import plugin_setup - -plugin_setup( - 'Corona', - install_requires=[ - 'beautifulsoup4', - 'requests', - ], -)