def api_keys(api_key_list, unassociated=False, dashboard_id=None, verify_mask=True): """ :param verify_mask: Choose whether to reject or expire non-conforming access masks :param api_key_list: [(key_id, vcode), (), ...] :param unassociated: True to add to unassociated API keys :param dashboard_id: Set the associated dashboard id. Defaults to the session variable. :return: """ if unassociated: api_owner = "unassociated" elif dashboard_id: api_owner = dashboard_id else: api_owner = session["CharacterOwnerHash"] with open("configs/base.json", "r") as base_config_file: base_config = json.load(base_config_file) errors_list = [] bulk_op = g.mongo.db.api_keys.initialize_ordered_bulk_op() bulk_run = False for key_id, vcode in api_key_list: db_api_cache = g.mongo.db.api_keys.find_one({"_id": api_owner, "keys.key_id": {"$eq": int(key_id)}}) cache_timer = 0 if db_api_cache and api_owner != "unassociated": cache_timer_list = [key["cached_until"] for key in db_api_cache["keys"] if key["key_id"] == int(key_id)] cache_timer = max(cache_timer_list) elif api_owner == "unassociated": cache_timer = 0 if not db_api_cache or cache_timer < time.time(): xml_contracts_payload = { "keyID": key_id, "vCode": vcode } xml_api_key_response = requests.get("https://api.eveonline.com/account/APIKeyInfo.xml.aspx", data=xml_contracts_payload, headers=xml_headers) # XML Parse try: xml_api_key_tree = ElementTree.fromstring(xml_api_key_response.text) except ElementTree.ParseError: print(xml_api_key_response.text) return errors_list # Store in database xml_time_pattern = "%Y-%m-%d %H:%M:%S" failed = False expired = False if xml_api_key_tree[1].tag == "error": errors_list.append("CCP gave an error for key with id " + "{}. Ensure the key is not expired and is valid.".format(key_id)) failed = True elif xml_api_key_tree[1][0].attrib["accessMask"] != str(base_config["access_mask"]): errors_list.append("Key with id {} is not (or no longer) a full API key.".format(key_id)) if verify_mask: failed = True else: expired = True elif xml_api_key_tree[1][0].attrib["type"] != "Account": errors_list.append("Key with id {} is not an Account API key.".format(key_id)) failed = True elif xml_api_key_tree[1][0].attrib["expires"].strip(): errors_list.append("Key with id {} expires. Must be a non-expiring API key.".format(key_id)) failed = True # Check for fail if failed: conversions.invalidate_key([key_id], api_owner) continue else: conversions.validate_key([key_id], api_owner, expired) # If same character is input, remove old keys first bulk_op.find({"_id": api_owner}).upsert().update( { "$pull": { "keys": {"key_id": int(key_id)} } }) if api_owner != "unassociated": # Remove keys from unassociated if found bulk_op.find({"_id": "unassociated"}).upsert().update( { "$pull": { "keys": {"key_id": int(key_id)} } } ) for api_character in xml_api_key_tree[1][0][0]: bulk_run = True update_request = {"$push": {"keys": { "key_id": int(key_id), "vcode": vcode, "character_id": int(api_character.attrib["characterID"]), "character_name": api_character.attrib["characterName"], "cached_until": int(calendar.timegm(time.strptime(xml_api_key_tree[2].text, xml_time_pattern))), "cached_str": xml_api_key_tree[2].text, "corporation_id": int(api_character.attrib["corporationID"]), "alliance_id": int(api_character.attrib["allianceID"]), "corporation_name": api_character.attrib["corporationName"].strip(), "alliance_name": api_character.attrib["allianceName"].strip() }}} if api_owner != "unassociated" or (api_owner == "unassociated" and not g.mongo.db.api_keys.find_one( {"keys.key_id": {"$eq": int(key_id)}, "_id": {"$ne": "unassociated"}})): bulk_op.find({"_id": api_owner}).upsert().update(update_request) if bulk_run: bulk_op.execute() return errors_list
def api_keys(api_key_list, unassociated=False, dashboard_id=None, verify_mask=True): """ :param verify_mask: Choose whether to reject or expire non-conforming access masks :param api_key_list: [(key_id, vcode), (), ...] :param unassociated: True to add to unassociated API keys :param dashboard_id: Set the associated dashboard id. Defaults to the session variable. :return: """ if unassociated: api_owner = "unassociated" elif dashboard_id: api_owner = dashboard_id else: api_owner = session["CharacterOwnerHash"] with open("configs/base.json", "r") as base_config_file: base_config = json.load(base_config_file) errors_list = [] bulk_op = g.mongo.db.api_keys.initialize_ordered_bulk_op() bulk_run = False for key_id, vcode in api_key_list: db_api_cache = g.mongo.db.api_keys.find_one({"_id": api_owner, "keys.key_id": {"$eq": int(key_id)}}) cache_timer = 0 if db_api_cache and api_owner != "unassociated": cache_timer_list = [key["cached_until"] for key in db_api_cache["keys"] if key["key_id"] == int(key_id)] cache_timer = max(cache_timer_list) elif api_owner == "unassociated": cache_timer = 0 if not db_api_cache or cache_timer < time.time(): xml_contracts_payload = {"keyID": key_id, "vCode": vcode} xml_api_key_response = requests.get( "https://api.eveonline.com/account/APIKeyInfo.xml.aspx", data=xml_contracts_payload, headers=xml_headers ) # XML Parse try: xml_api_key_tree = ElementTree.fromstring(xml_api_key_response.text) except ElementTree.ParseError: print(xml_api_key_response.text) return errors_list # Store in database xml_time_pattern = "%Y-%m-%d %H:%M:%S" failed = False expired = False if xml_api_key_tree[1].tag == "error": errors_list.append( "CCP gave an error for key with id " + "{}. Ensure the key is not expired and is valid.".format(key_id) ) failed = True elif xml_api_key_tree[1][0].attrib["accessMask"] != str(base_config["access_mask"]): errors_list.append("Key with id {} is not (or no longer) a full API key.".format(key_id)) if verify_mask: failed = True else: expired = True elif xml_api_key_tree[1][0].attrib["type"] != "Account": errors_list.append("Key with id {} is not an Account API key.".format(key_id)) failed = True elif xml_api_key_tree[1][0].attrib["expires"].strip(): errors_list.append("Key with id {} expires. Must be a non-expiring API key.".format(key_id)) failed = True # Check for fail if failed: conversions.invalidate_key([key_id], api_owner) continue else: conversions.validate_key([key_id], api_owner, expired) # If same character is input, remove old keys first bulk_op.find({"_id": api_owner}).upsert().update({"$pull": {"keys": {"key_id": int(key_id)}}}) if api_owner != "unassociated": # Remove keys from unassociated if found bulk_op.find({"_id": "unassociated"}).upsert().update({"$pull": {"keys": {"key_id": int(key_id)}}}) for api_character in xml_api_key_tree[1][0][0]: bulk_run = True update_request = { "$push": { "keys": { "key_id": int(key_id), "vcode": vcode, "character_id": int(api_character.attrib["characterID"]), "character_name": api_character.attrib["characterName"], "cached_until": int( calendar.timegm(time.strptime(xml_api_key_tree[2].text, xml_time_pattern)) ), "cached_str": xml_api_key_tree[2].text, "corporation_id": int(api_character.attrib["corporationID"]), "alliance_id": int(api_character.attrib["allianceID"]), "corporation_name": api_character.attrib["corporationName"].strip(), "alliance_name": api_character.attrib["allianceName"].strip(), } } } if api_owner != "unassociated" or ( api_owner == "unassociated" and not g.mongo.db.api_keys.find_one( {"keys.key_id": {"$eq": int(key_id)}, "_id": {"$ne": "unassociated"}} ) ): bulk_op.find({"_id": api_owner}).upsert().update(update_request) if bulk_run: bulk_op.execute() return errors_list
def contracts(keys=None, celery_time=0): """ :param keys: [("jf_service" or "personal", key_id, vcode, character_id), (), ...] :param celery_time: Set to the next run time instance :return: """ if celery_time: g.mongo.db.caches.update({"_id": "jf_service"}, {"$set": { "next_check": time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(int(time.time()) + celery_time))}}) invalid_apis = set() if not keys: # Default Refreshes keys = [("jf_service", secrets["jf_key_id"], secrets["jf_vcode"])] bulk_op = g.mongo.db.contracts.initialize_unordered_bulk_op() bulk_run = False for service in keys: if service[0] == "personal": # If service is personal, uses key_caches database for cache values instead db_cache = g.mongo.db.key_caches.find_one({"_id": service[3]}) cache_time = db_cache.get("contracts", 0) if db_cache else 0 else: db_cache = g.mongo.db.caches.find_one({"_id": service[0]}) cache_time = db_cache.get("cached_until", 0) if db_cache else 0 if not db_cache or cache_time < time.time(): # Clean contract history month_ago = int(time.time()) - 2629743 # Services are 1 month two_weeks_ago = int(time.time()) - 1512000 # Personals are 2 1/2 weeks filter_time = month_ago if service[0] == "personal": filter_time = two_weeks_ago if service[0] == "personal": xml_contracts_payload = { "keyID": service[1], "vCode": service[2], "characterID": service[3] } xml_contracts_response = requests.get("https://api.eveonline.com/char/Contracts.xml.aspx", data=xml_contracts_payload, headers=xml_headers) else: xml_contracts_payload = { "keyID": service[1], "vCode": service[2] } xml_contracts_response = requests.get("https://api.eveonline.com/Corp/Contracts.xml.aspx", data=xml_contracts_payload, headers=xml_headers) # XML Parse try: xml_contracts_tree = ElementTree.fromstring(xml_contracts_response.text) except ElementTree.ParseError: print(xml_contracts_response.text) return list(invalid_apis) # Store in database xml_time_pattern = "%Y-%m-%d %H:%M:%S" if service[0] == "personal": g.mongo.db.key_caches.update({"_id": int(service[3])}, {"$set": { "contracts": int( calendar.timegm(time.strptime(xml_contracts_tree[2].text, xml_time_pattern))), "contracts_str": xml_contracts_tree[2].text, "key": int(service[1])} }, upsert=True) else: g.mongo.db.caches.update({"_id": service[0]}, {"$set": {"cached_until": int( calendar.timegm(time.strptime(xml_contracts_tree[2].text, xml_time_pattern))), "cached_str": xml_contracts_tree[2].text}}, upsert=True) if xml_contracts_tree[1].tag == "error": print(xml_contracts_tree[1].attrib["code"], xml_contracts_tree[1].text, service[1]) conversions.invalidate_key([service[1]], session["CharacterOwnerHash"]) invalid_apis.add(service[1]) else: for contract in xml_contracts_tree[1][0]: issue_time = int(calendar.timegm(time.strptime(contract.attrib["dateIssued"], xml_time_pattern))) if issue_time > filter_time: bulk_run = True bulk_op.find({ "_id.id": int(contract.attrib["contractID"]), "_id.service": service[0] }).upsert().update( { "$set": { "issuer_id": int(contract.attrib["issuerID"]), "assignee_id": int(contract.attrib["assigneeID"]), "acceptor_id": int(contract.attrib["acceptorID"]), "start_station_id": int(contract.attrib["startStationID"]), "end_station_id": int(contract.attrib["endStationID"]), "type": contract.attrib["type"], "status": contract.attrib["status"], "title": contract.attrib["title"], "for_corp": int(contract.attrib["forCorp"]), "date_issued": contract.attrib["dateIssued"], "date_expired": contract.attrib["dateExpired"], "date_accepted": contract.attrib["dateAccepted"], "num_days": int(contract.attrib["numDays"]), "date_completed": contract.attrib["dateCompleted"], "price": float(contract.attrib["price"]), "reward": float(contract.attrib["reward"]), "collateral": float(contract.attrib["collateral"]), "volume": float(contract.attrib["volume"]), "issued_int": issue_time } }) if bulk_run: try: bulk_op.execute() except BulkWriteError as bulk_op_error: print("error", bulk_op_error.details) return list(invalid_apis)
def contracts(keys=None, celery_time=0): """ :param keys: [("jf_service" or "personal", key_id, vcode, character_id), (), ...] :param celery_time: Set to the next run time instance :return: """ if celery_time: g.mongo.db.caches.update( {"_id": "jf_service"}, {"$set": {"next_check": time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(int(time.time()) + celery_time))}}, ) invalid_apis = set() if not keys: # Default Refreshes keys = [("jf_service", secrets["jf_key_id"], secrets["jf_vcode"])] bulk_op = g.mongo.db.contracts.initialize_unordered_bulk_op() bulk_run = False for service in keys: if service[0] == "personal": # If service is personal, uses key_caches database for cache values instead db_cache = g.mongo.db.key_caches.find_one({"_id": service[3]}) cache_time = db_cache.get("contracts", 0) if db_cache else 0 else: db_cache = g.mongo.db.caches.find_one({"_id": service[0]}) cache_time = db_cache.get("cached_until", 0) if db_cache else 0 if not db_cache or cache_time < time.time(): # Clean contract history month_ago = int(time.time()) - 2629743 # Services are 1 month two_weeks_ago = int(time.time()) - 1512000 # Personals are 2 1/2 weeks filter_time = month_ago if service[0] == "personal": filter_time = two_weeks_ago if service[0] == "personal": xml_contracts_payload = {"keyID": service[1], "vCode": service[2], "characterID": service[3]} xml_contracts_response = requests.get( "https://api.eveonline.com/char/Contracts.xml.aspx", data=xml_contracts_payload, headers=xml_headers ) else: xml_contracts_payload = {"keyID": service[1], "vCode": service[2]} xml_contracts_response = requests.get( "https://api.eveonline.com/Corp/Contracts.xml.aspx", data=xml_contracts_payload, headers=xml_headers ) # XML Parse try: xml_contracts_tree = ElementTree.fromstring(xml_contracts_response.text) except ElementTree.ParseError: print(xml_contracts_response.text) return list(invalid_apis) # Store in database xml_time_pattern = "%Y-%m-%d %H:%M:%S" if service[0] == "personal": g.mongo.db.key_caches.update( {"_id": int(service[3])}, { "$set": { "contracts": int( calendar.timegm(time.strptime(xml_contracts_tree[2].text, xml_time_pattern)) ), "contracts_str": xml_contracts_tree[2].text, "key": int(service[1]), } }, upsert=True, ) else: g.mongo.db.caches.update( {"_id": service[0]}, { "$set": { "cached_until": int( calendar.timegm(time.strptime(xml_contracts_tree[2].text, xml_time_pattern)) ), "cached_str": xml_contracts_tree[2].text, } }, upsert=True, ) if xml_contracts_tree[1].tag == "error": print(xml_contracts_tree[1].attrib["code"], xml_contracts_tree[1].text, service[1]) conversions.invalidate_key([service[1]], session["CharacterOwnerHash"]) invalid_apis.add(service[1]) else: for contract in xml_contracts_tree[1][0]: issue_time = int(calendar.timegm(time.strptime(contract.attrib["dateIssued"], xml_time_pattern))) if issue_time > filter_time: bulk_run = True bulk_op.find( {"_id.id": int(contract.attrib["contractID"]), "_id.service": service[0]} ).upsert().update( { "$set": { "issuer_id": int(contract.attrib["issuerID"]), "assignee_id": int(contract.attrib["assigneeID"]), "acceptor_id": int(contract.attrib["acceptorID"]), "start_station_id": int(contract.attrib["startStationID"]), "end_station_id": int(contract.attrib["endStationID"]), "type": contract.attrib["type"], "status": contract.attrib["status"], "title": contract.attrib["title"], "for_corp": int(contract.attrib["forCorp"]), "date_issued": contract.attrib["dateIssued"], "date_expired": contract.attrib["dateExpired"], "date_accepted": contract.attrib["dateAccepted"], "num_days": int(contract.attrib["numDays"]), "date_completed": contract.attrib["dateCompleted"], "price": float(contract.attrib["price"]), "reward": float(contract.attrib["reward"]), "collateral": float(contract.attrib["collateral"]), "volume": float(contract.attrib["volume"]), "issued_int": issue_time, } } ) if bulk_run: try: bulk_op.execute() except BulkWriteError as bulk_op_error: print("error", bulk_op_error.details) return list(invalid_apis)