mirror of
https://github.com/oddluck/limnoria-plugins.git
synced 2025-04-25 20:41:21 -05:00
Readd old Corona plugin as CoronaLight
This commit is contained in:
parent
c6054f57be
commit
cfd4fd606a
13
CoronaLight/README.md
Normal file
13
CoronaLight/README.md
Normal file
@ -0,0 +1,13 @@
|
||||
Old version of plugin. Return the latest Coronavirus (COVID-19) statistics. Uses JHU data.
|
||||
|
||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=T8E56M6SP9JH2)
|
||||
|
||||
`config plugins.coronalight.template` - Configure the template for replies
|
||||
|
||||
Template default: `\x02$location: \x0307$confirmed\x03 infected, \x0304$dead\x03 dead ($ratio), \x0309$recovered\x03 recovered. (Last update: $updated)`
|
||||
|
||||
`config plugins.coronalight.countryFirst` - Country name abbreviations take precedence over USA state name abbreviations when `True`
|
||||
|
||||
countryFirst default: `False`
|
||||
|
||||
`config plugins.coronalight.cacheLifetime` - Time in seconds to cache API results. Default: `600`
|
66
CoronaLight/__init__.py
Normal file
66
CoronaLight/__init__.py
Normal file
@ -0,0 +1,66 @@
|
||||
###
|
||||
# Copyright (c) 2020, Hoaas
|
||||
# Copyright (c) 2020, oddluck <oddluck@riseup.net>
|
||||
# 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.
|
||||
###
|
||||
|
||||
"""
|
||||
CoronaLight: Return Corona virus 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__ = {}
|
||||
|
||||
# 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 imp 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
|
60
CoronaLight/config.py
Normal file
60
CoronaLight/config.py
Normal file
@ -0,0 +1,60 @@
|
||||
###
|
||||
# Copyright (c) 2020, Hoaas
|
||||
# Copyright (c) 2020, oddluck <oddluck@riseup.net>
|
||||
# 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('CoronaLight')
|
||||
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('CoronaLight', True)
|
||||
|
||||
|
||||
CoronaLight = conf.registerPlugin('CoronaLight')
|
||||
|
||||
conf.registerChannelValue(CoronaLight, 'template',
|
||||
registry.String("\x02\x1F$location\x1F: Cases: \x0307$confirmed\x03 | Deaths: \x0304$dead\x03 (\x0304$ratio\x03) | Recovered: \x0309$recovered\x03 | Updated: $updated", _("""Template for replies""")))
|
||||
|
||||
conf.registerChannelValue(CoronaLight, 'countryFirst',
|
||||
registry.Boolean(False, _("Give preference to country name abbreviations over USA state name abbreviations")))
|
||||
|
||||
conf.registerGlobalValue(CoronaLight, 'cacheLifetime',
|
||||
registry.Integer(600, _("Amount of time in seconds to cache API results")))
|
569
CoronaLight/plugin.py
Normal file
569
CoronaLight/plugin.py
Normal file
@ -0,0 +1,569 @@
|
||||
###
|
||||
# Copyright (c) 2020, Hoaas
|
||||
# Copyright (c) 2020, oddluck <oddluck@riseup.net>
|
||||
# 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 json
|
||||
import requests
|
||||
import csv
|
||||
import datetime
|
||||
from supybot import utils, plugins, ircutils, callbacks, log
|
||||
from supybot.commands import *
|
||||
try:
|
||||
from supybot.i18n import PluginInternationalization
|
||||
_ = PluginInternationalization('CoronaLight')
|
||||
except ImportError:
|
||||
# Placeholder that allows to run the plugin on a bot
|
||||
# without the i18n module
|
||||
_ = lambda x: x
|
||||
|
||||
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, THE",
|
||||
"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": "CAPE VERDE",
|
||||
"KY": "CAYMAN ISLANDS",
|
||||
"CF": "CENTRAL AFRICAN REPUBLIC",
|
||||
"TD": "CHAD",
|
||||
"CL": "CHILE",
|
||||
"CN": "CHINA",
|
||||
"CX": "CHRISTMAS ISLAND",
|
||||
"CC": "COCOS ISLANDS",
|
||||
"CO": "COLOMBIA",
|
||||
"KM": "COMOROS",
|
||||
"CG": "CONGO (BRAZZAVILLE)",
|
||||
"CD": "CONGO (KINSHASA)",
|
||||
"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": "GUIANA",
|
||||
"PF": "POLYNESIA",
|
||||
"TF": "FRENCH SOUTHERN TERRITORIES",
|
||||
"GA": "GABON",
|
||||
"GM": "GAMBIA, THE",
|
||||
"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-BISSAU",
|
||||
"GY": "GUYANA",
|
||||
"HT": "HAITI",
|
||||
"HM": "HEARD ISLAND AND MCDONALD ISLANDS",
|
||||
"VA": "HOLY SEE",
|
||||
"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": "KOREA, NORTH",
|
||||
"KR": "KOREA, SOUTH",
|
||||
"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, STATE OF",
|
||||
"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": "SAINT BARTHÉLEMY",
|
||||
"SH": "SAINT HELENA",
|
||||
"KN": "SAINT KITTS AND NEVIS",
|
||||
"LC": "SAINT LUCIA",
|
||||
"MF": "SAINT MARTIN",
|
||||
"PM": "SAINT PIERRE AND MIQUELON",
|
||||
"VC": "SAINT VINCENT AND THE 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": "SOUTH 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 ISLANDS",
|
||||
"TV": "TUVALU",
|
||||
"UG": "UGANDA",
|
||||
"UA": "UKRAINE",
|
||||
"AE": "UNITED ARAB EMIRATES",
|
||||
"GB": "UNITED KINGDOM",
|
||||
"UK": "UNITED KINGDOM",
|
||||
"US": "US",
|
||||
"UM": "UNITED STATES MINOR OUTLYING ISLANDS",
|
||||
"UY": "URUGUAY",
|
||||
"UZ": "UZBEKISTAN",
|
||||
"VU": "VANUATU",
|
||||
"VE": "VENEZUELA",
|
||||
"VN": "VIETNAM",
|
||||
"VG": "VIRGIN ISLANDS",
|
||||
"VI": "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'
|
||||
}
|
||||
|
||||
class CoronaLight(callbacks.Plugin):
|
||||
"""Displays current stats of the Coronavirus outbreak"""
|
||||
threaded = True
|
||||
|
||||
def __init__(self, irc):
|
||||
self.__parent = super(CoronaLight, self)
|
||||
self.__parent.__init__(irc)
|
||||
self.cache = {}
|
||||
|
||||
def getCSV(self):
|
||||
data = None
|
||||
try:
|
||||
day = datetime.date.today().strftime('%m-%d-%Y')
|
||||
url = "https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_daily_reports/{0}.csv".format(day)
|
||||
r = requests.get(url, timeout=10)
|
||||
r.raise_for_status()
|
||||
except (requests.exceptions.RequestException, requests.exceptions.HTTPError) as e:
|
||||
log.debug('Corona: error retrieving data for today: {0}'.format(e))
|
||||
try:
|
||||
day = datetime.date.today() - datetime.timedelta(days=1)
|
||||
day = day.strftime('%m-%d-%Y')
|
||||
url = "https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_daily_reports/{0}.csv".format(day)
|
||||
r = requests.get(url, timeout=10)
|
||||
r.raise_for_status()
|
||||
except (requests.exceptions.RequestException, requests.exceptions.HTTPError) as e:
|
||||
log.debug('Corona: error retrieving data for yesterday: {0}'.format(e))
|
||||
else:
|
||||
data = csv.DictReader(r.iter_lines(decode_unicode = True))
|
||||
else:
|
||||
data = csv.DictReader(r.iter_lines(decode_unicode = True))
|
||||
return data
|
||||
|
||||
def getAPI(self):
|
||||
data = None
|
||||
url = "https://services1.arcgis.com/0MSEUqKaxRlEPj5g/arcgis/rest/services/ncov_cases/FeatureServer/1/query?f=json&where=Confirmed>0&outFields=*"
|
||||
try:
|
||||
r = requests.get(url, timeout=10)
|
||||
r.raise_for_status()
|
||||
except (requests.exceptions.RequestException, requests.exceptions.HTTPError) as e:
|
||||
log.debug('Corona: error retrieving data from API: {0}'.format(e))
|
||||
else:
|
||||
try:
|
||||
r = json.loads(r.content.decode())
|
||||
data = r.get('features')
|
||||
except:
|
||||
data = None
|
||||
if not data:
|
||||
log.debug("Corona: Error retrieving features data from API.")
|
||||
return data
|
||||
|
||||
def timeCreated(self, time):
|
||||
time = datetime.datetime.fromtimestamp(time/1000.0)
|
||||
d = datetime.datetime.now() - 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
|
||||
|
||||
@wrap([optional('text')])
|
||||
def corona(self, irc, msg, args, search):
|
||||
"""[region]
|
||||
Displays Coronavirus statistics. Add a region name to search for country/state
|
||||
specific results. 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.
|
||||
"""
|
||||
git = api = False
|
||||
data = None
|
||||
if len(self.cache) > 0:
|
||||
cacheLifetime = self.registryValue("cacheLifetime")
|
||||
now = datetime.datetime.now()
|
||||
seconds = (now - self.cache['timestamp']).total_seconds()
|
||||
if seconds < cacheLifetime:
|
||||
data = self.cache['data']
|
||||
api = True
|
||||
log.debug("Corona: returning cached API data")
|
||||
else:
|
||||
data = self.getAPI()
|
||||
if data:
|
||||
api = True
|
||||
self.cache['timestamp'] = datetime.datetime.now()
|
||||
self.cache['data'] = data
|
||||
log.debug("Corona: caching API data")
|
||||
else:
|
||||
now = datetime.datetime.now()
|
||||
midnight = now.replace(hour=0, minute=0, second=0, microsecond=0)
|
||||
seconds = (now - midnight).seconds
|
||||
if seconds > (now - self.cache['timestamp']).total_seconds():
|
||||
data = self.cache['data']
|
||||
api = True
|
||||
log.debug("Corona: error accessing API, returning cached API data")
|
||||
else:
|
||||
data = self.getCSV()
|
||||
if data:
|
||||
git = True
|
||||
else:
|
||||
data = self.getAPI()
|
||||
if data:
|
||||
api = True
|
||||
self.cache['timestamp'] = datetime.datetime.now()
|
||||
self.cache['data'] = data
|
||||
log.debug("Corona: caching API data")
|
||||
else:
|
||||
data = self.getCSV()
|
||||
if data:
|
||||
git = True
|
||||
if not data:
|
||||
irc.reply("Error. Unable to access database.")
|
||||
return
|
||||
total_confirmed = total_deaths = total_recovered = total_active = last_update = 0
|
||||
confirmed = deaths = recovered = active = updated = 0
|
||||
location = 'Global'
|
||||
for region in data:
|
||||
if api:
|
||||
r = region.get('attributes')
|
||||
else:
|
||||
r = region
|
||||
if search:
|
||||
if api:
|
||||
region = r.get('Country_Region')
|
||||
state = r.get('Province_State')
|
||||
else:
|
||||
region = r.get('Country/Region')
|
||||
state = r.get('Province/State')
|
||||
if 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
|
||||
if search.lower() == 'usa' or 'united states' in search.lower():
|
||||
search = 'us'
|
||||
if 'korea' in search.lower():
|
||||
search = 'korea, south'
|
||||
if region and search.lower() == region.lower():
|
||||
location = region
|
||||
confirmed += int(r.get('Confirmed'))
|
||||
deaths += int(r.get('Deaths'))
|
||||
recovered += int(r.get('Recovered'))
|
||||
active += int(r.get('Active'))
|
||||
if api:
|
||||
time = int(r.get('Last_Update'))
|
||||
if git:
|
||||
time = datetime.datetime.strptime(r.get('Last Update'), "%Y-%m-%dT%H:%M:%S")
|
||||
time = int(time.timestamp()*1000)
|
||||
if time > updated:
|
||||
updated = time
|
||||
local_ratio_dead = "{0:.1%}".format(deaths/confirmed)
|
||||
elif state and search.lower() == state.lower():
|
||||
location = state
|
||||
confirmed += int(r.get('Confirmed'))
|
||||
deaths += int(r.get('Deaths'))
|
||||
recovered += int(r.get('Recovered'))
|
||||
active += int(r.get('Active'))
|
||||
if api:
|
||||
time = int(r.get('Last_Update'))
|
||||
if git:
|
||||
time = datetime.datetime.strptime(r.get('Last Update'), "%Y-%m-%dT%H:%M:%S")
|
||||
time = int(time.timestamp()*1000)
|
||||
if time > updated:
|
||||
updated = time
|
||||
local_ratio_dead = "{0:.1%}".format(deaths/confirmed)
|
||||
total_confirmed += int(r.get('Confirmed'))
|
||||
total_deaths += int(r.get('Deaths'))
|
||||
total_recovered += int(r.get('Recovered'))
|
||||
total_active += int(r.get('Active'))
|
||||
if api:
|
||||
time = int(r.get('Last_Update'))
|
||||
if git:
|
||||
time = datetime.datetime.strptime(r.get('Last Update'), "%Y-%m-%dT%H:%M:%S")
|
||||
time = int(time.timestamp()*1000)
|
||||
if time > last_update:
|
||||
last_update = time
|
||||
ratio_dead = "{0:.1%}".format(total_deaths/total_confirmed)
|
||||
template = self.registryValue("template", msg.channel)
|
||||
if location == 'Global':
|
||||
last_update = self.timeCreated(last_update)
|
||||
template = template.replace("$location", location)
|
||||
template = template.replace("$confirmed", str(total_confirmed))
|
||||
template = template.replace("$dead", str(total_deaths))
|
||||
template = template.replace("$recovered", str(total_recovered))
|
||||
template = template.replace("$ratio", ratio_dead)
|
||||
template = template.replace("$active", str(total_active))
|
||||
template = template.replace("$updated", last_update)
|
||||
else:
|
||||
updated = self.timeCreated(updated)
|
||||
template = template.replace("$location", location)
|
||||
template = template.replace("$confirmed", str(confirmed))
|
||||
template = template.replace("$dead", str(deaths))
|
||||
template = template.replace("$recovered", str(recovered))
|
||||
template = template.replace("$ratio", local_ratio_dead)
|
||||
template = template.replace("$active", str(active))
|
||||
template = template.replace("$updated", updated)
|
||||
irc.reply(template)
|
||||
|
||||
Class = CoronaLight
|
1
CoronaLight/requirements.txt
Normal file
1
CoronaLight/requirements.txt
Normal file
@ -0,0 +1 @@
|
||||
requests
|
Loading…
x
Reference in New Issue
Block a user