1
0
mirror of https://github.com/EDCD/EDMarketConnector.git synced 2025-04-15 16:50:34 +03:00
EDMarketConnector/companion.py

128 lines
4.2 KiB
Python

#!/usr/bin/python
# -*- coding: utf-8 -*-
import json
import requests
from collections import defaultdict
from cookielib import LWPCookieJar
import os
from os.path import dirname, join
from requests.packages import urllib3
import sys
from sys import platform
if __debug__:
from traceback import print_exc
from config import config
holdoff = 120 # be nice
# Map values reported by the Companion interface to names displayed in-game and recognized by trade tools
categorymap = { 'Narcotics': 'Legal Drugs',
'Slaves': 'Slavery', }
commoditymap= { 'Agricultural Medicines': 'Agri-Medicines',
'Atmospheric Extractors': 'Atmospheric Processors',
'Auto Fabricators': 'Auto-Fabricators',
'Basic Narcotics': 'Narcotics',
'Bio Reducing Lichen': 'Bioreducing Lichen',
'Hazardous Environment Suits': 'H.E. Suits',
'Heliostatic Furnaces': 'Microbial Furnaces',
'Marine Supplies': 'Marine Equipment',
'Non Lethal Weapons': 'Non-Lethal Weapons',
'Terrain Enrichment Systems': 'Land Enrichment Systems', }
bracketmap = { 1: 'Low',
2: 'Med',
3: 'High', }
class CredentialsError(Exception):
def __str__(self):
return 'Error: Invalid Credentials'
class VerificationRequired(Exception):
def __str__(self):
return 'Authentication required'
# Server companion.orerve.net uses a session cookie ("CompanionApp") to tie together login, verification
# and query. So route all requests through a single Session object which holds this state.
class Session:
STATE_NONE, STATE_INIT, STATE_AUTH, STATE_OK = range(4)
def __init__(self):
self.state = Session.STATE_INIT
self.credentials = None
urllib3.disable_warnings() # yuck suppress InsecurePlatformWarning
if platform=='win32' and getattr(sys, 'frozen', False):
os.environ['REQUESTS_CA_BUNDLE'] = join(dirname(sys.executable), 'cacert.pem')
self.session = requests.Session()
self.session.headers['User-Agent'] = 'Mozilla/5.0 (iPhone; CPU iPhone OS 7_1_2 like Mac OS X) AppleWebKit/537.51.2 (KHTML, like Gecko) Mobile/11D257'
self.session.cookies = LWPCookieJar(join(config.app_dir, 'cookies.txt'))
try:
self.session.cookies.load()
except IOError:
pass
def login(self, username=None, password=None):
self.state = Session.STATE_INIT
if (not username or not password):
if not self.credentials:
raise CredentialsError()
else:
self.credentials = { 'email' : username, 'password' : password }
r = self.session.post('https://companion.orerve.net/user/login', data = self.credentials)
r.raise_for_status()
if 'Password' in r.text:
raise CredentialsError()
elif 'Verification Code' in r.text:
self.state = Session.STATE_AUTH
raise VerificationRequired()
else:
self.state = Session.STATE_OK
return r.status_code
def verify(self, code):
r = self.session.post('https://companion.orerve.net/user/confirm',
data = { 'code' : code })
r.raise_for_status()
# verification doesn't actually return a yes/no, so log in again to determine state
try:
self.login()
except:
pass
def query(self):
if self.state == Session.STATE_NONE:
raise Exception('General error') # Shouldn't happen
elif self.state == Session.STATE_INIT:
raise CredentialsError()
elif self.state == Session.STATE_AUTH:
raise VerificationRequired()
r = self.session.get('https://companion.orerve.net/profile')
if r.status_code == requests.codes.forbidden:
# Maybe our session cookie expired?
self.login()
r = self.session.get('https://companion.orerve.net/profile')
r.raise_for_status()
return json.loads(r.text)
def close(self):
self.state = Session.STATE_NONE
try:
self.session.cookies.save()
self.session.close()
except:
pass
self.session = None