Skip to content
This repository was archived by the owner on Aug 27, 2022. It is now read-only.

Commit bc99a2a

Browse files
committed
Move
1 parent 6b9257e commit bc99a2a

File tree

3 files changed

+146
-166
lines changed

3 files changed

+146
-166
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
11
"""The authenticated component."""
2+
3+
4+
class AuthenticatedBaseException(Exception):
5+
"""Base exception for Authenticated."""
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
"""Providers"""
2+
import logging
3+
import requests
4+
from . import AuthenticatedBaseException
5+
6+
_LOGGER = logging.getLogger(__name__)
7+
8+
PROVIDERS = {}
9+
10+
11+
def register_provider(classname):
12+
"""Decorator used to register providers."""
13+
PROVIDERS[classname.name] = classname
14+
return classname
15+
16+
17+
class GeoProvider:
18+
"""GeoProvider class."""
19+
20+
url = None
21+
22+
def __init__(self, ipaddr):
23+
"""Initialize."""
24+
self.result = {}
25+
self.ipaddr = ipaddr
26+
27+
@property
28+
def country(self):
29+
"""Return country name or None."""
30+
return self.result.get("country")
31+
32+
@property
33+
def region(self):
34+
"""Return region name or None."""
35+
return self.result.get("region")
36+
37+
@property
38+
def city(self):
39+
"""Return city name or None."""
40+
return self.result.get("city")
41+
42+
@property
43+
def computed_result(self):
44+
"""Return the computed result."""
45+
if self.result is not None:
46+
return {"country": self.country, "region": self.region, "city": self.city}
47+
return None
48+
49+
def update_geo_info(self):
50+
"""Update Geo Information."""
51+
self.result = {}
52+
try:
53+
api = self.url.format(self.ipaddr)
54+
header = {"user-agent": "Home Assistant/Python"}
55+
data = requests.get(api, headers=header, timeout=5).json()
56+
57+
if data.get("error"):
58+
if data.get("reason") == "RateLimited":
59+
raise AuthenticatedBaseException(
60+
"RatelimitError, try a different provider."
61+
)
62+
63+
elif data.get("status", "success") == "error":
64+
return
65+
66+
elif data.get("reserved"):
67+
return
68+
69+
elif data.get("status", "success") == "fail":
70+
raise AuthenticatedBaseException(
71+
"[{}] - {}".format(
72+
self.ipaddr, data.get("message", "Unknown error.")
73+
)
74+
)
75+
76+
self.result = data
77+
self.parse_data()
78+
except AuthenticatedBaseException as exception:
79+
_LOGGER.error(exception)
80+
except requests.exceptions.ConnectionError:
81+
pass
82+
83+
def parse_data(self):
84+
"""Parse data from geoprovider."""
85+
self.result = self.result
86+
87+
88+
@register_provider
89+
class IPApi(GeoProvider):
90+
"""IPApi class."""
91+
92+
url = "https://ipapi.co/{}/json"
93+
name = "ipapi"
94+
95+
@property
96+
def country(self):
97+
"""Return country name or None."""
98+
return self.result.get("country_name")
99+
100+
101+
@register_provider
102+
class ExtremeIPLookup(GeoProvider):
103+
"""IPApi class."""
104+
105+
url = "https://extreme-ip-lookup.com/json/{}"
106+
name = "extreme"
107+
108+
109+
@register_provider
110+
class IPVigilante(GeoProvider):
111+
"""IPVigilante class."""
112+
113+
url = "https://ipvigilante.com/json/{}"
114+
name = "ipvigilante"
115+
116+
def parse_data(self):
117+
"""Parse data from geoprovider."""
118+
self.result = self.result.get("data", {})
119+
120+
@property
121+
def country(self):
122+
"""Return country name or None."""
123+
return self.result.get("country_name")
124+
125+
@property
126+
def region(self):
127+
"""Return region name or None."""
128+
return self.result.get("subdivision_1_name")
129+
130+
@property
131+
def city(self):
132+
"""Return city name or None."""
133+
return self.result.get("city_name")

custom_components/authenticated/sensor.py

Lines changed: 9 additions & 166 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,15 @@
1010
import os
1111
from ipaddress import ip_address as ValidateIP, ip_network
1212
import socket
13-
import requests
1413
import voluptuous as vol
1514
import yaml
1615

1716
import homeassistant.helpers.config_validation as cv
1817
from homeassistant.components.sensor import PLATFORM_SCHEMA
1918
from homeassistant.helpers.entity import Entity
2019

20+
from .providers import PROVIDERS
21+
2122
_LOGGER = logging.getLogger(__name__)
2223

2324
CONF_NOTIFY = "enable_notification"
@@ -41,24 +42,21 @@
4142
LOGFILE = "home-assistant.log"
4243
OUTFILE = ".ip_authenticated.yaml"
4344

44-
PROVIDERS = ["ipapi", "extreme", "ipvigilante"]
45-
4645
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
4746
{
48-
vol.Optional(CONF_PROVIDER, default="ipapi"): vol.In(PROVIDERS),
47+
vol.Optional(CONF_PROVIDER, default="ipapi"): vol.In(
48+
["ipapi", "extreme", "ipvigilante"]
49+
),
4950
vol.Optional(CONF_LOG_LOCATION, default=""): cv.string,
5051
vol.Optional(CONF_NOTIFY, default=True): cv.boolean,
5152
vol.Optional(CONF_EXCLUDE, default=[]): vol.All(cv.ensure_list, [cv.string]),
5253
}
5354
)
5455

55-
PROVIDERS = {}
5656

