def refresh_character_skills(character_id, recurring=14400): character = session.query(CharacterModel).filter( CharacterModel.id == character_id).one() job_log.debug("user.refresh_character_skills {}".format( character.character_name)) try: skills = esi_characters.skills(character.character_id, access_token=character.access_token) except InvalidToken: refresh_access_token(character) skills = esi_characters.skills(character.character_id, access_token=character.access_token) if "skills" in skills: skills = skills["skills"] for skill in skills: skill_id = skill["skill_id"] eveskill = EVESkillModel.from_id(skill_id) session.add(eveskill) skill_level = skill["current_skill_level"] skill_points = skill["skillpoints_in_skill"] characterskill = session.query(CharacterSkillModel).filter( CharacterSkillModel.character_id == character.id, CharacterSkillModel.eve_skill_id == eveskill.id).one_or_none() if characterskill is None: characterskill = CharacterSkillModel(character) characterskill.eve_skill = eveskill # XXX notify change? characterskill.level = skill_level characterskill.points = skill_points session.add(characterskill) session.commit() if recurring: refresh_character_corporation.apply_async(args=(character_id, recurring), countdown=recurring)
def setup(): job_log.info("group.setup") tornado.ioloop.IOLoop.current().run_sync(slack.refresh_user_email_to_ids) for group in session.query(GroupModel).all(): setup_group(group)
async def get(self): # XXX very naive query = self.get_argument("query", None) if not query: return self.write({"status": "success", "result": []}) characters = session.query(CharacterModel).order_by( CharacterModel.character_name).all() characters = [ character for character in characters if character.last_ship ] ships = set(character.last_ship.eve_type for character in characters if character.last_ship.eve_type.eve_name.startswith(query)) return self.write({ "status": "success", "result": [{ "ship_id": ship.id, "ship_name": ship.eve_name } for ship in ships] })
async def get(self): characters = list(session.query(CharacterModel).all()) users = list(session.query(UserModel).all()) memberships = list(session.query(MembershipModel).all()) glance_total = len(characters) glance_internal = len( [character for character in characters if character.is_internal]) glance_user = len([user for user in users if user.is_internal]) glance_membership = len( [membership for membership in memberships if membership.pending]) return self.render("admin.html", glance_total=glance_total, glance_internal=glance_internal, glance_user=glance_user, glance_membership=glance_membership)
def refresh_character_corporation(self, character_id, recurring=3600): try: character = session.query(CharacterModel).filter( CharacterModel.id == character_id).one() job_log.debug("user.refresh_character_corporation {}".format( character.character_name)) corporation_id = esi_characters.detail(character.character_id) if corporation_id is not None: corporation_id = corporation_id["corporation_id"] corporation = EVECorporationModel.from_id(corporation_id) if not len(character.corporation_history): # This character has no corp history at all session_entry = CharacterCorporationHistory( character, corporation) session_entry.join_date = datetime.now( ) # XXX fetch this from the actual join date? session.add(session_entry) session.commit() elif len( character.corporation_history ) and character.corporation_history[-1].corporation is corporation: # Character is still in the same corporation as the last time we checked, we need to do nothing pass elif len(character.corporation_history ) and character.corporation_history[ -1].corporation is not corporation: # Character changed corporation, close the last one and create a new one previously = character.corporation_history[-1] previously.exit_date = datetime.now() currently = CharacterCorporationHistory(character, corporation) currently.join_date = datetime.now() session.add(currently) session.add(previously) session.commit() eve_log.warn("{} changed corporations {} -> {}".format( character, previously.corporation, currently.corporation)) if recurring: refresh_character_corporation.apply_async(args=(character_id, recurring), countdown=recurring) except requests.exceptions.ConnectionError as e: self.retry(exc=e)
def refresh_character_ship(self, character_id, recurring=60): """Refresh a characters current ship.""" try: character = session.query(CharacterModel).filter( CharacterModel.id == character_id).one() job_log.debug("user.refresh_character_ship {}".format( character.character_name)) try: type_id = esi_characters.ship(character.character_id, access_token=character.access_token) except (InvalidToken, ExpiredToken): try: refresh_access_token(character) type_id = esi_characters.ship( character.character_id, access_token=character.access_token) except: return job_log.warn( "removing user.refresh_character_ship {}".format( character.character_name)) if type_id is not None: item_id = type_id["ship_item_id"] type_id = type_id["ship_type_id"] eve_type = EVETypeModel.from_id(type_id) if len(character.ship_history ) and character.ship_history[-1].eve_type == eve_type: # backoff if recurring <= 600: recurring = recurring + 60 else: recurring = 60 eve_log.warn("{} boarded {}".format(character.character_name, eve_type.eve_name)) history_entry = CharacterShipHistory(character, eve_type) history_entry.eve_item_id = item_id session.add(history_entry) session.commit() if recurring: refresh_character_ship.apply_async(args=(character_id, recurring), countdown=recurring) except requests.exceptions.ConnectionError as e: self.retry(exc=e)
def refresh_group_slack(self, group_id, recurring=300): """Refresh a group's slack channel.""" try: group = session.query(GroupModel).filter( GroupModel.id == group_id).one() tornado.ioloop.IOLoop.current().run_sync( lambda: slack.group_upkeep(group)) if recurring: refresh_group_slack.apply_async(args=(group_id, recurring), countdown=recurring) except Exception as e: self.retry(exc=e)
def refresh_character_location(self, character_id, recurring=30): """Refresh a characters current location.""" try: character = session.query(CharacterModel).filter( CharacterModel.id == character_id).one() job_log.debug("user.refresh_character_location {}".format( character.character_name)) try: system_id = esi_characters.location( character.character_id, access_token=character.access_token) except (InvalidToken, ExpiredToken): try: refresh_access_token(character) system_id = esi_characters.location( character.character_id, access_token=character.access_token) except: return job_log.warn( "removing user.refresh_character_ship {}".format( character.character_name)) if system_id is not None: system_id = system_id["solar_system_id"] system = EVESolarSystemModel.from_id(system_id) if len(character.location_history ) and system.id == character.location_history[-1].system_id: # backoff if recurring < 300: recurring = recurring + 30 else: recurring = 30 history_entry = CharacterLocationHistory(character, system) eve_log.warn("{} moved to {}".format(character.character_name, system.eve_name)) session.add(history_entry) session.commit() if recurring: refresh_character_location.apply_async(args=(character_id, recurring), countdown=recurring) except requests.exceptions.ConnectionError as e: self.retry(exc=e)
async def get(self): # FIXME all of this is very naive and slow for large numbers of # characters, move most of the filtering to the database and paginate # the result set characters = session.query(CharacterModel).order_by( CharacterModel.character_name).all() filter_ship = self.get_argument("ship", None) filter_system = self.get_argument("system", None) filter_main = self.get_argument("main", None) if filter_ship: filter_ship = filter_ship.split("|") characters = [ character for character in characters if character.last_ship ] characters = [ character for character in characters if character.last_ship.eve_type.eve_name in filter_ship ] if filter_system: filter_system = filter_system.split("|") characters = [ character for character in characters if character.last_location ] characters = [ character for character in characters if character.last_location.system.eve_name in filter_system ] if filter_main: filter_main = filter_main.split("|") characters = [ character for character in characters if character.user.main_character.character_name ] characters = [ character for character in characters if character.user.main_character.character_name in filter_main ] return self.render("admin_characters.html", characters=characters)
def refresh_group_members(group_id, recurring=60): """Refresh a group and kick any members that are not internal.""" group = session.query(GroupModel).filter(GroupModel.id == group_id).one() job_log.debug("group.refresh_group_members {}".format(group)) for membership in group.memberships: if not membership.user.is_internal: job_log.warn( "group.refresh_group_members removing {} from {} no_internal". format(membership.user, group)) session.delete(membership) session.commit() if recurring: refresh_group_members.apply_async(args=(group_id, recurring), countdown=recurring)
async def _add(self): character_id, character_scopes, access_token, refresh_token, account_hash = await self._sso_response( ) # See if we already have this character character = session.query(CharacterModel).filter( CharacterModel.character_id == character_id).first() if character: # XXX add new scopes if character.user == self.current_user: character.access_token = access_token character.refresh_token = refresh_token character.account_hash = account_hash # For our scopes we see if they already exist, if they # don't we create them and hang them on the character character.update_scopes(character_scopes) else: sec_log.warn( "user {} tried to add {} but belongs to {}".format( self.current_user, character, character.user)) raise tornado.web.HTTPError(403) else: character = await self._create(character_id, character_scopes, access_token, refresh_token, account_hash) # Append the character to the currently logged in character self.current_user.characters.append(character) self.current_user.chg_date = datetime.now() session.add(self.current_user) session.commit() sec_log.info("added %s for %s" % (character, character.user)) queue_user.setup_character(character) self.flash_success( self.locale.translate("CHARACTER_ADD_SUCCESS_ALERT")) self.redirect("/characters")
def model_by_id(self, model, argument): """Fetch a model instance by its primary key from the arguments. We also verify if the current user is the owner of the model. XXX""" # XXX verify current owner of the model (if it has a relationship with user) model_id = self.get_argument(argument, None) if not model_id: raise tornado.web.HTTPError(404) instance = session.query(model).filter(model.id == model_id).first() if not instance: raise tornado.web.HTTPError(404) if hasattr(instance, "user"): if not instance.user == self.current_user and not self.current_user.is_admin: raise tornado.web.HTTPError(403) return instance
def get_current_user(self): cookie = self.get_secure_cookie("user_id") if cookie: user_id = int(self.get_secure_cookie("user_id")) else: return None user = session.query(UserModel).filter(UserModel.id == user_id).first() if not user: # This was a cookie for a non-existing user app_log.warn( "Cookie with id:{} was used to try to login but no user by that id" .format(user_id)) self.clear_cookie("user_id") return self.redirect("/") return user
async def get(self): # XXX naive query = self.get_argument("query", None) if not query: return self.write({"status": "success", "result": []}) systems = session.query(EVESolarSystemModel).all() systems = [ system for system in systems if system.eve_name.startswith(query) ] return self.write({ "status": "success", "result": [{ "system_id": system.id, "system_name": system.eve_name } for system in systems] })
async def post(self): fit = self.get_argument("fit") items = parse_fit(fit) required_skills = dict() for item in items: for r in skills_item(item): required_skills[r[2]] = r[4] characters = {} character_models = session.query(CharacterModel).all() total = 0 for character_model in character_models: if not character_model.is_internal: continue total += 1 for character_skill in character_model.skills: if not character_skill.eve_skill.eve_id in required_skills.keys( ): continue if character_skill.level >= required_skills[ character_skill.eve_skill.eve_id]: characters[character_model] = characters.get( character_model, []) characters[character_model].append(True) can_fly = 0 for character in characters: if len(characters[character]) == len(required_skills): can_fly += 1 return self.render("fc_fits_result.html", can_fly=can_fly, total=total, fit=fit)
def refresh_character_ship(character_id, recurring=60): """Refresh a characters current ship.""" character = session.query(CharacterModel).filter( CharacterModel.id == character_id).one() job_log.debug("user.refresh_character_ship {}".format( character.character_name)) try: type_id = esi_characters.ship(character.character_id, access_token=character.access_token) except InvalidToken: refresh_access_token(character) type_id = esi_characters.ship(character.character_id, access_token=character.access_token) if type_id is not None: item_id = type_id["ship_item_id"] type_id = type_id["ship_type_id"] eve_type = EVETypeModel.from_id(type_id) if len(character.ship_history ) and character.ship_history[-1].eve_type == eve_type: pass else: eve_log.info("{} boarded {}".format(character.character_name, eve_type.eve_name)) history_entry = CharacterShipHistory(character, eve_type) history_entry.eve_item_id = item_id session.add(history_entry) session.commit() if recurring: refresh_character_ship.apply_async(args=(character_id, recurring), countdown=recurring)
async def get(self): # XXX naive query = self.get_argument("query", None) if not query: return self.write({"status": "success", "result": []}) characters = session.query(CharacterModel).order_by( CharacterModel.character_name).all() characters = [ character for character in characters if character.character_name.startswith(query) ] return self.write({ "status": "success", "result": [{ "character_id": character.id, "character_name": character.character_name } for character in characters] })
def refresh_character_location(character_id, recurring=30): """Refresh a characters current location.""" character = session.query(CharacterModel).filter( CharacterModel.id == character_id).one() job_log.debug("user.refresh_character_location {}".format( character.character_name)) try: system_id = esi_characters.location( character.character_id, access_token=character.access_token) except InvalidToken: refresh_access_token(character) system_id = esi_characters.location( character.character_id, access_token=character.access_token) if system_id is not None: system_id = system_id["solar_system_id"] system = EVESolarSystemModel.from_id(system_id) if len(character.location_history ) and system.id is character.location_history[-1].system_id: # don't update location history if the user is still in the same system pass else: history_entry = CharacterLocationHistory(character, system) eve_log.info("{} moved to {}".format(character.character_name, system.eve_name)) session.add(history_entry) session.commit() if recurring: refresh_character_location.apply_async(args=(character_id, recurring), countdown=recurring)
async def get(self): users = session.query(UserModel).all() users = sorted(users, key=lambda x: x.main_character.character_name) return self.render("admin_users.html", users=users)
async def get(self): groups = session.query(GroupModel).all() return self.render("admin_groups.html", groups=groups)
async def get(self): characters = session.query(CharacterModel).order_by( CharacterModel.character_name).all() return self.render("admin_characters.html", characters=characters)
async def get(self): users = session.query(UserModel).all() return self.render("admin_users.html", users=users)
def refresh_character_skills(self, character_id, recurring=14400): try: character = session.query(CharacterModel).filter( CharacterModel.id == character_id).one() job_log.debug("user.refresh_character_skills {}".format( character.character_name)) try: skills = esi_characters.skills(character.character_id, access_token=character.access_token) except (InvalidToken, ExpiredToken): try: refresh_access_token(character) skills = esi_characters.skills( character.character_id, access_token=character.access_token) except: return job_log.warn( "removing user.refresh_character_ship {}".format( character.character_name)) if skills and "skills" in skills: # XXX why can skills be None here? skills = skills["skills"] for skill in skills: skill_id = skill["skill_id"] eveskill = EVESkillModel.from_id(skill_id) session.add(eveskill) session.commit() skill_level = skill["current_skill_level"] skill_points = skill["skillpoints_in_skill"] characterskills = session.query(CharacterSkillModel).filter( CharacterSkillModel.character_id == character.id).filter( CharacterSkillModel.eve_skill_id == eveskill.id).all() # XXX why? for characterskill in characterskills: session.delete(characterskill) session.commit() characterskill = CharacterSkillModel(character) characterskill.eve_skill = eveskill characterskill.level = skill_level characterskill.points = skill_points session.add(characterskill) session.commit() if recurring: refresh_character_skills.apply_async(args=(character_id, recurring), countdown=recurring) except requests.exceptions.ConnectionError as e: self.retry(exc=e)
async def _login(self): character_id, character_scopes, access_token, refresh_token, account_hash = await self._sso_response( ) # See if we already have this character character = session.query(CharacterModel).filter( CharacterModel.character_id == character_id).first() # The character already exists so we log in to the corresponding user # and redirect to the success page if character: if character.account_hash != account_hash: sec_log.critical( "account hash for {} changed denying login".format( character)) raise tornado.web.HTTPError(400) sec_log.info("logged in {} through {}".format( character.user, character)) self.set_current_user(character.user) login = UserLoginModel() login.user = character.user login.pub_date = datetime.now() login.ip_address = self.request.remote_ip session.add(login) session.commit() return self.redirect("/login/success") else: # We don't have an account with this character on it yet. Let's # fetch the character information from the XML API and fill it # into a model, tie it up to a fresh new user and log it in character = await self._create(character_id, character_scopes, access_token, refresh_token, account_hash) character.is_main = True character.pub_date = datetime.now() user = UserModel() user.characters.append(character) user.pub_date = datetime.now() user.chg_date = datetime.now() session.add(user) session.commit() self.set_current_user(user) sec_log.info("created %s through %s" % (character.user, character)) login = UserLoginModel() login.user = character.user login.pub_date = datetime.now() login.ip_address = self.request.remote_ip session.add(login) session.commit() queue_user.setup_character(character) # Redirect to another page with some more information for the # user of what is going on return self.redirect("/login/created")
def setup(): job_log.info("user.setup") for user in session.query(UserModel).all(): setup_user(user)