Initial commit. This is based on code from ed_tools and fvbot.
This commit is contained in:
commit
010ff377e5
21
Readme.md
Normal file
21
Readme.md
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
# inara.py
|
||||||
|
|
||||||
|
This is a simple python library that is used to retrieve and store data to inara.py.
|
||||||
|
|
||||||
|
It subclasses requests_cache.core.CachedSession to provide a specialized HTTP session to talk to inara.
|
||||||
|
Usage is simple:
|
||||||
|
|
||||||
|
from inara.inara import InaraSession
|
||||||
|
|
||||||
|
session = InaraSession(inara_username, inara_password)
|
||||||
|
session.update_location('Chona')
|
||||||
|
session.update_credits(1000000000)
|
||||||
|
info = session.get_cmdr_info()
|
||||||
|
pprint(info)
|
||||||
|
|
||||||
|
|
||||||
|
If the logged-in user is a member of a Wing, you can get information about wing-mates like so:
|
||||||
|
|
||||||
|
info = session.get_cmdr_info(wing_id, cmdr_id)
|
||||||
|
|
||||||
|
where the 'id's are the numeric identifiers visible in inara's URLs.
|
0
__init__.py
Normal file
0
__init__.py
Normal file
145
inara.py
Normal file
145
inara.py
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
"""
|
||||||
|
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 = session.get_soup(CMDR_URL)
|
||||||
|
if not self._inara_is_logged_in(soup):
|
||||||
|
return False
|
||||||
|
|
||||||
|
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 True
|
||||||
|
|
||||||
|
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 = session.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 = session.get_soup("%s/cmdr/%s" % (BASE_URL, cmdr_id))
|
||||||
|
else:
|
||||||
|
cmdr_soup = session.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]
|
Reference in New Issue
Block a user