From 485e81db79eff99e0db2da0244c6ba01e46ac53a Mon Sep 17 00:00:00 2001 From: Adam Cooper Date: Tue, 24 Oct 2017 08:34:06 +0100 Subject: [PATCH] whois domain lookup sensor (#10000) * Init commit of new whois sensor * Updated requirements * Resolved updated showing expired, added expired attr * Added missing attribute in init, added whois to coveragerc * Various PR comment changes - Now more resiliant to invalid hostnames - Removed various assumed STATE_UNKOWN setting - Upfront check for valid hostname preventing the sensor starting with dud - Resolved unit of measurement Day, Days, None issue - Datetime formatting now done to iso 8601 standard - Removed all expired usage, not really that useful - Unused hass assignment * More PR comment resolutions - Resolved the dilemma with hosts / single host per sensor. Now running single domain per sensor. - Renamed host(s) to domain * Moved coveragerc sensor location * Re-phrased the expiration_date warning * Resolved assumed updated_date existence * Resolved missing indent * Resolved discover_info typo * Update whois.py --- .coveragerc | 1 + homeassistant/components/sensor/whois.py | 136 +++++++++++++++++++++++ requirements_all.txt | 3 + requirements_test_all.txt | 3 + script/gen_requirements_all.py | 1 + 5 files changed, 144 insertions(+) create mode 100644 homeassistant/components/sensor/whois.py diff --git a/.coveragerc b/.coveragerc index ddbd4a1e0b1..3eb2087a232 100644 --- a/.coveragerc +++ b/.coveragerc @@ -568,6 +568,7 @@ omit = homeassistant/components/sensor/ups.py homeassistant/components/sensor/vasttrafik.py homeassistant/components/sensor/waqi.py + homeassistant/components/sensor/whois.py homeassistant/components/sensor/worldtidesinfo.py homeassistant/components/sensor/worxlandroid.py homeassistant/components/sensor/xbox_live.py diff --git a/homeassistant/components/sensor/whois.py b/homeassistant/components/sensor/whois.py new file mode 100644 index 00000000000..9f50a4c13db --- /dev/null +++ b/homeassistant/components/sensor/whois.py @@ -0,0 +1,136 @@ +""" +Get WHOIS information for a given host. + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/sensor.whois/ +""" +import logging +from datetime import timedelta + +import voluptuous as vol + +from homeassistant.const import CONF_NAME +from homeassistant.components.sensor import PLATFORM_SCHEMA +import homeassistant.helpers.config_validation as cv +from homeassistant.helpers.entity import Entity + +REQUIREMENTS = ['pythonwhois==2.4.3'] + +_LOGGER = logging.getLogger(__name__) + +CONF_DOMAIN = 'domain' + +DEFAULT_NAME = 'Whois' + +ATTR_NAME_SERVERS = 'name_servers' +ATTR_REGISTRAR = 'registrar' +ATTR_UPDATED = 'updated' +ATTR_EXPIRES = 'expires' + +SCAN_INTERVAL = timedelta(hours=24) + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Required(CONF_DOMAIN): cv.string, + vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string +}) + + +def setup_platform(hass, config, add_devices, discovery_info=None): + """Set up the WHOIS sensor.""" + from pythonwhois import get_whois + from pythonwhois.shared import WhoisException + + domain = config.get(CONF_DOMAIN) + name = config.get(CONF_NAME) + + try: + if 'expiration_date' in get_whois(domain, normalized=True): + add_devices([WhoisSensor(name, domain)], True) + else: + _LOGGER.warning( + "WHOIS lookup for %s didn't contain expiration_date", + domain) + return + except WhoisException as ex: + _LOGGER.error("Exception %s occurred during WHOIS lookup for %s", + ex, + domain) + return + + +class WhoisSensor(Entity): + """Implementation of a WHOIS sensor.""" + + def __init__(self, name, domain): + """Initialize the sensor.""" + from pythonwhois import get_whois + + self.whois = get_whois + + self._name = name + self._domain = domain + + self._state = None + self._data = None + self._updated_date = None + self._expiration_date = None + self._name_servers = [] + + @property + def name(self): + """Return the name of the sensor.""" + return self._name + + @property + def icon(self): + """The icon to represent this sensor.""" + return 'mdi:calendar-clock' + + @property + def unit_of_measurement(self): + """The unit of measurement to present the value in.""" + return 'days' + + @property + def state(self): + """Return the expiration days for hostname.""" + return self._state + + @property + def device_state_attributes(self): + """Get the more info attributes.""" + if self._data: + updated_formatted = self._updated_date.isoformat() + expires_formatted = self._expiration_date.isoformat() + + return { + ATTR_NAME_SERVERS: ' '.join(self._name_servers), + ATTR_REGISTRAR: self._data['registrar'][0], + ATTR_UPDATED: updated_formatted, + ATTR_EXPIRES: expires_formatted, + } + + def update(self): + """Get the current WHOIS data for hostname.""" + from pythonwhois.shared import WhoisException + + try: + response = self.whois(self._domain, normalized=True) + except WhoisException as ex: + _LOGGER.error("Exception %s occurred during WHOIS lookup", ex) + return + + if response: + self._data = response + + if self._data['nameservers']: + self._name_servers = self._data['nameservers'] + + if 'expiration_date' in self._data: + self._expiration_date = self._data['expiration_date'][0] + if 'updated_date' in self._data: + self._updated_date = self._data['updated_date'][0] + + time_delta = (self._expiration_date - self._expiration_date.now()) + + self._state = time_delta.days diff --git a/requirements_all.txt b/requirements_all.txt index 5a49ac5ef89..7c36120416a 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -851,6 +851,9 @@ python_openzwave==0.4.0.35 # homeassistant.components.alarm_control_panel.egardia pythonegardia==1.0.22 +# homeassistant.components.sensor.whois +pythonwhois==2.4.3 + # homeassistant.components.device_tracker.trackr pytrackr==0.0.5 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 88034f90283..b6a378b3d78 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -117,6 +117,9 @@ pynx584==0.4 # homeassistant.components.sensor.darksky python-forecastio==1.3.5 +# homeassistant.components.sensor.whois +pythonwhois==2.4.3 + # homeassistant.components.device_tracker.unifi pyunifi==2.13 diff --git a/script/gen_requirements_all.py b/script/gen_requirements_all.py index ddac210bc26..fa2cedda8ab 100755 --- a/script/gen_requirements_all.py +++ b/script/gen_requirements_all.py @@ -78,6 +78,7 @@ TEST_REQUIREMENTS = ( 'uvcclient', 'warrant', 'yahoo-finance', + 'pythonwhois' ) IGNORE_PACKAGES = (