57-
58-
def register_provider(classname):
59-
"""Decorator used to register providers."""
60-
PROVIDERS[classname.name] = classname
61-
return classname
57+
def humanize_time(timestring):
58+
"""Convert time."""
59+
return datetime.strptime(timestring[:19], "%Y-%m-%dT%H:%M:%S")
6260

6361

6462
def setup_platform(hass, config, add_devices, discovery_info=None):
@@ -78,14 +76,6 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
7876
add_devices([sensor], True)
7977

8078

81-
class AuthenticatedBaseException(Exception):
82-
"""Base exception for Authenticated."""
83-
84-
85-
class AuthenticatedRateLimitException(AuthenticatedBaseException):
86-
"""Ratelimit exception."""
87-
88-
8979
class AuthenticatedSensor(Entity):
9080
"""Representation of a Sensor."""
9181

@@ -325,7 +315,7 @@ def load_authentications(authfile, exclude):
325315
if ValidateIP(token["last_used_ip"]) in ip_network(
326316
excludeaddress, False
327317
):
328-
raise Exception('IP in excluded address configuration')
318+
raise Exception("IP in excluded address configuration")
329319
if token.get("last_used_at") is None:
330320
continue
331321
if token["last_used_ip"] in tokens_cleaned:
@@ -433,150 +423,3 @@ def notify(self, hass):
433423
last_used_at.replace("T", " "),
434424
)
435425
notify(message, title="New successful login", notification_id=self.ip_address)
436-
437-
438-
class GeoProvider:
439-
"""GeoProvider class."""
440-
441-
url = None
442-
443-
def __init__(self, ipaddr):
444-
"""Initialize."""
445-
self.result = {}
446-
self.ipaddr = ipaddr
447-
448-
@property
449-
def country(self):
450-
"""Return country name or None."""
451-
if self.result:
452-
if self.result.get("country") is not None:
453-
return self.result["country"]
454-
return None
455-
456-
@property
457-
def region(self):
458-
"""Return region name or None."""
459-
if self.result:
460-
if self.result.get("region") is not None:
461-
return self.result["region"]
462-
return None
463-
464-
@property
465-
def city(self):
466-
"""Return city name or None."""
467-
if self.result:
468-
if self.result.get("city") is not None:
469-
return self.result["city"]
470-
return None
471-
472-
@property
473-
def computed_result(self):
474-
"""Return the computed result."""
475-
if self.result is not None:
476-
return {"country": self.country, "region": self.region, "city": self.city}
477-
return None
478-
479-
def update_geo_info(self):
480-
"""Update Geo Information."""
481-
self.result = {}
482-
try:
483-
api = self.url.format(self.ipaddr)
484-
header = {"user-agent": "Home Assistant/Python"}
485-
data = requests.get(api, headers=header, timeout=5).json()
486-
487-
if data.get("error"):
488-
if data.get("reason") == "RateLimited":
489-
raise AuthenticatedRateLimitException(
490-
"RatelimitError, try a different provider."
491-
)
492-
493-
elif data.get("status", "success") == "error":
494-
return
495-
496-
elif data.get("reserved"):
497-
return
498-
499-
elif data.get("status", "success") == "fail":
500-
raise AuthenticatedBaseException(
501-
"[{}] - {}".format(
502-
self.ipaddr, data.get("message", "Unknown error.")
503-
)
504-
)
505-
506-
self.result = data
507-
self.parse_data()
508-
except AuthenticatedRateLimitException as exception:
509-
_LOGGER.error(exception)
510-
except AuthenticatedBaseException as exception:
511-
_LOGGER.error(exception)
512-
except requests.exceptions.ConnectionError:
513-
pass
514-
515-
def parse_data(self):
516-
"""Parse data from geoprovider."""
517-
self.result = self.result
518-
519-
520-
@register_provider
521-
class IPApi(GeoProvider):
522-
"""IPApi class."""
523-
524-
url = "https://ipapi.co/{}/json"
525-
name = "ipapi"
526-
527-
@property
528-
def country(self):
529-
"""Return country name or None."""
530-
if self.result:
531-
if self.result.get("country_name") is not None:
532-
return self.result["country_name"]
533-
return None
534-
535-
536-
@register_provider
537-
class ExtremeIPLookup(GeoProvider):
538-
"""IPApi class."""
539-
540-
url = "https://extreme-ip-lookup.com/json/{}"
541-
name = "extreme"
542-
543-
544-
@register_provider
545-
class IPVigilante(GeoProvider):
546-
"""IPVigilante class."""
547-
548-
url = "https://ipvigilante.com/json/{}"
549-
name = "ipvigilante"
550-
551-
def parse_data(self):
552-
"""Parse data from geoprovider."""
553-
self.result = self.result.get("data", {})
554-
555-
@property
556-
def country(self):
557-
"""Return country name or None."""
558-
if self.result:
559-
if self.result.get("country_name") is not None:
560-
return self.result["country_name"]
561-
return None
562-
563-
@property
564-
def region(self):
565-
"""Return region name or None."""
566-
if self.result:
567-
if self.result.get("subdivision_1_name") is not None:
568-
return self.result["subdivision_1_name"]
569-
return None
570-
571-
@property
572-
def city(self):
573-
"""Return city name or None."""
574-
if self.result:
575-
if self.result.get("city_name") is not None:
576-
return self.result["city_name"]
577-
return None
578-
579-
580-
def humanize_time(timestring):
581-
"""Convert time."""
582-
return datetime.strptime(timestring[:19], "%Y-%m-%dT%H:%M:%S")

0 commit comments

Comments
 (0)