Skip to content

Instantly share code, notes, and snippets.

@guim1111
Last active December 18, 2019 10:29
Show Gist options
  • Save guim1111/a99d6d3f43d06c706a9f718bebe5aacc to your computer and use it in GitHub Desktop.
Save guim1111/a99d6d3f43d06c706a9f718bebe5aacc to your computer and use it in GitHub Desktop.
For home, it can be usefull to get your external ip to get your services from internet to your home network, evrey time ip change, will send a email to previous configuration
#Auth
#python3.4 or newer
#use "screen python3 registerIp.py" for better experience then ctrl+a+d and 'screen -r' (see more screen linux command on google)
#to stop ctrl + c
#interesting url to develope this
#help from https://medium.com/greedygame-engineering/an-elegant-way-to-run-periodic-tasks-in-python-61b7c477b679 (but in python 2)
#if you want to mount your own server https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-postfix-as-a-send-only-smtp-server-on-ubuntu-16-04
#https://www.freecodecamp.org/news/send-emails-using-code-4fcea9df63f/
#
#This script is designed for who wants the external ip and send it with email. For who want to have services at home
#or anywhere with dynamic external ip without paying for dynamic dns
#Need a external URL that return only your ip
#Tested with python 3.7 in ubuntu 18.04 using outlook account aka @hotmail.com
#
import urllib.request, threading, getpass, time, signal, datetime, smtplib
from datetime import timedelta
from string import Template
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
__author__ = "guim1111"
#URL which will tell you only the ip
URL_GETIP = "https://ident.me"
#Time that wait to get again the ip from url in seconds
WAIT_TIME_SECONDS = 5
#do not touch
LAST_IP = "0"
#Edit this if you want to hardcode this (password not recommended)
MY_ADDRESS = ""
TO_ADDRESS = ""
MY_PASSWORD = ""
#Edit this for smtp that you want, but recommended this default, (only ports that accept ssl)
SMTP_HOST = "smtp-mail.outlook.com" #default for outlook account, gmail need more steps to be used with smtplib
SMTP_PORT = "587" #try 25 if doesn't work, ssl smpt port recommended
class ProgramKilled(Exception):
pass
def getIp():
global LAST_IP
ip = urllib.request.urlopen(URL_GETIP).read().decode('utf8')
now=datetime.datetime.now()
if LAST_IP != ip:
sendMail(ip)
LAST_IP = ip
file.write("{} -- {}\n".format(ip, now))
print(f"{ip} detectada! -- {now}")
def signalHandler(signum, frame):
raise ProgramKilled
def sendMail(ip):
s = smtplib.SMTP(host=SMTP_HOST, port=SMTP_PORT)
s.starttls()
s.login(MY_ADDRESS, MY_PASSWORD)
msg = MIMEMultipart()
msg["From"]=MY_ADDRESS
msg["To"]=TO_ADDRESS
msg["Subject"]=f"Your ip now is: {ip}"
msg.attach(MIMEText(f"Your ip was {LAST_IP}, now it's {ip}", "plain"))
s.send_message(msg)
del msg
s.quit()
class Job(threading.Thread):
def __init__(self, interval, execute, *args, **kwargs):
threading.Thread.__init__(self)
self.daemon = False
self.stopped = threading.Event()
self.interval = interval
self.execute = execute
self.args = args
self.kwargs = kwargs
def stop(self):
self.stopped.set()
self.join()
def run(self):
while not self.stopped.wait(self.interval.total_seconds()):
self.execute(*self.args, **self.kwargs)
def checkSMTPCredentials():
global MY_ADDRESS
global TO_ADDRESS
global MY_PASSWORD
if MY_ADDRESS == "":
MY_ADDRESS = input("Set a mail from where this script will work: ")
TO_ADDRESS = input("Set a mail which will receive the mails (blank = previous email): ") or MY_ADDRESS
else:
print("There is a mail hardcoded, be sure you put it correct and the mail who will receive")
if MY_PASSWORD == "":
MY_PASSWORD = getpass.getpass("Set a password of first mail account (this will not be stored in any file): ")
else:
print("There is a password hardcoded (BE SURE THAT THIS IS WHAT YOU WANT, it's unsecure to put a credentials in any file)")
if input("Write 'ok' to continue with this") != "ok":
exit(1)
print(f"Checking credentials for {SMTP_HOST}")
s = smtplib.SMTP(host=SMTP_HOST, port=SMTP_PORT)
s.starttls()
try:
s.login(MY_ADDRESS, MY_PASSWORD)
except smtplib.SMTPAuthenticationError:
print ("Incorrect username/password for this SMTP!")
s.quit()
exit(1)
s.quit()
print("Credentials are correct!")
def checkIp():
response = urllib.request.urlopen(URL_GETIP)
ip = response.read().decode('utf8')
code = response.getcode()
if code != 200:
print("Something is wrong, the code of conectio is not 200")
exit(2)
print(f"Statuss 200, your ip is {ip} get from {URL_GETIP}")
def main():
file=open("myip.log", "w+")
signal.signal(signal.SIGTERM, signalHandler)
signal.signal(signal.SIGINT, signalHandler)
job = Job(interval=timedelta(seconds=WAIT_TIME_SECONDS), execute=getIp)
job.start()
while True:
try:
time.sleep(1)
except ProgramKilled:
print ("Program killed, bye!")
job.stop()
file.close()
break
if __name__ == "__main__":
#Coment checkSMTPCredentials if you want to automate all without user input with hardcoded credentials (not secure)
#Coment checkIp if you don't want to check if web that tell your ip is up or you have internet connectivity
checkSMTPCredentials()
checkIp()
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment