This repository has been archived on 2019-12-04. You can view files and clone it, but cannot push or open issues or pull requests.
elite_api/inara.py

146 lines
3.7 KiB
Python
Raw Permalink Normal View History

"""
A wrapper around the requests library to retrieve and update various information
about a commander from inara.cz
"""
from bs4 import BeautifulSoup
import re
import requests_cache
from requests_cache.core import CachedSession
BASE_URL = "http://inara.cz/"
CMDR_URL = BASE_URL + 'cmdr/'
# Some fun exceptions to raise!
class ServerError(Exception):
pass
class CredentialsError(Exception):
pass
class LoggingInException(Exception):
pass
class CmdrNotFoundException(Exception):
pass
class InaraSession(CachedSession):
def __init__(self, username, password):
CachedSession.__init__(self,
cache_name='inara',
backend='memory',
expire_after=600.0,
old_data_on_error=True)
self.username = username
self.password = password
self.inara_login()
def inara_login(self):
if (not self.username or not self.password):
raise CredentialsError()
data = {
"loginid": self.username,
"loginpass": self.password,
"formact": "ENT_LOGIN",
"location": "intro"
}
r = self.post(BASE_URL, data=data)
r.raise_for_status()
def _inara_is_logged_in(self, soup):
logout_link = soup.find(href=re.compile('ENT_LOGOUT'))
return logout_link is not None
def update_credits(self, credits):
soup = self.get_soup(CMDR_URL)
if not self._inara_is_logged_in(soup):
return None
oass = int(soup.find(id='oassinput')['value'])
data = {
"location": "cmdr",
"formact": "USER_CREDITS_SET",
"playercredits": credits,
"playercreditsassets": credits + oass,
"oass": oass,
}
r = self.post(CMDR_URL, data=data)
r.raise_for_status()
return credits + oass
def update_location(self, location):
data = {
'formact': 'USER_LOCATION_SET',
'playercurloc': location
}
r = self.post(CMDR_URL, data=data)
r.raise_for_status()
def get_cmdr_info(wing_id=None, cmdr_id=None):
result = {}
if wing_id is not None and cmdr_id is not None:
wing_soup = self.get_soup("%s/wing/%s" % (BASE_URL, wing_id))
result['rank'] = _get_rank(wing_soup, cmdr_id)
result['location'] = _get_location(wing_soup, cmdr_id)
if cmdr_id is not None:
cmdr_soup = self.get_soup("%s/cmdr/%s" % (BASE_URL, cmdr_id))
else:
cmdr_soup = self.get_soup(CMDR_URL)
result['balance'] = _get_cmdr_balance(cmdr_soup)
result['assets'] = _get_cmdr_assets(cmdr_soup)
return result
def get_soup(self, url):
r = self.get(url)
r.raise_for_status()
soup = BeautifulSoup(r.text, 'html.parser')
if not self._inara_is_logged_in(soup):
self.inara_login()
# invalidate the cache entry, since we only want logged-in data
self.cache.delete_url(url)
raise LoggingInException()
return soup
def _get_cmdr_row(soup, cmdr_id):
link = soup.find(attrs={'class': 'subtable'}).find(
href=re.compile('/cmdr/' + cmdr_id))
for parent in link.parents:
if parent.name == 'tr':
return parent
raise CmdrNotFoundException()
def _get_rank(soup, cmdr_id):
row = _get_cmdr_row(soup, cmdr_id)
return row.td.img['title']
def _get_location(soup, cmdr_id):
row = _get_cmdr_row(soup, cmdr_id)
location_link = row.find(href=re.compile('market'))
if not location_link or len(location_link.contents) == 0:
return "Unknown"
else:
return location_link.contents[0]
def _get_cmdr_balance(soup):
title_text = soup.find(text="Credit Balance")
br = title_text.parent.next_sibling
return br.contents[0]
def _get_cmdr_assets(soup):
title_text = soup.find(text="Overall assets")
br = title_text.parent.next_sibling
return br.contents[0]