+class credentials(object):
+ def __init__(self, username, password):
+ self.username = username
+ self.password = password
+
+ @classmethod
+ def fromfile(cls, path):
+ username, password = None, None
+ with open(path) as fp:
+ for words in profile.splitlines(fp):
+ if words[0] == "username":
+ username = words[1]
+ elif words[0] == "password":
+ password = words[1]
+ elif words[0] == "pass64":
+ import binascii
+ password = binascii.a2b_base64(words[1]).decode("utf8")
+ if None in (username, password):
+ raise ValueError("Incomplete profile: " + path)
+ return cls(username, password)
+
+ @classmethod
+ def default(cls):
+ path = os.path.join(profile.confdir, "batoto")
+ if os.path.exists(path):
+ return cls.fromfile(path)
+ return None
+
+class session(object):
+ def __init__(self, base, credentials):
+ self.base = base
+ self.creds = credentials
+ self.jar = http.cookiejar.CookieJar()
+ self.web = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(self.jar))
+ self.loggedin = False
+
+ rlre = re.compile(r"Welcome, (.*) ")
+ def dologin(self):
+ with self.web.open(self.base) as hs:
+ page = soupify(hs.read())
+
+ cur = page.find("a", id="user_link")
+ print(0)
+ if cur:
+ m = self.rlre.search(cur.get_text())
+ if not m or m.group(1) != self.creds.username:
+ print(1)
+ outurl = None
+ nav = page.find("div", id="user_navigation")
+ if nav:
+ for li in nav.findAll("li"):
+ if li.a and "Sign Out" in li.a.string:
+ outurl = li.a["href"]
+ if not outurl:
+ raise pageerror("Could not find logout URL", page)
+ with self.wep.open(outurl) as hs:
+ hs.read()
+ with self.web.open(self.base) as hs:
+ page = soupify(hs.read())
+ else:
+ print(2)
+ return
+ else:
+ print(3)
+
+ form = page.find("form", id="login")
+ values = {}
+ for el in form.findAll("input", type="hidden"):
+ values[el["name"]] = el["value"]
+ values["ips_username"] = self.creds.username
+ values["ips_password"] = self.creds.password
+ values["anonymous"] = "1"
+ req = urllib.request.Request(form["action"], urllib.parse.urlencode(values).encode("ascii"))
+ with self.web.open(req) as hs:
+ page = soupify(hs.read())
+ for resp in page.findAll("p", attrs={"class": "message"}):
+ if resp.strong and "You are now signed in" in resp.strong.string:
+ break
+ else:
+ raise pageerror("Could not log in", page)
+
+ def login(self):
+ if not self.loggedin:
+ if self.creds:
+ self.dologin()
+ self.loggedin = True
+
+ def open(self, url):
+ return self.web.open(url)
+
+ def fetch(self, url):
+ with self.open(url) as hs:
+ return hs.read()
+
+ def lfetch(self, url, ck):
+ page = soupify(self.fetch(url))
+ if not ck(page):
+ self.login()
+ page = soupify(self.fetch(url))
+ if not ck(page):
+ raise pageerror("Could not verify login status despite having logged in", page)
+ return page
+