Corona/SpiffyTitles: cleanup, formatting

This commit is contained in:
oddluck 2020-06-04 13:15:46 -04:00
parent 87fdaca856
commit 7cad84a682
4 changed files with 931 additions and 985 deletions

312
Corona/codes.py Normal file
View File

@ -0,0 +1,312 @@
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",
}

View File

@ -32,6 +32,7 @@ import requests
import datetime import datetime
import re import re
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from .codes import states, countries
from supybot import utils, plugins, ircutils, callbacks, log from supybot import utils, plugins, ircutils, callbacks, log
from supybot.commands import * from supybot.commands import *
@ -44,319 +45,6 @@ except ImportError:
# without the i18n module # without the i18n module
_ = lambda x: x _ = 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",
"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",
}
class Corona(callbacks.Plugin): class Corona(callbacks.Plugin):
"""Displays current stats of the Coronavirus outbreak""" """Displays current stats of the Coronavirus outbreak"""
@ -421,7 +109,7 @@ class Corona(callbacks.Plugin):
] ]
results = sorted( results = sorted(
results, results,
key=lambda k_v: int(re.sub("[^\d]", "", k_v["TotalCases"])) key=lambda k_v: int(re.sub(r"[^\d]", "", k_v["TotalCases"]))
if len(k_v) == len(headers["countries"]) if len(k_v) == len(headers["countries"])
else 0, else 0,
reverse=True, reverse=True,
@ -436,10 +124,10 @@ class Corona(callbacks.Plugin):
elif not item[headers["countries"][i]]: elif not item[headers["countries"][i]]:
item[headers["countries"][i]] = "N/A" item[headers["countries"][i]] = "N/A"
if re.sub( if re.sub(
"[^\w. ]", "", item[headers["countries"][i]] r"[^\w. ]", "", item[headers["countries"][i]]
).isdigit(): ).isdigit():
item[headers["countries"][i]] = int( item[headers["countries"][i]] = int(
re.sub("[^\d]", "", item[headers["countries"][i]]) re.sub(r"[^\d]", "", item[headers["countries"][i]])
) )
i += 1 i += 1
self.countries[item["Country,Other"]] = item self.countries[item["Country,Other"]] = item
@ -542,7 +230,7 @@ class Corona(callbacks.Plugin):
] ]
results = sorted( results = sorted(
results, results,
key=lambda k_v: int(re.sub("[^\d]", "", k_v["TotalCases"])) key=lambda k_v: int(re.sub(r"[^\d]", "", k_v["TotalCases"]))
if len(k_v) == len(headers["states"]) if len(k_v) == len(headers["states"])
else 0, else 0,
reverse=True, reverse=True,
@ -555,10 +243,10 @@ class Corona(callbacks.Plugin):
if not item[headers["states"][i]]: if not item[headers["states"][i]]:
item[headers["states"][i]] = "0" item[headers["states"][i]] = "0"
if re.sub( if re.sub(
"[^\w. ]", "", item[headers["states"][i]] r"[^\w. ]", "", item[headers["states"][i]]
).isdigit(): ).isdigit():
item[headers["states"][i]] = int( item[headers["states"][i]] = int(
re.sub("[^\d]", "", item[headers["states"][i]]) re.sub(r"[^\d]", "", item[headers["states"][i]])
) )
i += 1 i += 1
self.states[item["USAState"]] = item self.states[item["USAState"]] = item
@ -766,8 +454,6 @@ class Corona(callbacks.Plugin):
"Error retrieving data from https://www.worldometers.info/coronavirus/" "Error retrieving data from https://www.worldometers.info/coronavirus/"
) )
return return
reply = ""
n = 1
if search: if search:
search = search.strip().lower() search = search.strip().lower()
else: else:

View File

@ -190,7 +190,8 @@ conf.registerChannelValue(
SpiffyTitles.default, SpiffyTitles.default,
"mimeTypes", "mimeTypes",
registry.CommaSeparatedListOfStrings( registry.CommaSeparatedListOfStrings(
["text/html","application/xhtml+xml"], _("""Acceptable mime types for parsing html titles.""") ["text/html", "application/xhtml+xml"],
_("""Acceptable mime types for parsing html titles."""),
), ),
) )

View File

