コード例 #1
0
ファイル: tickers.py プロジェクト: bryanchambers/parsec
def send_results(total, matches, new, changes):
    subject = 'Parsec Tickers Updated'
    percent = round((matches / float(total)) * 100, 1)

    msg = str(new) + ' New, ' + str(changes) + ' Changes, ' + str(
        matches) + '/' + str(total) + ' Matched (' + str(percent) + '%)'
    email('*****@*****.**', subject, msg)
コード例 #2
0
ファイル: parsec.py プロジェクト: bryanchambers/parsec
def send_results(year, qtr, s, f, reports):
    subject = 'Parsec Reports Updated'

    msg = str(year) + ' Q' + str(qtr) + ': '
    msg = msg + str(s) + ' Successful, ' + str(f) + ' Failed'
    msg = msg + ', Reports: ' + ', '.join(reports)
    email('*****@*****.**', subject, msg)
コード例 #3
0
ファイル: pe.py プロジェクト: bryanchambers/parsec
def get_pe_ratios():
    pe = {}

    for batch in get_ticker_batches():
        pe = {**pe, **get_pe_batch(batch)}

    with open('info/companies.json', 'r') as file:
        companies = json.load(file)
        file.close()

    n = 0
    for cik in companies:
        if 'ticker' in companies[cik]:

            ticker = companies[cik]['ticker']
            if ticker in pe:
                companies[cik]['pe'] = pe[ticker]
                n = n + 1

    with open('info/companies.json', 'w') as file:
        json.dump(companies, file)
        file.close()

    subject = 'Parsec PE Updated'
    message = str(n) + ' Updated'
    email('*****@*****.**', subject, message)
コード例 #4
0
ファイル: main.py プロジェクト: fitzthum/home
    def leaveApt(self, loc):
        if loc == "train":
            # commuting to work

            # let's look at soem events
            # TODO: some way to increase priority of events from phone
            notify.email("Upcoming Events", calendar.getAllEventsTxt())
            pass
        else:
            # took a later train?
            # working from home?
            pass
コード例 #5
0
	def processState(self):
		state = self.Vars['state']
		if state != self.MergedRequest['state']:
			date = time.strftime("%Y-%m-%d", time.localtime())
			result = self.db.Command('''UPDATE ReleaseAutomation.merged SET state="%s", action_date="%s" WHERE id=%d'''%(state, date, int(self.MergedRequest['id'])))
			if type(result) == ErrType:
				return result

			if state == 'live' and self.MergedRequest['severity'] == 'async':
				result = self.db.Command('''UPDATE ReleaseAutomation.release_cycle SET processed="Y" WHERE id=%d'''%(int(self.MergedRequest['release_cycle_id'])))
				if type(result) == ErrType:
					return result


			#NOTIFY each bug
			result = self.db.Command('''SELECT * FROM ReleaseAutomation.combined WHERE merged_id=%d'''%(int(self.MergedRequest['id'])))
			if type(result) == ErrType:
				return result
			combined_list = result
			for combined in combined_list:
				subject = '''[Bug %d] Release Request has been updated'''%(int(combined['bug_id']))
				msg = '''%s (%s) has changed the state of this request to %s'''%(self.UserProfile['realname'], self.UserProfile['login_name'], state.upper())
			
				email = notify.email()
				result = email.send([], subject, msg)
				if type(result) == ErrType:
					return result
			#done
			return True
		#else

		return False
コード例 #6
0
def hermes_scraper():
    wanted_bags = config.load()
    print(wanted_bags['categories'])

    URL = config.get_url()
    page = requests.get(URL, headers={'Cache-Control': 'no-cache'})
    print(f'Status code: {page.status_code}')
    soup = BeautifulSoup(page.content, 'html.parser')
    bags_on_site = soup.find_all(class_='product-item-name')
    available_bags = []

    print(f'Number of bags: {len(bags_on_site)}')
    for bag_on_site_html in bags_on_site:
        bag_on_site = bag_on_site_html.text.strip()
        print("Bag on site: " + bag_on_site)

        for wanted_bag in wanted_bags['categories']:
            if wanted_bag in bag_on_site:
                available_bags.append(bag_on_site)

    previous_bags = db.get_bags()
    available_bags.sort()
    print(f'Previous bags: {previous_bags}')
    print(f'Wanted bags: {wanted_bags}')
    print(f'Available bags: {available_bags}')
    print(f'previous bags == current bags: {previous_bags == available_bags}')

    if (previous_bags != available_bags):
        print("Change in bags")
        notify.email(wanted_bags, available_bags)
        db.update_bags(available_bags)
    else:
        print("No change")

    return str(available_bags)

    if __name__ == "__main__":
        app.run(debug=True,
                host='0.0.0.0',
                port=int(os.environ.get('PORT', 8080)))
コード例 #7
0
	def process(self):
		if not self.Process:
			return False

		removed = {'combined': False, 'release': []}

		for request in self.ReleaseRequests:
			id = str(request['id'])
			if id in self.Vars and self.Vars[id] == "on":
				result = self.db.Command('''DELETE FROM ReleaseAutomation.release_request WHERE id=%d'''%(int(id)))
				if type(result) == ErrType:
					return result
				removed['release'].append(request)
			#else
		
		#Delete combined?
		result = self.db.Command('''SELECT * FROM ReleaseAutomation.release_request WHERE combined_id=%d'''%(int(self.CombinedRequest['id'])))
		if type(result) == ErrType:
			return result

		if len(result) < 1:
			result = self.db.Command('''DELETE FROM ReleaseAutomation.combined WHERE id=%d'''%(int(self.CombinedRequest['id'])))
			if type(result) == ErrType:
				return result
		#

		#DELETE Merged?
		result = self.db.Command('''SELECT * FROM ReleaseAutomation.combined WHERE merged_id=%d'''%(int(self.CombinedRequest['merged_id'])))
		if type(result) == ErrType:
			return result

		if len(result) < 1:
			result = self.db.Command('''DELETE FROM ReleaseAutomation.merged WHERE id=%d'''%(int(self.CombinedRequest['merged_id'])))
			if type(result) == ErrType:
				return result
			removed['combined'] = True
		#

		#Delete async request?
		if self.CombinedRequest['severity'] == "async":
			result = self.db.Command('''SELECT * FROM ReleaseAutomation.merged WHERE release_cycle_id=%d'''%(int(self.MergedRequest['release_cycle_id'])))
			if type(result) == ErrType:
				return result

			if len(result) < 1:
				result = self.db.Command('''SELECT async FROM ReleaseAutomation.release_cycle WHERE id=%d'''%(int(self.MergedRequest['release_cycle_id'])))
				if type(result) == ErrType:
					return result
				if len(result) > 0:
					if result[0]['async'] == "Y":
						result = self.db.Command('''DELETE FROM ReleaseAutomation.release_cycle WHERE id=%d'''%(int(self.MergedRequest['release_cycle_id'])))
						if type(result) == ErrType:
							return result
		#

		#NOTIFY
		subject = '''[Bug %d] Release Request has been edited.'''%(int(self.CombinedRequest['bug_id']))
		if removed['combined']:
			msg = '''%s (%s) has removed %s from the Release Request Queue\r\n'''%(self.UserProfile['realname'], self.UserProfile['login_name'], self.CombinedRequest['name'])
		
		elif removed['release']:
			msg = '''%s %s has removed the following portions of %s from the Release Request Queue:\r\n\r\n'''%(self.UserProfile['realname'], self.UserProfile['login_name'], self.CombinedRequest['name'])
			for request in removed['release']:
				msg += '''Name: %s, Type: %s, BuildID: %07d\r\n'''%(request['name'], request['type'], int(request['builds_id']))
			msg += "\r\n\r\n"
		
		else:
			return False

		email = notify.email()
		result = email.send([], subject, msg)
		if type(result) == ErrType:
			return result

		return True
コード例 #8
0
ファイル: warning.py プロジェクト: damiller/GRIFFIN-SOH
thisScript = os.path.abspath(__file__)

for arg in sys.argv:
  print arg
  if (arg=='nomail'):
    mail=0
    print "Mail will be suppressed \n"
  elif (arg=='debug'):
    debug = 1
    print "Debugging stuff will be printed \n"

# Prepare warning message

SUBJECT = "WARNING: Temperature is too HIGH"

BODY = """
The temperature in the electronics shack has reached a warning level.
Shutdown will occur when temperature becomes critical.
"""+thisScript+"\n"

# And now, notify by e-mail that there's a problem.

if (mail):
  notify.email(SUBJECT,BODY)

