0

I have just learned the basics of Python, and I am trying to make a few projects so that I can increase my knowledge of the programming language.

Since I am rather paranoid, I created a script that uses PycURL to fetch my current IP address every x seconds, for VPN security. Here is my code[EDITED]:

import requests

enterIP = str(input("What is your current IP address?"))

def getIP():
    while True:
        try:
             result = requests.get("http://ipinfo.io/ip")
             print(result.text)
        except KeyboardInterrupt:
             print("\nProccess terminated by user")
    return result.text

def checkIP():
    while True:
        if enterIP == result.text:
            pass
         else:
            print("IP has changed!")

getIP()
checkIP()

Now I would like to expand the idea, so that the script asks the user to enter their current IP, saves that octet as a string, then uses a loop to keep running it against the PycURL function to make sure that their IP hasn't changed? The only problem is that I am completely stumped, I cannot come up with a function that would take the output of PycURL and compare it to a string. How could I achieve that?

  • Initially I was using a function but I ran into some errors, and with the simplicity of this script I don't need to define a function at the moment. –  May 27 '17 at 21:30
  • @sS5H It should be the other way around. You do not need to define a class for such a simple function ;) – ruuter May 27 '17 at 21:32
  • @sS5H you made it worse :D You do not need two loops. One is more than enough. You also do not need to ask for an input. Just check once at the start and save it. Then run the loop and compare it to the first. – ruuter May 27 '17 at 22:20

2 Answers2

2

As @holdenweb explained, you do not need pycurl for such a simple task, but nevertheless, here is a working example:

import pycurl
import time
from StringIO import StringIO

def get_ip():
    buffer = StringIO()
    c = pycurl.Curl()
    c.setopt(pycurl.URL, "http://ipinfo.io/ip")
    c.setopt(c.WRITEDATA, buffer)
    c.perform()
    c.close()
    return buffer.getvalue()

def main():
    initial = get_ip()
    print 'Initial IP: %s' % initial

    try:
        while True:
            current = get_ip()
            if current != initial:
                print 'IP has changed to: %s' % current
            time.sleep(300)
    except KeyboardInterrupt:
        print("\nProccess terminated by user")

if __name__ == '__main__':
    main()

As you can see I moved the logic of getting the IP to separate function: get_ip and added few missing things, like catching the buffer to a string and returning it. Otherwise it is pretty much the same as the first example in pycurl quickstart

The main function is called below, when the script is accessed directly (not by import).

First off it calls the get_ip to get initial IP and then runs the while loop which checks if the IP has changed and lets you know if so.

EDIT: Since you changed your question, here is your new code in a working example:

import requests

def getIP():
    result = requests.get("http://ipinfo.io/ip")
    return result.text

def checkIP():
    initial = getIP()
    print("Initial IP: {}".format(initial))
    while True:
        current = getIP()
        if initial == current:
            pass                                
        else:
            print("IP has changed!")

checkIP()

As I mentioned in the comments above, you do not need two loops. One is enough. You don't even need two functions, but better do. One for getting the data and one for the loop. In the later, first get initial value and then run the loop, inside which you check if value has changed or not.

ruuter
  • 2,453
  • 2
  • 30
  • 44
  • I'm assuming you're using Python2, since I get a lot of errors because of functions that were modified in Python3? –  May 27 '17 at 22:07
  • Yes you are correct. This example assumes python 2, but keep the same framework and change to functions and syntax for py3. Better yet, dump the pycurl approach and use requests as @holdenweb pointed out. Nevertheless, general structure of the script could stay the same. – ruuter May 27 '17 at 22:15
  • After tweaking some things, the script worked perfectly. Thanks! –  May 27 '17 at 22:21
  • Glad to hear, you're welcome. Edited the answer though, since you changed the question. This time it's py3. – ruuter May 27 '17 at 22:38
1

It seems, from reading the pycurl documentation, like you would find it easier to solve this problem using the requests library. Curl is more to do with file transfer, so the library expects you to provide a file-like object into which it writes the contents. This would greatly complicate your logic.

requests allows you to access the text of the server's response directly:

>>> import requests
>>> result = requests.get("http://ipinfo.io/ip")
>>> result.text
'151.231.192.8\n'

As @PeterWood suggested, a function would be more appropriate than a class for this - or if the script is going to run continuously, just a simple loop as the body of the program.

holdenweb
  • 33,305
  • 7
  • 57
  • 77
  • Thank you, this looks a lot more simple and efficient. I got this block of code to replicate PycURL a lot more simply. Now, I have created two functions: one is for the requests loop and the other is a loop function to make sure that the IP hasn't changed. It's only running the first function however. Do I need to use threads so that both of these loop functions can run at the same time? –  May 27 '17 at 21:51
  • If you want to do two things concurrently then you have a number of alternatives. Threads would probably be the easiest. – holdenweb May 28 '17 at 09:41