@ -406,8 +406,6 @@ class SpiffyTitles(callbacks.Plugin):
Get the HTML of a website based on a URL Get the HTML of a website based on a URL
""" """
max_retries = self.registryValue("maxRetries") max_retries = self.registryValue("maxRetries")
if not retries:
retries = 1
if retries >= max_retries: if retries >= max_retries:
log.debug("SpiffyTitles: hit maximum retries for %s" % url) log.debug("SpiffyTitles: hit maximum retries for %s" % url)
return (None, False) return (None, False)
@ -422,6 +420,7 @@ class SpiffyTitles(callbacks.Plugin):
allow_redirects=True, allow_redirects=True,
stream=True, stream=True,
) as request: ) as request:
request.raise_for_status()
is_redirect = False is_redirect = False
if request.history: if request.history:
# check the top two domain levels # check the top two domain levels
@ -435,11 +434,8 @@ class SpiffyTitles(callbacks.Plugin):
% (redir.status_code, redir.url) % (redir.status_code, redir.url)
) )
log.debug("SpiffyTitles: Final url %s" % (request.url)) log.debug("SpiffyTitles: Final url %s" % (request.url))
if request.status_code == requests.codes.ok:
# Check the content type # Check the content type
content_type = ( content_type = request.headers.get("content-type").split(";")[0].strip()
request.headers.get("content-type").split(";")[0].strip()
)
acceptable_types = self.registryValue("default.mimeTypes") acceptable_types = self.registryValue("default.mimeTypes")
log.debug("SpiffyTitles: content type %s" % (content_type)) log.debug("SpiffyTitles: content type %s" % (content_type))
if content_type in acceptable_types: if content_type in acceptable_types:
@ -467,16 +463,6 @@ class SpiffyTitles(callbacks.Plugin):
"</head><body></body></html>".format(text) "</head><body></body></html>".format(text)
) )
return (text, is_redirect) return (text, is_redirect)
else:
log.error(
"SpiffyTitles HTTP response code %s" % (request.status_code,)
)
text = self.registryValue("badLinkText", channel=channel)
text = (
"<html><head><title>{0}</title>"
"</head><body></body></html>".format(text)
)
return (text, is_redirect)
except requests.exceptions.MissingSchema as e: except requests.exceptions.MissingSchema as e:
url_wschema = "http://%s" % (url) url_wschema = "http://%s" % (url)
log.error("SpiffyTitles missing schema. Retrying with %s" % (url_wschema)) log.error("SpiffyTitles missing schema. Retrying with %s" % (url_wschema))
@ -493,8 +479,18 @@ class SpiffyTitles(callbacks.Plugin):
self.get_source_by_url(url, channel, retries + 1) self.get_source_by_url(url, channel, retries + 1)
except requests.exceptions.HTTPError as e: except requests.exceptions.HTTPError as e:
log.error("SpiffyTitles HTTPError: %s" % (str(e))) log.error("SpiffyTitles HTTPError: %s" % (str(e)))
text = self.registryValue("badLinkText", channel=channel)
text = "<html><head><title>{0}</title></head><body></body></html>".format(
text
)
return (text, is_redirect)
except requests.exceptions.InvalidURL as e: except requests.exceptions.InvalidURL as e:
log.error("SpiffyTitles InvalidURL: %s" % (str(e))) log.error("SpiffyTitles InvalidURL: %s" % (str(e)))
text = self.registryValue("badLinkText", channel=channel)
text = "<html><head><title>{0}</title></head><body></body></html>".format(
text
)
return (text, is_redirect)
return (None, False) return (None, False)
def get_base_domain(self, url): def get_base_domain(self, url):
@ -599,24 +595,33 @@ class SpiffyTitles(callbacks.Plugin):
dailymotion_handler_enabled = self.registryValue( dailymotion_handler_enabled = self.registryValue(
"dailymotion.enabled", channel=channel "dailymotion.enabled", channel=channel
) )
if not dailymotion_handler_enabled:
return self.handler_default(url, channel)
log.debug("SpiffyTitles: calling dailymotion handler for %s" % url) log.debug("SpiffyTitles: calling dailymotion handler for %s" % url)
title = None title = None
video_id = None video_id = None
""" Get video ID """ """ Get video ID """
if dailymotion_handler_enabled and "/video/" in info.path: if "/video/" in info.path:
video_id = info.path.lstrip("/video/").split("_")[0] video_id = info.path.lstrip("/video/").split("_")[0]
elif dailymotion_handler_enabled and "dai.ly" in url: elif "dai.ly" in url:
video_id = url.split("/")[-1].split("?")[0] video_id = url.split("/")[-1].split("?")[0]
if video_id: if not video_id:
fields = "id,title,owner.screenname,duration,views_total" log.error(
api_url = "https://api.dailymotion.com/video/%s?fields=%s" % ( "SpiffyTitles: unable to get dailymotion video_id for URL: %s" % url
video_id,
fields,
) )
return self.handler_default(url, channel)
fields = "id,title,owner.screenname,duration,views_total"
api_url = "https://api.dailymotion.com/video/%s?fields=%s" % (video_id, fields,)
log.debug("SpiffyTitles: looking up dailymotion info: %s", api_url) log.debug("SpiffyTitles: looking up dailymotion info: %s", api_url)
try:
request = requests.get(api_url, timeout=self.timeout) request = requests.get(api_url, timeout=self.timeout)
ok = request.status_code == requests.codes.ok request.raise_for_status()
if ok: except (
requests.exceptions.RequestException,
requests.exceptions.HTTPError,
) as e:
log.error("SpiffyTitles: dailymotion error: {0}".format(e))
return self.handler_default(url, channel)
response = json.loads(request.content.decode()) response = json.loads(request.content.decode())
if response and "title" in response: if response and "title" in response:
video = response video = response
@ -624,20 +629,12 @@ class SpiffyTitles(callbacks.Plugin):
self.registryValue("dailymotion.template", channel=channel) self.registryValue("dailymotion.template", channel=channel)
) )
video["views_total"] = "{:,}".format(int(video["views_total"])) video["views_total"] = "{:,}".format(int(video["views_total"]))
video["duration"] = self.get_duration_from_seconds( video["duration"] = self.get_duration_from_seconds(video["duration"])
video["duration"]
)
video["ownerscreenname"] = video["owner.screenname"] video["ownerscreenname"] = video["owner.screenname"]
title = dailymotion_template.render(video) title = dailymotion_template.render(video)
else: else:
log.debug( log.debug(
"SpiffyTitles: received unexpected payload from video: %s" "SpiffyTitles: received unexpected payload from video: %s" % api_url
% api_url
)
else:
log.error(
"SpiffyTitles: dailymotion handler returned %s: %s"
% (request.status_code, request.content.decode()[:200])
) )
if not title: if not title:
log.debug("SpiffyTitles: could not get dailymotion info for %s" % url) log.debug("SpiffyTitles: could not get dailymotion info for %s" % url)
@ -650,20 +647,29 @@ class SpiffyTitles(callbacks.Plugin):
Handles Vimeo links Handles Vimeo links
""" """
vimeo_handler_enabled = self.registryValue("vimeo.enabled", channel=channel) vimeo_handler_enabled = self.registryValue("vimeo.enabled", channel=channel)
if not vimeo_handler_enabled:
return self.handler_default(url, channel)
log.debug("SpiffyTitles: calling vimeo handler for %s" % url) log.debug("SpiffyTitles: calling vimeo handler for %s" % url)
title = None title = None
video_id = None video_id = None
""" Get video ID """ """ Get video ID """
if vimeo_handler_enabled:
result = re.search(r"^(http(s)://)?(www\.)?(vimeo\.com/)?(\d+)", url) result = re.search(r"^(http(s)://)?(www\.)?(vimeo\.com/)?(\d+)", url)
if result: if result:
video_id = result.group(5) video_id = result.group(5)
if video_id: if not video_id:
log.error("SpiffyTitles: Failef to get Vimeo video ID from URL: %s" % url)
return self.handler_default(url, channel)
api_url = "https://vimeo.com/api/v2/video/%s.json" % video_id api_url = "https://vimeo.com/api/v2/video/%s.json" % video_id
log.debug("SpiffyTitles: looking up vimeo info: %s", api_url) log.debug("SpiffyTitles: looking up vimeo info: %s", api_url)
try:
request = requests.get(api_url, timeout=self.timeout) request = requests.get(api_url, timeout=self.timeout)
ok = request.status_code == requests.codes.ok request.raise_for_status()
if ok: except (
requests.exceptions.RequestException,
requests.exceptions.HTTPError,
) as e:
log.error("SpiffyTitles: vimeo error: {0}".format(e))
return self.handler_default(url, channel)
response = json.loads(request.content.decode()) response = json.loads(request.content.decode())
if response and "title" in response[0]: if response and "title" in response[0]:
video = response[0] video = response[0]
@ -680,24 +686,14 @@ class SpiffyTitles(callbacks.Plugin):
video["stats_number_of_plays"] = 0 video["stats_number_of_plays"] = 0
if "stats_number_of_comments" in video: if "stats_number_of_comments" in video:
int_comments = int(video["stats_number_of_comments"]) int_comments = int(video["stats_number_of_comments"])
video["stats_number_of_comments"] = "{:,}".format( video["stats_number_of_comments"] = "{:,}".format(int_comments)
int_comments
)
else: else:
video["stats_number_of_comments"] = 0 video["stats_number_of_comments"] = 0
video["duration"] = self.get_duration_from_seconds( video["duration"] = self.get_duration_from_seconds(video["duration"])
video["duration"]
)
title = vimeo_template.render(video) title = vimeo_template.render(video)
else: else:
log.debug( log.debug(
"SpiffyTitles: received unexpected payload from video: %s" "SpiffyTitles: received unexpected payload from video: %s" % api_url
% api_url
)
else:
log.error(
"SpiffyTitles: vimeo handler returned %s: %s"
% (request.status_code, request.content.decode()[:200])
) )
if not title: if not title:
log.debug("SpiffyTitles: could not get vimeo info for %s" % url) log.debug("SpiffyTitles: could not get vimeo info for %s" % url)
@ -710,18 +706,30 @@ class SpiffyTitles(callbacks.Plugin):
Handles coub.com links Handles coub.com links
""" """
coub_handler_enabled = self.registryValue("coub.enabled", channel=channel) coub_handler_enabled = self.registryValue("coub.enabled", channel=channel)
if not coub_handler_enabled:
return self.handler_default(url, channel)
log.debug("SpiffyTitles: calling coub handler for %s" % url) log.debug("SpiffyTitles: calling coub handler for %s" % url)
title = None title = None
video_id = None
""" Get video ID """ """ Get video ID """
if coub_handler_enabled and "/view/" in url: if "/view/" in url:
video_id = url.split("/view/")[1] video_id = url.split("/view/")[1]
""" Remove any query strings """ """ Remove any query strings """
if "?" in video_id: if "?" in video_id:
video_id = video_id.split("?")[0] video_id = video_id.split("?")[0]
if not video_id:
log.error("SpiffyTitles: Failed to get Coub video ID for URL: %s" % url)
return self.handler_default(url, channel)
api_url = "http://coub.com/api/v2/coubs/%s" % video_id api_url = "http://coub.com/api/v2/coubs/%s" % video_id
try:
request = requests.get(api_url, timeout=self.timeout) request = requests.get(api_url, timeout=self.timeout)
ok = request.status_code == requests.codes.ok request.raise_for_status()
if ok: except (
requests.exceptions.RequestException,
requests.exceptions.HTTPError,
) as e:
log.error("SpiffyTitles: coub error: {0}".format(e))
return self.handler_default(url, channel)
response = json.loads(request.content.decode()) response = json.loads(request.content.decode())
if response: if response:
video = response video = response
@ -730,14 +738,8 @@ class SpiffyTitles(callbacks.Plugin):
video["recoubs_count"] = "{:,}".format(int(video["recoubs_count"])) video["recoubs_count"] = "{:,}".format(int(video["recoubs_count"]))
video["views_count"] = "{:,}".format(int(video["views_count"])) video["views_count"] = "{:,}".format(int(video["views_count"]))
title = coub_template.render(video) title = coub_template.render(video)
else:
log.error(
"SpiffyTitles: coub handler returned %s: %s"
% (request.status_code, request.content.decode()[:200])
)
if not title: if not title:
if coub_handler_enabled: log.debug("SpiffyTitles: Coub handler failed to get data for URL: %s" % url)
log.debug("SpiffyTitles: %s does not appear to be a video link!" % url)
return self.handler_default(url, channel) return self.handler_default(url, channel)
else: else:
return title return title
@ -772,9 +774,9 @@ class SpiffyTitles(callbacks.Plugin):
Youtube Video links posted. Youtube Video links posted.
""" """
youtube_handler_enabled = self.registryValue("youtube.enabled", channel) youtube_handler_enabled = self.registryValue("youtube.enabled", channel)
developer_key = self.registryValue("youtube.developerKey")
if not youtube_handler_enabled: if not youtube_handler_enabled:
return None return self.handler_default(url, channel)
developer_key = self.registryValue("youtube.developerKey")
if not developer_key: if not developer_key:
log.info( log.info(
"SpiffyTitles: no Youtube developer key set! Check the documentation " "SpiffyTitles: no Youtube developer key set! Check the documentation "
@ -783,9 +785,13 @@ class SpiffyTitles(callbacks.Plugin):
return None return None
log.debug("SpiffyTitles: calling Youtube handler for %s" % (url)) log.debug("SpiffyTitles: calling Youtube handler for %s" % (url))
video_id = self.get_video_id_from_url(url, domain) video_id = self.get_video_id_from_url(url, domain)
if not video_id:
log.debug(
"SpiffyTitles: Failed to get YouTube video ID for URL: {0}".format(url)
)
return self.handler_default(url, channel)
yt_template = Template(self.registryValue("youtube.template", channel)) yt_template = Template(self.registryValue("youtube.template", channel))
title = "" title = ""
if video_id:
options = { options = {
"part": "snippet,statistics,contentDetails", "part": "snippet,statistics,contentDetails",
"maxResults": 1, "maxResults": 1,
@ -794,13 +800,20 @@ class SpiffyTitles(callbacks.Plugin):
} }
api_url = "https://www.googleapis.com/youtube/v3/videos" api_url = "https://www.googleapis.com/youtube/v3/videos"
log.debug("SpiffyTitles: requesting %s" % (api_url)) log.debug("SpiffyTitles: requesting %s" % (api_url))
request = requests.get(api_url, params=options, timeout=self.timeout)
ok = request.status_code == requests.codes.ok
if ok:
response = json.loads(request.content.decode())
if response:
try: try:
if response["pageInfo"]["totalResults"] > 0: request = requests.get(api_url, params=options, timeout=self.timeout)
request.raise_for_status()
except (
requests.exceptions.RequestException,
requests.exceptions.HTTPError,
) as e:
log.error("SpiffyTitiles: YouTube Error: {0}".format(e))
return self.handler_default(url, channel)
response = json.loads(request.content.decode())
if not response or not response.get("items"):
log.error("SpiffyTitles: Failed to parse YouTube JSON response")
return self.handler_default(url, channel)
try:
items = response["items"] items = response["items"]
video = items[0] video = items[0]
snippet = video["snippet"] snippet = video["snippet"]
@ -816,29 +829,19 @@ class SpiffyTitles(callbacks.Plugin):
if "likeCount" in statistics: if "likeCount" in statistics:
like_count = "{:,}".format(int(statistics["likeCount"])) like_count = "{:,}".format(int(statistics["likeCount"]))
if "dislikeCount" in statistics: if "dislikeCount" in statistics:
dislike_count = "{:,}".format( dislike_count = "{:,}".format(int(statistics["dislikeCount"]))
int(statistics["dislikeCount"])
)
if "favoriteCount" in statistics: if "favoriteCount" in statistics:
favorite_count = "{:,}".format( favorite_count = "{:,}".format(int(statistics["favoriteCount"]))
int(statistics["favoriteCount"])
)
if "commentCount" in statistics: if "commentCount" in statistics:
comment_count = "{:,}".format( comment_count = "{:,}".format(int(statistics["commentCount"]))
int(statistics["commentCount"])
)
channel_title = snippet["channelTitle"] channel_title = snippet["channelTitle"]
video_duration = video["contentDetails"]["duration"] video_duration = video["contentDetails"]["duration"]
duration_seconds = self.get_total_seconds_from_duration( duration_seconds = self.get_total_seconds_from_duration(video_duration)
video_duration
)
""" """
#23 - If duration is zero, then it"s a LIVE video #23 - If duration is zero, then it"s a LIVE video
""" """
if duration_seconds > 0: if duration_seconds > 0:
duration = self.get_duration_from_seconds( duration = self.get_duration_from_seconds(duration_seconds)
duration_seconds
)
else: else:
duration = "LIVE" duration = "LIVE"
published = snippet["publishedAt"].split("T")[0] published = snippet["publishedAt"].split("T")[0]
@ -860,21 +863,9 @@ class SpiffyTitles(callbacks.Plugin):
} }
) )
title = compiled_template title = compiled_template
else:
log.debug(
"SpiffyTitles: video appears to be private; no results!"
)
except IndexError as e: except IndexError as e:
log.error( log.error(
"SpiffyTitles: IndexError. Youtube API JSON response: %s" "SpiffyTitles: IndexError. Youtube API JSON response: %s" % (str(e))
% (str(e))
)
else:
log.error("SpiffyTitles: Error parsing Youtube API JSON response")
else:
log.error(
"SpiffyTitles: Youtube API HTTP %s: %s"
% (request.status_code, request.content.decode()[:200])
) )
# If we found a title, return that. otherwise, use default handler # If we found a title, return that. otherwise, use default handler
if title: if title:
@ -950,11 +941,14 @@ class SpiffyTitles(callbacks.Plugin):
Queries twitch API for additional information about twitch links. Queries twitch API for additional information about twitch links.
This handler is for (www.)twitch.tv This handler is for (www.)twitch.tv
""" """
url = url.split("?")[0]
twitch_client_id = self.registryValue("twitch.clientID")
twitch_handler_enabled = self.registryValue("twitch.enabled", channel=channel) twitch_handler_enabled = self.registryValue("twitch.enabled", channel=channel)
if not twitch_handler_enabled or not twitch_client_id: if not twitch_handler_enabled:
return self.handler_default(url, channel) return self.handler_default(url, channel)
twitch_client_id = self.registryValue("twitch.clientID")
if not twitch_client_id:
log.error("SpiffyTitles: Please set your Twitch client ID")
return self.handler_default(url, channel)
url = url.split("?")[0]
self.log.debug("SpiffyTitles: calling twitch handler for %s" % (url)) self.log.debug("SpiffyTitles: calling twitch handler for %s" % (url))
patterns = { patterns = {
"video": { "video": {
@ -985,16 +979,27 @@ class SpiffyTitles(callbacks.Plugin):
return self.handler_default(url, channel) return self.handler_default(url, channel)
headers = {"Client-ID": twitch_client_id} headers = {"Client-ID": twitch_client_id}
self.log.debug("SpiffyTitles: twitch - requesting %s" % (data_url)) self.log.debug("SpiffyTitles: twitch - requesting %s" % (data_url))
try:
request = requests.get(data_url, timeout=self.timeout, headers=headers) request = requests.get(data_url, timeout=self.timeout, headers=headers)
ok = request.status_code == requests.codes.ok request.raise_for_status()
except (
requests.exceptions.RequestException,
requests.exceptions.HTTPError,
) as e:
log.error("SpiffytTitles: Twitch Error: {0}".format(e))
return self.handler_default(url, channel)
data = {} data = {}
if ok: try:
response = json.loads(request.content.decode()) response = json.loads(request.content.decode())
if response: except:
response = None
if not response:
log.error("SpiffyTitles: Error parsing Twitch.TV JSON response")
return self.handler_default(url, channel)
self.log.debug("SpiffyTitles: twitch - got response:\n%s" % (response)) self.log.debug("SpiffyTitles: twitch - got response:\n%s" % (response))
if "error" in response: if "error" in response:
return "[ Twitch ] - Error!" log.error("SpiffyTitles: Twitch Error: {0}".format(response["error"]))
try: return self.handler_default(url, channel)
if link_type == "channel": if link_type == "channel":
self.log.debug("SpiffyTitles: Twitch: link_type is channel") self.log.debug("SpiffyTitles: Twitch: link_type is channel")
if "data" in response and response["data"]: if "data" in response and response["data"]:
@ -1003,64 +1008,47 @@ class SpiffyTitles(callbacks.Plugin):
link_type = "stream" link_type = "stream"
else: else:
self.log.debug("SpiffyTitles: Twitch: No data[0]") self.log.debug("SpiffyTitles: Twitch: No data[0]")
data_url = ( data_url = "https://api.twitch.tv/helix/users?login={channel_name}".format(
"https://api.twitch.tv/helix/users?" **link_info
"login={channel_name}".format(**link_info)
) )
request = requests.get(
data_url, timeout=self.timeout, headers=headers
)
ok = request.status_code == requests.codes.ok
user_data = {}
if not ok:
self.log.error(
"SpiffyTitles: twitch HTTP %s: %s"
% (request.status_code, request.content.decode()[:200])
)
else:
response = json.loads(request.content.decode())
if not response:
self.log.error(
"SpiffyTitles: Error parsing Twitch JSON response"
)
else:
if "error" in response:
self.log.error(
"SpiffyTitles: twitch - error in JSON response"
)
return self.handler_default(url, channel)
try: try:
request = requests.get(data_url, timeout=self.timeout, headers=headers)
request.raise_for_status()
except (
requests.exceptions.RequestException,
requests.exceptions.HTTPError,
) as e:
log.error("SpiffyTitles: Twitch Error: {0}".format(e))
return self.handler_default(url, channel)
user_data = {}
try:
response = json.loads(request.content.decode())
user_data = response["data"][0] user_data = response["data"][0]
display_name = user_data["display_name"] display_name = user_data["display_name"]
description = user_data["description"] description = user_data["description"]
view_count = user_data["view_count"] view_count = user_data["view_count"]
except KeyError as e: except Exception as e:
self.log.error( log.error(
"SpiffyTitles: KeyError parsing Twitch.TV JSON " "SpiffyTitles: KeyError parsing Twitch.TV JSON response: %s"
"response: %s"
% (str(e)) % (str(e))
) )
elif link_type == "video": elif link_type == "video":
data = response data = response
elif link_type == "clip": elif link_type == "clip":
data = response data = response
except KeyError as e: if not data or not user_data:
self.log.error( log.error("SpiffyTitles: Twitch: Failed to get data from Twitch API")
"SpiffyTitles: KeyError parsing Twitch.TV JSON response: %s" return self.handler_default(url, channel)
% (str(e)) log.debug("SpiffyTitles: twitch - Got data '%s'" % (data))
)
if data or user_data:
self.log.debug("SpiffyTitles: twitch - Got data '%s'" % (data))
twitch_template = self.get_template( twitch_template = self.get_template(
"".join(["twitch.", link_type, "Template"]), channel "".join(["twitch.", link_type, "Template"]), channel
) )
twitch_logo = self.get_twitch_logo(channel) twitch_logo = self.get_twitch_logo(channel)
if not twitch_template: if not twitch_template:
self.log.debug( self.log.debug("SpiffyTitles - twitch: bad template for %s" % (link_type))
"SpiffyTitles - twitch: bad template for %s" % (link_type) log.error("SpiffyTitles: Twitch: Got data, but template was bad")
) return self.handler_default(url, channel)
reply = "[ Twitch.TV ] - Got data, but template was bad" if link_type == "stream":
elif link_type == "stream":
display_name = data["user_name"] display_name = data["user_name"]
game_id = data["game_id"] game_id = data["game_id"]
game_name = game_id game_name = game_id
@ -1069,9 +1057,7 @@ class SpiffyTitles(callbacks.Plugin):
created_at = self._time_created_at(data["started_at"]) created_at = self._time_created_at(data["started_at"])
if game_id: if game_id:
get_game = requests.get( get_game = requests.get(
"https://api.twitch.tv/helix/games?id={}".format( "https://api.twitch.tv/helix/games?id={}".format(game_id),
game_id
),
timeout=self.timeout, timeout=self.timeout,
headers=headers, headers=headers,
) )
@ -1090,40 +1076,21 @@ class SpiffyTitles(callbacks.Plugin):
elif link_type == "clip": elif link_type == "clip":
data = response["data"][0] data = response["data"][0]
display_name = data["broadcaster_name"] display_name = data["broadcaster_name"]
data_url = "https://api.twitch.tv/helix/users?login={}".format( data_url = "https://api.twitch.tv/helix/users?login={}".format(display_name)
display_name
)
request = requests.get(
data_url, timeout=self.timeout, headers=headers
)
ok = request.status_code == requests.codes.ok
user_data = {}
if not ok:
self.log.error(
"SpiffyTitles: twitch HTTP %s: %s"
% (request.status_code, request.content.decode()[:200])
)
else:
response = json.loads(request.content.decode())
if not response:
self.log.error(
"SpiffyTitles: Error parsing Twitch JSON response"
)
else:
if "error" in response:
self.log.error(
"SpiffyTitles: twitch - error in JSON response"
)
return self.handler_default(url, channel)
try: try:
request = requests.get(data_url, timeout=self.timeout, headers=headers)
request.raise_for_status()
except (
requests.exceptions.RequestException,
requests.exceptions.HTTPError,
) as e:
log.error("SpiffyTitles: Twitch Error: {0}".format(e))
return self.handler_default(url, channel)
user_data = {}
try:
response = json.loads(request.content.decode())
user_data = response["data"][0] user_data = response["data"][0]
description = user_data["description"] description = user_data["description"]
except KeyError as e:
self.log.error(
"SpiffyTitles: KeyError parsing Twitch.TV JSON "
"response: %s"
% (str(e))
)
game_id = data["game_id"] game_id = data["game_id"]
game_name = game_id game_name = game_id
title = data["title"] title = data["title"]
@ -1131,9 +1098,7 @@ class SpiffyTitles(callbacks.Plugin):
created_at = self._time_created_at(data["created_at"]) created_at = self._time_created_at(data["created_at"])
if game_id: if game_id:
get_game = requests.get( get_game = requests.get(
"https://api.twitch.tv/helix/games?id={}".format( "https://api.twitch.tv/helix/games?id={}".format(game_id),
game_id
),
timeout=self.timeout, timeout=self.timeout,
headers=headers, headers=headers,
) )
@ -1149,43 +1114,27 @@ class SpiffyTitles(callbacks.Plugin):
"twitch_logo": twitch_logo, "twitch_logo": twitch_logo,
} }
reply = twitch_template.render(template_vars) reply = twitch_template.render(template_vars)
except Exception as e:
self.log.error(
"SpiffyTitles: Error parsing Twitch.TV JSON response: %s" % (str(e))
)
elif link_type == "video": elif link_type == "video":
data = response["data"][0] data = response["data"][0]
display_name = data["user_name"] display_name = data["user_name"]
data_url = "https://api.twitch.tv/helix/users?login={}".format( data_url = "https://api.twitch.tv/helix/users?login={}".format(display_name)
display_name
)
request = requests.get(
data_url, timeout=self.timeout, headers=headers
)
ok = request.status_code == requests.codes.ok
user_data = {}
if not ok:
self.log.error(
"SpiffyTitles: twitch HTTP %s: %s"
% (request.status_code, request.content.decode()[:200])
)
else:
response = json.loads(request.content.decode())
if not response:
self.log.error(
"SpiffyTitles: Error parsing Twitch JSON response"
)
else:
if "error" in response:
self.log.error(
"SpiffyTitles: twitch - error in JSON response"
)
return self.handler_default(url, channel)
try: try:
request = requests.get(data_url, timeout=self.timeout, headers=headers)
except (
requests.exceptions.RequestException,
requests.exceptions.HTTPError,
) as e:
log.error("SpiffyTitles: Twitch Error: {0}".format(e))
return self.handler_default(url, channel)
user_data = {}
try:
response = json.loads(request.content.decode())
user_data = response["data"][0] user_data = response["data"][0]
description = user_data["description"] description = user_data["description"]
except KeyError as e:
self.log.error(
"SpiffyTitles: KeyError parsing Twitch.TV JSON "
"response: %s"
% (str(e))
)
title = data["title"] title = data["title"]
view_count = data["view_count"] view_count = data["view_count"]
created_at = self._time_created_at(data["created_at"]) created_at = self._time_created_at(data["created_at"])
@ -1200,7 +1149,12 @@ class SpiffyTitles(callbacks.Plugin):
"twitch_logo": twitch_logo, "twitch_logo": twitch_logo,
} }
reply = twitch_template.render(template_vars) reply = twitch_template.render(template_vars)
except Exception as e:
self.log.error(
"SpiffyTitles: Error parsing Twitch.TV JSON response: %s" % (str(e))
)
else: else:
try:
template_vars = { template_vars = {
"display_name": display_name, "display_name": display_name,
"description": description, "description": description,
@ -1208,7 +1162,10 @@ class SpiffyTitles(callbacks.Plugin):
"twitch_logo": twitch_logo, "twitch_logo": twitch_logo,
} }
reply = twitch_template.render(template_vars) reply = twitch_template.render(template_vars)
self.log.debug("SpiffyTitles: twitch - reply = '%s'" % (reply)) except Exception as e:
self.log.error(
"SpiffyTitles: Error parsing Twitch.TV JSON response: %s" % (str(e))
)
return reply return reply
def _time_created_at(self, s): def _time_created_at(self, s):
@ -1251,20 +1208,23 @@ class SpiffyTitles(callbacks.Plugin):
Handles imdb.com links, querying the OMDB API for additional info Handles imdb.com links, querying the OMDB API for additional info
Typical IMDB URL: http://www.imdb.com/title/tt2467372/ Typical IMDB URL: http://www.imdb.com/title/tt2467372/
""" """
apikey = self.registryValue("imdb.omdbAPI")
result = None
response = None
if not self.registryValue("imdb.enabled", channel=channel): if not self.registryValue("imdb.enabled", channel=channel):
log.debug( log.debug(
"SpiffyTitles: IMDB handler disabled. Falling back to default handler." "SpiffyTitles: IMDB handler disabled. Falling back to default handler."
) )
return self.handler_default(url, channel) return self.handler_default(url, channel)
apikey = self.registryValue("imdb.omdbAPI")
result = None
response = None
# Don't care about query strings # Don't care about query strings
if "?" in url: if "?" in url:
url = url.split("?")[0] url = url.split("?")[0]
# We can only accommodate a specific format of URL here # We can only accommodate a specific format of URL here
if "/title/" in url: if "/title/" in url:
imdb_id = url.split("/title/")[1].rstrip("/") imdb_id = url.split("/title/")[1].rstrip("/").strip()
if not imdb_id:
log.error("SpiffyTitles: Invalid IMDB URL: %s" % url)
return self.handler_default(url, channel)
omdb_url = "http://www.omdbapi.com/" omdb_url = "http://www.omdbapi.com/"
options = {"apikey": apikey, "i": imdb_id, "r": "json", "plot": "short"} options = {"apikey": apikey, "i": imdb_id, "r": "json", "plot": "short"}
try: try:
@ -1379,27 +1339,25 @@ class SpiffyTitles(callbacks.Plugin):
api_url = "https://%s/w/api.php" % (info.netloc) api_url = "https://%s/w/api.php" % (info.netloc)
extract = "" extract = ""
self.log.debug("SpiffyTitles: requesting %s" % (api_url)) self.log.debug("SpiffyTitles: requesting %s" % (api_url))
try:
request = requests.get(api_url, params=api_params, timeout=self.timeout) request = requests.get(api_url, params=api_params, timeout=self.timeout)
ok = request.status_code == requests.codes.ok request.raise_for_status()
if ok: except (
requests.exceptions.RequestException,
requests.exceptions.HTTPError,
) as e:
log.error("SpiffyTitles: Wikipedia Error: {0}".format(e))
return self.handler_default(url, channel)
response = json.loads(request.content.decode()) response = json.loads(request.content.decode())
if response: if response:
try: try:
extract = list(response["query"]["pages"].values())[0]["extract"] extract = list(response["query"]["pages"].values())[0]["extract"]
except KeyError as e: except KeyError as e:
self.log.error( self.log.error(
"SpiffyTitles: KeyError. Wikipedia API JSON response: %s" "SpiffyTitles: KeyError. Wikipedia API JSON response: %s" % (str(e))
% (str(e))
) )
else: else:
self.log.error( self.log.error("SpiffyTitles: Error parsing Wikipedia API JSON response")
"SpiffyTitles: Error parsing Wikipedia API JSON response"
)
else:
self.log.error(
"SpiffyTitles: Wikipedia API HTTP %s: %s"
% (request.status_code, request.content.decode()[:200])
)
if extract: if extract:
if self.registryValue("wikipedia.removeParentheses"): if self.registryValue("wikipedia.removeParentheses"):
extract = re.sub(r" ?\([^)]*\)", "", extract) extract = re.sub(r" ?\([^)]*\)", "", extract)
@ -1456,11 +1414,17 @@ class SpiffyTitles(callbacks.Plugin):
self.log.debug("SpiffyTitles: no title found.") self.log.debug("SpiffyTitles: no title found.")
return self.handler_default(url, channel) return self.handler_default(url, channel)
self.log.debug("SpiffyTitles: requesting %s" % (data_url)) self.log.debug("SpiffyTitles: requesting %s" % (data_url))
try:
request = requests.get(data_url, timeout=self.timeout) request = requests.get(data_url, timeout=self.timeout)
ok = request.status_code == requests.codes.ok request.raise_for_status()
except (
requests.exceptions.RequestException,
requests.exceptions.HTTPError,
) as e:
log.error("SpiffyTitles: Reddit Error: {0}".format(e))
return self.handler_default(url, channel)
data = {} data = {}
extract = "" extract = ""
if ok:
response = json.loads(request.content.decode()) response = json.loads(request.content.decode())
if response: if response:
try: try:
@ -1468,23 +1432,15 @@ class SpiffyTitles(callbacks.Plugin):
data = response[0]["data"]["children"][0]["data"] data = response[0]["data"]["children"][0]["data"]
if link_type == "comment": if link_type == "comment":
data = response[1]["data"]["children"][0]["data"] data = response[1]["data"]["children"][0]["data"]
data["title"] = response[0]["data"]["children"][0]["data"][ data["title"] = response[0]["data"]["children"][0]["data"]["title"]
"title"
]
if link_type == "user": if link_type == "user":
data = response["data"] data = response["data"]
except KeyError as e: except KeyError as e:
self.log.error( self.log.error(
"SpiffyTitles: KeyError parsing Reddit JSON response: %s" "SpiffyTitles: KeyError parsing Reddit JSON response: %s" % (str(e))
% (str(e))
) )
else: else:
self.log.error("SpiffyTitles: Error parsing Reddit JSON response") self.log.error("SpiffyTitles: Error parsing Reddit JSON response")
else:
self.log.error(
"SpiffyTitles: Reddit HTTP %s: %s"
% (request.status_code, request.content.decode()[:200])
)
if data: if data:
today = datetime.datetime.now().date() today = datetime.datetime.now().date()
created = datetime.datetime.fromtimestamp(data["created_utc"]).date() created = datetime.datetime.fromtimestamp(data["created_utc"]).date()
@ -1575,7 +1531,12 @@ class SpiffyTitles(callbacks.Plugin):
imgur provides the following information about albums: imgur provides the following information about albums:
https://api.imgur.com/models/album https://api.imgur.com/models/album
""" """
if self.registryValue("imgur.enabled", channel=channel): if not self.registryValue("imgur.enabled", channel=channel):
return self.handler_default(url, channel)
client_id = self.registryValue("imgur.clientID")
if not client_id:
log.error("SpiffyTitles: imgur client ID not set")
return self.handler_default(url, channel)
if info.path.startswith("/a/"): if info.path.startswith("/a/"):
album_id = info.path.split("/a/")[1] album_id = info.path.split("/a/")[1]
elif info.path.startswith("/gallery/"): elif info.path.startswith("/gallery/"):
@ -1583,29 +1544,26 @@ class SpiffyTitles(callbacks.Plugin):
""" If there is a query string appended, remove it """ """ If there is a query string appended, remove it """
if "?" in album_id: if "?" in album_id:
album_id = album_id.split("?")[0] album_id = album_id.split("?")[0]
client_id = self.registryValue("imgur.clientID") if not self.is_valid_imgur_id(album_id):
if client_id and self.is_valid_imgur_id(album_id): log.error("SpiffyTitles: Invalid imgur ID")
return self.handler_default(url, channel)
log.debug("SpiffyTitles: found imgur album id %s" % (album_id)) log.debug("SpiffyTitles: found imgur album id %s" % (album_id))
try:
headers = {"Authorization": "Client-ID {0}".format(client_id)} headers = {"Authorization": "Client-ID {0}".format(client_id)}
api_url = "https://api.imgur.com/3/album/{0}".format(album_id) api_url = "https://api.imgur.com/3/album/{0}".format(album_id)
request = requests.get(
api_url, headers=headers, timeout=self.timeout
)
request.raise_for_status()
ok = request.status_code == requests.codes.ok
album = None
if ok:
try: try:
request = requests.get(api_url, headers=headers, timeout=self.timeout)
request.raise_for_status()
except (
requests.exceptions.RequestException,
requests.exceptions.HTTPError,
) as e:
log.error("SpiffyTitles: Imgur Error: {0}".format(e))
return self.handler_default(url, channel)
album = None
album = json.loads(request.content.decode()) album = json.loads(request.content.decode())
album = album.get("data") album = album.get("data")
except:
log.error("SpiffyTitles: Error reading imgur JSON response")
album = None
if album: if album:
album_template = self.registryValue( album_template = self.registryValue("imgur.albumTemplate", channel=channel)
"imgur.albumTemplate", channel=channel
)
imgur_album_template = Template(album_template) imgur_album_template = Template(album_template)
compiled_template = imgur_album_template.render( compiled_template = imgur_album_template.render(
{ {
@ -1618,17 +1576,7 @@ class SpiffyTitles(callbacks.Plugin):
) )
return compiled_template return compiled_template
else: else:
log.error( log.error("SpiffyTitles: imgur album API returned unexpected results!")
"SpiffyTitles: imgur album API returned unexpected results!"
)
except (
requests.exceptions.RequestException,
requests.exceptions.HTTPError,
) as e:
log.error("SpiffyTitles: imgur error: %s" % (e))
else:
log.debug("SpiffyTitles: unable to determine album id for %s" % (url))
else:
return self.handler_default(url, channel) return self.handler_default(url, channel)
def handler_imgur_image(self, url, info, channel): def handler_imgur_image(self, url, info, channel):
@ -1637,8 +1585,13 @@ class SpiffyTitles(callbacks.Plugin):
Used for both direct images and imgur.com/some_image_id_here type links, as Used for both direct images and imgur.com/some_image_id_here type links, as
they're both single images. they're both single images.
""" """
if not self.registryValue("imgur.enabled", channel=channel):
return self.handler_default(url, channel)
client_id = self.registryValue("imgur.clientID")
if not client_id:
log.error("SpiffyTitles: imgur client ID not set")
return self.handler_default(url, channel)
title = None title = None
if self.registryValue("imgur.enabled", channel=channel):
""" """
If there is a period in the path, it's a direct link to an image. If there is a period in the path, it's a direct link to an image.
If not, then it's an imgur.com/some_image_id_here type link If not, then it's an imgur.com/some_image_id_here type link
@ -1648,19 +1601,22 @@ class SpiffyTitles(callbacks.Plugin):
image_id = path.split(".")[0] image_id = path.split(".")[0]
else: else:
image_id = info.path.lstrip("/") image_id = info.path.lstrip("/")
client_id = self.registryValue("imgur.clientID") if not self.is_valid_imgur_id(image_id):
if client_id and self.is_valid_imgur_id(image_id): log.error("SpiffyTitles: Invalid imgur image ID")
return self.handler_default(url, channel)
log.debug("SpiffyTitles: found image id %s" % (image_id)) log.debug("SpiffyTitles: found image id %s" % (image_id))
try:
headers = {"Authorization": "Client-ID {0}".format(client_id)} headers = {"Authorization": "Client-ID {0}".format(client_id)}
api_url = "https://api.imgur.com/3/image/{0}".format(image_id) api_url = "https://api.imgur.com/3/image/{0}".format(image_id)
request = requests.get( try:
api_url, headers=headers, timeout=self.timeout request = requests.get(api_url, headers=headers, timeout=self.timeout)
)
request.raise_for_status() request.raise_for_status()
ok = request.status_code == requests.codes.ok except (
requests.exceptions.RequestException,
requests.exceptions.HTTPError,
) as e:
log.error("SpiffyTitles: Imgur Error: {0}".format(e))
return self.handler_default(url, channel)
image = None image = None
if ok:
try: try:
image = json.loads(request.content.decode()) image = json.loads(request.content.decode())
image = image.get("data") image = image.get("data")
@ -1687,16 +1643,7 @@ class SpiffyTitles(callbacks.Plugin):
) )
title = compiled_template title = compiled_template
else: else:
log.error( log.error("SpiffyTitles: imgur API returned unexpected results!")
"SpiffyTitles: imgur API returned unexpected results!"
)
except (
requests.exceptions.RequestException,
requests.exceptions.HTTPError,
) as e:
log.error("SpiffyTitles: imgur error: %s" % (e))
else:
log.error("SpiffyTitles: error retrieving image id for %s" % (url))
if title: if title:
return title return title
else: else: