From 4766b891ff104acb5de8e4ee736b11ce69079327 Mon Sep 17 00:00:00 2001 From: Klaus-Uwe Mitterer Date: Fri, 5 Feb 2016 11:39:34 +0100 Subject: [PATCH] Move Facebook credentials to config file Create setup.py Allow Two Factor Authentication Lots of smaller changes --- pokemon.py | 142 ++++++++++++++++++++++++++++++++++------------------- setup.py | 21 ++++++++ 2 files changed, 113 insertions(+), 50 deletions(-) create mode 100755 setup.py diff --git a/pokemon.py b/pokemon.py index 9ea39c3..9e0714b 100755 --- a/pokemon.py +++ b/pokemon.py @@ -1,95 +1,137 @@ #!/usr/bin/env python +# -*- coding: utf-8 -*- '''pokemon.py: Automatically poke back on Facebook''' __author__ = "Klaus-Uwe Mitterer" __maintainer__ = __author__ __email__ = "info@klaus-uwe.me" -__version__ = "0.2" +__version__ = "0.3" -import urllib, cookielib, urllib2, time, BeautifulSoup, signal +import urllib, cookielib, urllib2, time, BeautifulSoup, signal, sys, configparser, os.path + +def getNH(html): + for input in BeautifulSoup.BeautifulSoup(html).findAll('input'): + try: + if input["name"] == "nh": + return input["value"] + except: + pass + return False + +def log(text, status=0): + print text class Account: - jar = cookielib.CookieJar() - cookie = urllib2.HTTPCookieProcessor(jar) - opener = urllib2.build_opener(cookie) + def __init__(self, username, password): + self.username = username + self.password = password + + self.jar = cookielib.MozillaCookieJar("cookies.txt") + try: + self.jar.load() + except: + pass + + self.cookie = urllib2.HTTPCookieProcessor(self.jar) + self.opener = urllib2.build_opener(self.cookie) def login(self): - email = "something" - password = "something" - try: - params = urllib.urlencode({'lsd':'AVoT-4T0','charset_test':'€,´,€,´,水,Д,Є','version':'1','ajax':'0','width':'0','pxr':'0','gps':'0','dimensions':'0','m_ts':int(time.time()),'li':'dflbVIod_lz7592W_lmOrvph','email':email,'pass':password,'login':'Log+In'}) + params = urllib.urlencode({'lsd':'AVoT-4T0','charset_test':'€,´,€,´,水,Д,Є','version':'1','ajax':'0','width':'0','pxr':'0','gps':'0','dimensions':'0','m_ts':int(time.time()),'li':'dflbVIod_lz7592W_lmOrvph','email':self.username,'pass':self.password,'login':'Log+In'}) req = urllib2.Request('https://m.facebook.com/login.php?refsrc=https%3A%2F%2Fm.facebook.com%2F&refid=8', params) res = self.opener.open(req) html = res.read() + + if "Code Generator" in html: + nh = getNH(html) + print "You have two-factor authentication enabled. Please enter an approval code (e.g. from your Facebook app)." + print "Please note: If you get a login error after this, try logging in to Facebook through a browser, confirm the login notification and choose 'Save Browser', then try again." + appcode = raw_input("Input code: ") + params = urllib.urlencode({'lsd':'AVrIY3Uu','charset_test':'€,´,€,´,水,Д,Є','approvals_code':appcode,'nh':nh,'codes_submitted':'0', 'submit[Submit+Code]':'Submit+Code'}) + req = urllib2.Request('https://m.facebook.com/login/checkpoint/', params) + res = self.opener.open(req) + html = res.read() + + if "Save Browser" in html: + nh = getNH(html) + params = urllib.urlencode({'lsd':'AVrIY3Uu','charset_test':'€,´,€,´,水,Д,Є','name_action_selected':'save_device','nh':nh,'submit[Continue]':'Continue'}) + req = urllib2.Request('https://m.facebook.com/login/checkpoint/', params) + res = self.opener.open(req) + html = res.read() + except urllib2.HTTPError, e: - print e.msg + log(e.msg, 1) except urllib2.URLError, e: - print e.reason[1] - print "This may occur if you run into Facebook's rate limit." - print "Please try again later." + log(e.reason[1], 1) + log("This may occur if you run into Facebook's rate limit.", 1) + log("Please try again later.", 1) return False def fetch(self,url): req = urllib2.Request(url,None) res = self.opener.open(req) - return res.read(), res.headers.get("Set-Cookie") + content, cookie = res.read(), res.headers.get("Set-Cookie") + return content, cookie - def loggedin(self): - webpage, session = self.fetch('https://m.facebook.com/') + def loggedin(self, webpage=None): + if webpage == None: + webpage, session = self.fetch('https://m.facebook.com/') if "Logout" in webpage: return True return False def poke(self): - webpage, session = me.fetch('https://m.facebook.com/pokes') - - if "Logout" in webpage: + webpage, session = self.fetch('https://m.facebook.com/pokes') + if self.loggedin(webpage): links=BeautifulSoup.BeautifulSoup(webpage).findAll('a') for a in links: url=a['href'] if "dom_id_replace" in url: if not "suggestion" in url: - poke=me.fetch('https://m.facebook.com'+url) - print "Poke!" + poke = self.fetch('https://m.facebook.com' + url) + log("Poke!") - me.fetch('https://m.facebook.com/notifications.php') + self.fetch('https://m.facebook.com/notifications.php') return True return False -me = Account() -me.login() + def loop(self): + while True: + try: + if not self.poke(): + self.login() + except KeyboardInterrupt: + self.quit() + except: + log("Something unexpected happened... o.O", 1) + raise -class Timeout: - time = 10 - - def timeouthandler(self, signum, frame): - raise Exception("Poke timed out.") - - def timeoutstarter(self): - signal.signal(signal.SIGALRM, self.timeouthandler) - signal.alarm(self.time) + def quit(self, status=0): + log("Exiting...") + self.jar.save() + sys.exit(status) -to = Timeout() - -if me.loggedin(): - print("Login successful!") -else: - print("Doh!") - print("Seems like you entered wrong credentials.") - print("Check the README for details.") - sys.exit(1) - -while True: +def getCredentials(conffile="config.cfg"): try: - to.timeoutstarter() - if not me.poke(): - me.login() - except KeyboardInterrupt: - raise + config = configparser.RawConfigParser() + config.read(conffile) + return config.get("facebook","user"), config.get("facebook","pass") except: - pass + raise IOError("Config file not found. Run setup.py and try again.") +if __name__ == "__main__": + me = Account(*getCredentials()) + me.login() + + if me.loggedin(): + log("Login successful!") + else: + log("Doh!", 1) + log("Seems like you entered wrong credentials.", 1) + log("Check the README for details.", 1) + me.quit(1) + + me.loop() diff --git a/setup.py b/setup.py new file mode 100755 index 0000000..3f1b829 --- /dev/null +++ b/setup.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python3 + +import configparser, os.path + +if os.path.isfile("config.cfg"): + raise IOError("config.cfg already exists. Please remove it before running this script.") + +config = configparser.RawConfigParser() + +config.add_section('facebook') + +user = input("Facebook username (email address): ") +pwd = input("Facebook password: ") + +config.set('facebook', 'user', user) +config.set('facebook', 'pass', pwd) + +with open('config.cfg', 'wt') as cfg: + config.write(cfg) + +print("We're all done. You can now use Pokemon. Have fun!")