This repository has been archived by the owner on Mar 31, 2023. It is now read-only.
/
ippush.py
163 lines (133 loc) · 4.65 KB
/
ippush.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#!/usr/bin/env python3
"""ippush.py
Sends a machine's IP address using the Pushover API.
"""
import os
import json
import time
import logging.config
import logging
import urllib.request
from py_pushover_simple import pushover
import conf.logger_config as lc
if not os.path.isdir('log'):
os.mkdir('log')
logging.config.dictConfig(lc.LOGGER_CONFIG)
logger = logging.getLogger(__name__)
logger.debug('Logger initialized.')
def read_settings(settings_file):
"""Read settings"""
with open(settings_file) as sf:
s = json.load(sf)
return s
class IPPush:
"""Get a machine's IP address and send a push if it has changed."""
def __init__(self, settings):
self.__location__ = os.path.realpath(os.path.join(
os.getcwd(), os.path.dirname(__file__)
))
self.ipv4 = None
self.old_ip = None
self.ipv6 = None
self.old_ipv6 = None
self.settings = settings
self.wtfismy_ipv4 = 'https://ipv4.wtfismyip.com/text'
self.wtfismy_ipv6 = 'https://ipv6.wtfismyip.com/text'
def get_current_ip(self):
"""Gets the machine's current IP address using
https://wtfismyip.com
Note: https://wtfismyip.com doesn't care if you automate
requests to their service if it is for non-commercial use as
long as you rate-limit to at most one request/min/ip address.
Failure to comply may result in blockage.
"""
try:
with urllib.request.urlopen(self.wtfismy_ipv4) as r:
if r.code == 200:
logger.info('IPv4 capabilities are True')
self.ipv4 = r.read().decode('utf-8').rstrip('\r\n')
except urllib.error.HTTPError as e:
logger.error(e)
ipv6 = False
try:
with urllib.request.urlopen(self.wtfismy_ipv6) as r:
if r.code == 200:
ipv6 = True
logger.info('IPv6 capabilities are True')
self.ipv6 = r.read().decode('utf-8').rstrip('\r\n')
except urllib.error.HTTPError as e:
logger.error(e)
except urllib.error.URLError:
logger.info('IPv6 capabilities are False')
logger.debug('IPv6 Status: %s', bool(ipv6))
return self
def get_old_ip(self):
"""Gets the old IP address from the ip.old file."""
try:
with open(os.path.join(self.__location__, 'ip.old')) as f:
self.old_ip = f.readline().rstrip('\r\n')
except FileNotFoundError:
self.old_ip = '0.0.0.0'
try:
with open(os.path.join(self.__location__, 'ipv6.old')) as f:
self.old_ipv6 = f.readline().rstrip('\r\n')
except FileNotFoundError:
self.old_ipv6 = '::'
return self
def send_push(self):
"""Sets up the message to send to the Pushover API"""
sloc = self.settings['server_location']
ip = self.ipv4
ipv6 = self.ipv6
t = time.strftime('%c\n')
message = '''{}
IPv4:
New external IP for {} is
{}
Old IP was:
{}
IPv6:
New external IPv6 address is:
{}
Old IPv6 address was:
{}
'''.format(t, sloc, ip, self.old_ip, ipv6, self.old_ipv6)
self.send_message(message)
logger.info('Push sent.')
def write_new_ip(self):
"""Writes the machine's new IP address to the ip.old file."""
output = self.ipv4 + '\n'
with open(os.path.join(self.__location__, 'ip.old'), 'w') as f:
f.write(output)
logger.info('New IP Written.')
output2 = '{}\n'.format(self.ipv6)
with open(os.path.join(self.__location__, 'ipv6.old'), 'w') as f:
f.write(output2)
def update(self):
"""Update runs the class methods."""
self.get_old_ip()
self.get_current_ip()
if self.ipv4 != self.old_ip: # or (self.ipv6 != self.old_ipv6):
try:
self.send_push()
except pushover.PushoverError as e:
logger.error(
'Unable to send push. Exception:\n\n%s\n', e
)
self.write_new_ip()
else:
logger.info('IP did not change.')
def send_message(self, message):
"""Sends a push using py_pushover_simple"""
p = pushover.Pushover()
p.user = self.settings['keys']['user_key']
p.token = self.settings['keys']['app_token']
try:
p.target = self.settings['device']
except KeyError:
pass
p.send_message(message)
if __name__ == '__main__':
config = read_settings('settings.json')
SECRETS = config['keys']
IPPush(config).update()