if debug:
  print "Mail to be sent SUBJECT:"+SUBJECT
  print BODY

コード例 #9
0
ファイル: recommend.py プロジェクト: bryanchambers/parsec
with open('info/companies.json', 'r') as file:
    companies = json.load(file)
    file.close()

with open('scores/value-scores.json', 'r') as file:
    scores = json.load(file)
    file.close()

results = []

for cik in scores:
    if cik in companies:
        result = companies[cik]
        result['cik'] = cik
        result['value'] = scores[cik]
        if 'pe' in result: result['pe_score'] = get_pe_score(result['pe'])

        result['overall'] = (result['value'] * 0.6) + (
            result['pe_score'] * 0.4) if 'pe_score' in result else 0
        if result['overall'] > 0: results.append(result)

results.sort(key=lambda x: x['overall'], reverse=True)

rows = []
for result in results:
    rows.append(format_result(result))

subject = 'Parsec Recommendations'
message = '\n\n'.join(rows)
email('*****@*****.**', subject, message)
コード例 #10
0
	def process(self):
		action = "Denied"
		if not self.Process:
			return False

		if not self.Vars['approval']:
			return False

		if self.Vars['approval'] == "approve":
			action = "Approved"
			date = time.strftime("%Y-%m-%d", time.localtime())
			result = self.db.Command('''UPDATE ReleaseAutomation.merged SET approver_id=%d, state="approved", action_date="%s" WHERE id=%d'''%(self.UserID, date, int(self.MergedRequest['id'])))
			if type(result) == ErrType:
				return result

			return True

		elif self.Vars['approval'] == "deny":
			if self.MergedRequest['severity'] == "async":
				result = getCurrentReleaseCycle(self.db)
				if type(result) == ErrType:
					return result
			
				cycle_id = result 
				old_cycle_id = int(self.MergedRequest['release_cycle_id'])
			
				#merged
				result = self.db.Command('''UPDATE ReleaseAutomation.merged SET state="approved", severity="critical", release_cycle_id=%d WHERE id=%d'''%(cycle_id, int(self.MergedRequest['id'])))
				if type(result) == ErrType:
					return result
	
				#combined
				result = self.db.Command('''UPDATE ReleaseAutomation.combined SET severity="critical" WHERE id=%d'''%(self.CombinedID))
				if type(result) == ErrType:
					return result


				#cleanup release_cycle
				result = self.db.Command('''SELECT * FROM ReleaseAutomation.merged WHERE release_cycle_id=%d'''%(old_cycle_id))
				if type(result) == ErrType:
					return result
				if len(result) < 1:
					result = self.db.Command('''DELETE FROM ReleaseAutomation.release_cycle WHERE id=%d AND async="Y"'''%(old_cycle_id))
					if type(result) == ErrType:
						return result
			
			#delete regular request
			else:
				result = self.db.Command('''SELECT * FROM ReleaseAutomation.combined WHERE merged_id=%d AND NOT id=%d'''%(int(self.MergedRequest['id']), int(self.CombinedRequest['id'])))
				if type(result) == ErrType:
					return result
				if not result:
					#there are no other combined, so we delete the merged, whihc takes care of everything
					result = self.Pyro.exec_task("rmMerged",method_args=(int(self.MergedRequest['id']),))
					if type(result) == ErrType:
						return result
				else:
					#Otherwise we delete from combined
					result = self.Pyro.exec_task("rmCombined",method_args=(int(self.CombinedRequest['id']),))
					if type(result) == ErrType:
						return result

			#NOTIFY
			subject = '''[Bug %d] Has been %s.'''%(int(self.CombinedRequest['bug_id']), action)
			msg = '''This request has been %s by:\r\n'''%(action)
			msg += '''%s (%s)\r\n'''%(self.UserProfile['realname'], self.UserProfile['login_name'])
			if action == "Denied" and self.MergedRequest['severity'] == "async":
				msg += '''\r\nThe request has been automatically moved into the current release cycle and its priority lowered to CRITICAL.\r\n'''
			msg += "\r\n"
			msg += self.Vars['notes']
			msg += "\r\n\r\n"
			email = notify.email()
			result = email.send([], subject, msg)
			if type(result) == ErrType:
				return result


			return True

		return False
