mirror of
https://github.com/oddluck/limnoria-plugins.git
synced 2025-04-29 06:51:12 -05:00
Corona/SpiffyTitles: cleanup, formatting
This commit is contained in:
parent
87fdaca856
commit
7cad84a682
312
Corona/codes.py
Normal file
312
Corona/codes.py
Normal 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",
|
||||||
|
}
|
328
Corona/plugin.py
328
Corona/plugin.py
@ -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:
|
||||||
|
@ -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."""),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -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:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user