コード例 #11
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("-i",
                        "--interest-check",
                        dest="ic",
                        action='store_true',
                        help="Enable Interest Checks")
    parser.add_argument("-g",
                        "--group-buy",
                        dest="gb",
                        action='store_true',
                        help="Enable Group Buys")
    parser.add_argument("-s",
                        "--sms",
                        dest="sms",
                        action='store_true',
                        help="Send via SMS")
    parser.add_argument("-e",
                        "--email",
                        dest="email",
                        action='store_true',
                        help="Send via Email")
    parser.add_argument("-ep", "--port", dest="port", help="Email Port")
    parser.add_argument("-ef",
                        "--email-from",
                        dest="email_from",
                        help="Sender Email Address")
    parser.add_argument("-et",
                        "--email-to",
                        dest="email_to",
                        help="Recipient Email Address")
    parser.add_argument("-p",
                        "--email-pass",
                        dest="email_pass",
                        help="Email Pass")
    parser.add_argument("-es",
                        "--email-server",
                        dest="email_server",
                        help="Email Server")
    parser.add_argument("--ti", "--twilio-id", dest="twilio_id", help="SMS Id")
    parser.add_argument("-tk",
                        "--twilio-key",
                        dest="twilio_key",
                        help="SMS Key")
    parser.add_argument("-sf",
                        "--sms-from",
                        dest="sms_from",
                        help="Sender Phone Number")
    parser.add_argument("-st",
                        "--sms-to",
                        dest="sms_to",
                        help="SMS Recipient Phone Number")

    args = parser.parse_args()

    # Ensure that the parameters passed are valid
    if args.email and (not args.email_from or not args.email_to
                       or not args.email_pass or not args.email_server
                       or not args.port):
        parser.error(
            "--email requires --email-to, --email-from, --email-pass, --email-server, and --port"
        )

    if args.sms and (not args.sms_from or not args.sms_to or not args.twilio_id
                     or not args.twilio_key):
        parser.error(
            "--sms requires --sms-to, --sms-from, --twilio-id, and --twilio-key"
        )

    # Scrapes the selected forums and returns dictionaries. Returned values may be None
    gb_dict, ic_dict = scraper.main(ic=args.ic, gb=args.gb)

    if args.email:
        email_message = formatter.email(ic_dict=ic_dict, gb_dict=gb_dict)
        notify.email(message=email_message,
                     email_to=email_to,
                     email_from=email_from,
                     email_pass=email_pass,
                     email_server=email_server,
                     port=port)

    if args.sms:
        sms_message = formatter.sms(ic_dict=ic_dict, gb_dict=gb_dict)
        notify.sms(message=sms_message,
                   sms_to=sms_to,
                   sms_from=sms_from,
                   twilio_id=twilio_id,
                   twilio_key=twilio_key)
コード例 #12
0
ファイル: companies.py プロジェクト: bryanchambers/parsec
def send_results(n):
    subject = 'Parsec Companies Updated'

    msg = str(n) + ' Added'
    email('*****@*****.**', subject, msg)
コード例 #13
0
ファイル: SOHProcCheck.py プロジェクト: BillMills/GRIFFIN-SOH
    SUBJ += procName
    BODY += procName + ": process list " + `listofPIDs` + "\n"
    if deltaTime > 0:
        BODY += "          file untouched %s seconds \n" % deltaTime
    killProcs(listofPIDs) # kill -9 any outstanding processes
    os.system('%s/linux/bin/odbedit -c cleanup' % os.environ['MIDASSYS']) # Cleanup
    BODY += "          Restart with command " + execute + "\n"
    os.system(execute)
    listofPIDS = seekProcs(procName)
    BODY += "          Restarted as process " + `listofPIDS` + "\n"
    if (len(listofPIDS)!=1):
        BODY += "      ** THIS IS AN URGENT PROBLEM. FIX IT **\n"
        SUBJ += " WARNING"
       
# Back to main level
# At this point you should have one of each process running
# If Subject is NOT empty, send an e-mail
if (len(SUBJ) != 0):
    SUBJ = "tigsoh process notification: "+SUBJ
    BODY = BODY + "generated by "+ os.path.abspath(__file__)  
    if mail:
        email(SUBJ,BODY)

if debug:
    print "Subject: " + SUBJ+"\n"
    print """Message body:
""" + BODY
    

# end
コード例 #14
0
ファイル: parsec.py プロジェクト: bryanchambers/parsec
    month = datetime.now().month

    if month < 4: return 1
    elif month < 7: return 2
    elif month < 10: return 3
    else: return 4


def get_quarters():
    year = datetime.now().year
    qtr = get_current_quarter()
    qtrs = [{'year': year, 'qtr': qtr}]

    qtrs.append({
        'year': year if qtr > 1 else year - 1,
        'qtr': qtr - 1 if qtr > 1 else 4
    })

    qtrs.reverse()
    return qtrs


try:
    triggers = load_triggers()

    for qtr in get_quarters():
        parse_quarter(qtr['year'], qtr['qtr'], triggers)

except Exception as error:
    email('*****@*****.**', 'Parsec Error', repr(error))
コード例 #15
0
	def submit(self):
		self.DateSubmitted = time.strftime("%Y-%m-%d", time.localtime())

		#setup priority and state
		self.State = "approved"
		
		if self.UploadPriority == "ASYNC-CRITICAL":
			self.UploadPriority = "async"
			self.State = "waiting"

		self.UploadPriority = self.UploadPriority.lower()
	
		self.db.Start()
		current_cycle_id = getCurrentReleaseCycle(self.db)
		if type(current_cycle_id) == ErrType:
			return result

		if self.UploadPriority == "async":
			merged_id = None
			process = time.strftime("%Y-%m-%d", time.localtime())
			live = "0000-00-00"
			
			#Move from current cycle to async?
			result = self.db.Command('''SELECT id FROM ReleaseAutomation.merged WHERE name="%s" AND products_id=%d AND release_cycle_id=%d'''%(self.Name, self.ProductID, current_cycle_id))
			if type(result) == ErrType:
				return result
			if len(result) > 0:
				merged_id = result[0]['id']


			result = self.db.Command('''INSERT INTO ReleaseAutomation.release_cycle (process_date,live_date,processed,closed,async) VALUES ("%s", "%s", "N", "Y", "Y")'''%(process, live))
			if type(result) == ErrType:
				return result
			result = self.db.Command('''SELECT LAST_INSERT_ID()''')
			if type(result) == ErrType:
				return result
			self.CycleID = int(result[0]['LAST_INSERT_ID()'])


			#Now move the merged request to the async
			if merged_id:
				result = self.db.Command('''UPDATE ReleaseAutomation.merged SET release_cycle_id=%d WHERE id=%d'''%(self.CycleID, merged_id))
				if type(result) == ErrType:
					return result

		else:
			self.CycleID = current_cycle_id

		#Find/add merged request
		result = self.db.Command('''SELECT id FROM ReleaseAutomation.merged WHERE name="%s" AND products_id=%d AND release_cycle_id=%d'''%(self.Name, self.ProductID, self.CycleID))
		if type(result) == ErrType:
			return result

		if len(result) > 0:
			merged = result[0]
			self.MergedID = int(merged['id'])
			result = self.db.Command('''UPDATE ReleaseAutomation.merged SET state="approved", action_date="%s" WHERE id=%d'''%(self.DateSubmitted, self.MergedID))
			if type(result) == ErrType:
				return result
		else:
			#Add new merged:
			result = self.db.Command('''INSERT INTO ReleaseAutomation.merged (name,severity,release_cycle_id,state,action_date,products_id) VALUES("%s", "%s", %d, "%s", "%s", %d)'''%(self.Name, self.UploadPriority, self.CycleID, self.State, self.DateSubmitted, self.ProductID))
			if type(result) == ErrType:
				return result

			result = self.db.Command('''SELECT LAST_INSERT_ID()''')
			if type(result) == ErrType:
				return result
			last_id = result[0]
			self.MergedID = int(last_id['LAST_INSERT_ID()'])


		#check for existing request
		result = self.db.Command('''SELECT * FROM ReleaseAutomation.combined WHERE bug_id=%d AND name LIKE "%s"'''%(self.BugID, self.Name))
		if type(result) == ErrType:
			return result
		if len(result) > 0:
			self.db.Rollback()
			return "There is already a request for this package and bug. If you are trying to update the package a second time, please create a related incident."


		
		#insert combined request
		result = self.db.Command('''INSERT INTO ReleaseAutomation.combined (name,merged_id,bug_id,severity,submitter_id,submit_date,notes) VALUES("%s", %d, %d, "%s", %d, "%s", "%s")'''%(self.Name, self.MergedID, self.BugID, self.UploadPriority, self.SubmitterID, self.DateSubmitted, self.Notes))
		if type(result) == ErrType:
			return result
			
		result = self.db.Command('''SELECT LAST_INSERT_ID()''')
		if type(result) == ErrType:
			return result
		last_id = result[0]
		self.CombinedID = int(last_id['LAST_INSERT_ID()'])

		

		#insert release_request
		package_list = []
		for build in self.BuildIDs:
			for package_id in self.PackageIDs[str(build)]:
				#get types per package
				if package_id[1] in ["host-tool", "common", "host"]:
					table = "Builds.hostPkgs"
				else:
					table = "Builds."+package_id[1]+"Pkgs"
				result = self.db.Command('''SELECT * FROM %s WHERE id=%d'''%(table,package_id[0]))
				if type(result) == ErrType:
					return result

				package = result[0]
				package_name = package['name']
				package_type = package_id[1]
				package_list.append(package_type)
				result = self.db.Command('''INSERT INTO ReleaseAutomation.release_request (name,combined_id,bug_id,builds_id, type, package_id) VALUES("%s", %d, %d, %d, "%s", %d)'''%( package_name, self.CombinedID, self.BugID, build, package_type, package_id[0]))
				if type(result) == ErrType:
					return result
			#end for packageIDs
		#end for BuildIDs
		self.db.Commit()

		#NOTIFY
		subject = '''[Bug %d] Release Request Submitted'''%(self.BugID)
		msg = '''The following Request has been submitted into the Release Request Queue:\r\n'''
		msg += '''Bug %d\r\nPackage:%s\r\nType: %s\r\nSubmitter: %s (%s)\r\nPriority: %s\r\nDate Submitted: %s\r\n\r\n'''%(self.BugID, self.Name, ", ".join(package_list), self.SubmitterName, self.SubmitterEmail, self.UploadPriority, self.DateSubmitted)
		if self.UploadPriority == "async":
			msg += '''Note: This Request Requires manager approval before it will be processed\r\n\r\n'''

		
		email = notify.email()
		result = email.send([], subject, msg)
		if type(result) == ErrType:
			return result

		return None
コード例 #16
0
def send_results(n, c):
    subject = 'Parsec Reports Organized'

    msg = str(n) + ' New, ' + str(c) + ' Updated'
    email('*****@*****.**', subject, msg)
コード例 #17
0
ファイル: SOHProcCheck.py プロジェクト: damiller/GRIFFIN-SOH
    SUBJ += procName
    BODY += procName + ": process list " + ` listofPIDs ` + "\n"
    if deltaTime > 0:
        BODY += "          file untouched %s seconds \n" % deltaTime
    killProcs(listofPIDs)  # kill -9 any outstanding processes
    os.system('%s/linux/bin/odbedit -c cleanup' %
              os.environ['MIDASSYS'])  # Cleanup
    BODY += "          Restart with command " + execute + "\n"
    os.system(execute)
    listofPIDS = seekProcs(procName)
    BODY += "          Restarted as process " + ` listofPIDS ` + "\n"
    if (len(listofPIDS) != 1):
        BODY += "      ** THIS IS AN URGENT PROBLEM. FIX IT **\n"
        SUBJ += " WARNING"

# Back to main level
# At this point you should have one of each process running
# If Subject is NOT empty, send an e-mail
if (len(SUBJ) != 0):
    SUBJ = "tigsoh process notification: " + SUBJ
    BODY = BODY + "generated by " + os.path.abspath(__file__)
    if mail:
        email(SUBJ, BODY)

if debug:
    print "Subject: " + SUBJ + "\n"
    print """Message body:
""" + BODY

# end
コード例 #18
0
ファイル: analyze.py プロジェクト: bryanchambers/parsec
def send_results(n):
    subject = 'Parsec Reports Analyzed'
    message = str(n) + ' Companies Scored'
    email('*****@*****.**', subject, message)
コード例 #19
0
#!/usr/bin/env python3

import public_ip, asyncio, notify

current_ip = public_ip.get('current')
new_ip = public_ip.get('new')

do_ips_match = public_ip.compare(current_ip, new_ip)

if public_ip.has_changed() == True:
    notify.email(new_ip)
    public_ip.set(new_ip)
else:
    print('No change')