How to use is_matching method in pytest-bdd

Best Python code snippet using pytest-bdd_python

models.py

Source:models.py Github

copy

Full Screen

1import json2from copy import deepcopy3from datetime import timedelta4from typing import List, Optional5from urllib.parse import urljoin6import dhooks_lite7from requests.exceptions import HTTPError8from simple_mq import SimpleMQ9from django.contrib.auth.models import Group, User10from django.contrib.staticfiles.storage import staticfiles_storage11from django.core.cache import cache12from django.db import models13from django.utils.timezone import now14from django.utils.translation import gettext_lazy as _15from eveuniverse.helpers import EveEntityNameResolver, meters_to_ly16from eveuniverse.models import (17 EveConstellation,18 EveEntity,19 EveGroup,20 EveRegion,21 EveSolarSystem,22 EveType,23)24from allianceauth.authentication.models import State25from allianceauth.eveonline.evelinks import dotlan, eveimageserver, zkillboard26from allianceauth.eveonline.models import EveAllianceInfo, EveCorporationInfo27from allianceauth.services.hooks import get_extension_logger28from allianceauth.services.modules.discord.models import DiscordUser29from app_utils.django import app_labels30from app_utils.json import JSONDateTimeDecoder, JSONDateTimeEncoder31from app_utils.logging import LoggerAddTag32from app_utils.urls import site_absolute_url33from app_utils.views import humanize_value34from . import APP_NAME, HOMEPAGE_URL, __title__, __version__35from .app_settings import (36 KILLTRACKER_KILLMAIL_MAX_AGE_FOR_TRACKER,37 KILLTRACKER_WEBHOOK_SET_AVATAR,38)39from .core.killmails import ZKB_KILLMAIL_BASEURL, EntityCount, Killmail, TrackerInfo40from .exceptions import WebhookTooManyRequests41from .managers import EveKillmailManager, TrackerManager, WebhookManager42logger = LoggerAddTag(get_extension_logger(__name__), __title__)43class EveKillmail(models.Model):44 id = models.BigIntegerField(primary_key=True)45 time = models.DateTimeField(default=None, null=True, blank=True, db_index=True)46 solar_system = models.ForeignKey(47 EveEntity, on_delete=models.CASCADE, default=None, null=True, blank=True48 )49 updated_at = models.DateTimeField(auto_now=True)50 objects = EveKillmailManager()51 def __str__(self):52 return f"ID:{self.id}"53 def __repr__(self):54 return f"{type(self).__name__}(id={self.id})"55 def load_entities(self):56 """loads unknown entities for this killmail"""57 qs = EveEntity.objects.filter(id__in=self.entity_ids(), name="")58 qs.update_from_esi()59 def entity_ids(self) -> List[int]:60 ids = [61 self.victim.character_id,62 self.victim.corporation_id,63 self.victim.alliance_id,64 self.victim.ship_type_id,65 self.solar_system_id,66 ]67 for attacker in self.attackers.all():68 ids += [69 attacker.character_id,70 attacker.corporation_id,71 attacker.alliance_id,72 attacker.ship_type_id,73 attacker.weapon_type_id,74 ]75 return [int(x) for x in ids if x is not None]76class EveKillmailCharacter(models.Model):77 character = models.ForeignKey(78 EveEntity,79 on_delete=models.CASCADE,80 default=None,81 null=True,82 blank=True,83 related_name="+",84 )85 corporation = models.ForeignKey(86 EveEntity,87 on_delete=models.CASCADE,88 default=None,89 null=True,90 blank=True,91 related_name="+",92 )93 alliance = models.ForeignKey(94 EveEntity,95 on_delete=models.CASCADE,96 default=None,97 null=True,98 blank=True,99 related_name="+",100 )101 faction = models.ForeignKey(102 EveEntity,103 on_delete=models.CASCADE,104 default=None,105 null=True,106 blank=True,107 related_name="+",108 )109 ship_type = models.ForeignKey(110 EveEntity,111 on_delete=models.CASCADE,112 default=None,113 null=True,114 blank=True,115 related_name="+",116 )117 class Meta:118 abstract = True119 def __str__(self) -> str:120 if self.character:121 return str(self.character)122 elif self.corporation:123 return str(self.corporation)124 elif self.alliance:125 return str(self.alliance)126 elif self.faction:127 return str(self.faction)128 else:129 return f"PK:{self.pk}"130class EveKillmailVictim(EveKillmailCharacter):131 killmail = models.OneToOneField(132 EveKillmail, primary_key=True, on_delete=models.CASCADE, related_name="victim"133 )134 damage_taken = models.BigIntegerField(default=None, null=True, blank=True)135class EveKillmailAttacker(EveKillmailCharacter):136 killmail = models.ForeignKey(137 EveKillmail, on_delete=models.CASCADE, related_name="attackers"138 )139 damage_done = models.BigIntegerField(default=None, null=True, blank=True)140 is_final_blow = models.BooleanField(141 default=None, null=True, blank=True, db_index=True142 )143 security_status = models.FloatField(default=None, null=True, blank=True)144 weapon_type = models.ForeignKey(145 EveEntity,146 on_delete=models.CASCADE,147 default=None,148 null=True,149 blank=True,150 related_name="+",151 )152class EveKillmailPosition(models.Model):153 killmail = models.OneToOneField(154 EveKillmail, primary_key=True, on_delete=models.CASCADE, related_name="position"155 )156 x = models.FloatField(default=None, null=True, blank=True)157 y = models.FloatField(default=None, null=True, blank=True)158 z = models.FloatField(default=None, null=True, blank=True)159class EveKillmailZkb(models.Model):160 killmail = models.OneToOneField(161 EveKillmail, primary_key=True, on_delete=models.CASCADE, related_name="zkb"162 )163 location_id = models.PositiveIntegerField(164 default=None, null=True, blank=True, db_index=True165 )166 hash = models.CharField(max_length=64, default="", blank=True)167 fitted_value = models.FloatField(default=None, null=True, blank=True)168 total_value = models.FloatField(default=None, null=True, blank=True, db_index=True)169 points = models.PositiveIntegerField(170 default=None, null=True, blank=True, db_index=True171 )172 is_npc = models.BooleanField(default=None, null=True, blank=True, db_index=True)173 is_solo = models.BooleanField(default=None, null=True, blank=True, db_index=True)174 is_awox = models.BooleanField(default=None, null=True, blank=True, db_index=True)175class Webhook(models.Model):176 """A webhook to receive messages"""177 HTTP_TOO_MANY_REQUESTS = 429178 class WebhookType(models.IntegerChoices):179 DISCORD = 1, _("Discord Webhook")180 name = models.CharField(181 max_length=64, unique=True, help_text="short name to identify this webhook"182 )183 webhook_type = models.IntegerField(184 choices=WebhookType.choices,185 default=WebhookType.DISCORD,186 help_text="type of this webhook",187 )188 url = models.CharField(189 max_length=255,190 unique=True,191 help_text=(192 "URL of this webhook, e.g. "193 "https://discordapp.com/api/webhooks/123456/abcdef"194 ),195 )196 notes = models.TextField(197 blank=True,198 help_text="you can add notes about this webhook here if you want",199 )200 is_enabled = models.BooleanField(201 default=True,202 db_index=True,203 help_text="whether notifications are currently sent to this webhook",204 )205 objects = WebhookManager()206 def __init__(self, *args, **kwargs) -> None:207 super().__init__(*args, **kwargs)208 self.main_queue = self._create_queue("main")209 self.error_queue = self._create_queue("error")210 def __str__(self) -> str:211 return self.name212 def __repr__(self) -> str:213 return "{}(id={}, name='{}')".format(214 self.__class__.__name__, self.id, self.name215 )216 def __getstate__(self):217 # Copy the object's state from self.__dict__ which contains218 # all our instance attributes. Always use the dict.copy()219 # method to avoid modifying the original state.220 state = self.__dict__.copy()221 # Remove the unpicklable entries.222 del state["main_queue"]223 del state["error_queue"]224 return state225 def __setstate__(self, state):226 # Restore instance attributes (i.e., filename and lineno).227 self.__dict__.update(state)228 # Restore the previously opened file's state. To do so, we need to229 # reopen it and read from it until the line count is restored.230 self.main_queue = self._create_queue("main")231 self.error_queue = self._create_queue("error")232 def save(self, *args, **kwargs):233 is_new = self.id is None234 super().save(*args, **kwargs)235 if is_new:236 self.main_queue = self._create_queue("main")237 self.error_queue = self._create_queue("error")238 def _create_queue(self, suffix: str) -> Optional[SimpleMQ]:239 return (240 SimpleMQ(241 cache.get_master_client(), f"{__title__}_webhook_{self.pk}_{suffix}"242 )243 if self.pk244 else None245 )246 def reset_failed_messages(self) -> int:247 """moves all messages from error queue into main queue.248 returns number of moved messages.249 """250 counter = 0251 while True:252 message = self.error_queue.dequeue()253 if message is None:254 break255 else:256 self.main_queue.enqueue(message)257 counter += 1258 return counter259 def enqueue_message(260 self,261 content: str = None,262 embeds: List[dhooks_lite.Embed] = None,263 tts: bool = None,264 username: str = None,265 avatar_url: str = None,266 ) -> int:267 """Enqueues a message to be send with this webhook"""268 username = __title__ if KILLTRACKER_WEBHOOK_SET_AVATAR else username269 brand_url = urljoin(270 site_absolute_url(),271 staticfiles_storage.url("killtracker/killtracker_logo.png"),272 )273 avatar_url = brand_url if KILLTRACKER_WEBHOOK_SET_AVATAR else avatar_url274 return self.main_queue.enqueue(275 self._discord_message_asjson(276 content=content,277 embeds=embeds,278 tts=tts,279 username=username,280 avatar_url=avatar_url,281 )282 )283 @staticmethod284 def _discord_message_asjson(285 content: str = None,286 embeds: List[dhooks_lite.Embed] = None,287 tts: bool = None,288 username: str = None,289 avatar_url: str = None,290 ) -> str:291 """Converts a Discord message to JSON and returns it292 Raises ValueError if mesage is incomplete293 """294 if not content and not embeds:295 raise ValueError("Message must have content or embeds to be valid")296 if embeds:297 embeds_list = [obj.asdict() for obj in embeds]298 else:299 embeds_list = None300 message = dict()301 if content:302 message["content"] = content303 if embeds_list:304 message["embeds"] = embeds_list305 if tts:306 message["tts"] = tts307 if username:308 message["username"] = username309 if avatar_url:310 message["avatar_url"] = avatar_url311 return json.dumps(message, cls=JSONDateTimeEncoder)312 def send_message_to_webhook(self, message_json: str) -> bool:313 """Send given message to webhook314 Params315 message_json: Discord message encoded in JSON316 """317 timeout = cache.ttl(self._blocked_cache_key())318 if timeout:319 raise WebhookTooManyRequests(timeout)320 message = json.loads(message_json, cls=JSONDateTimeDecoder)321 if message.get("embeds"):322 embeds = [323 dhooks_lite.Embed.from_dict(embed_dict)324 for embed_dict in message.get("embeds")325 ]326 else:327 embeds = None328 hook = dhooks_lite.Webhook(329 url=self.url,330 user_agent=dhooks_lite.UserAgent(331 name=APP_NAME, url=HOMEPAGE_URL, version=__version__332 ),333 )334 response = hook.execute(335 content=message.get("content"),336 embeds=embeds,337 username=message.get("username"),338 avatar_url=message.get("avatar_url"),339 wait_for_response=True,340 max_retries=0, # we will handle retries ourselves341 )342 logger.debug("headers: %s", response.headers)343 logger.debug("status_code: %s", response.status_code)344 logger.debug("content: %s", response.content)345 if response.status_code == self.HTTP_TOO_MANY_REQUESTS:346 logger.error(347 "%s: Received too many requests error from API: %s",348 self,349 response.content,350 )351 try:352 retry_after = int(response.content.get("retry_after")) + 2353 except (ValueError, TypeError):354 retry_after = WebhookTooManyRequests.DEFAULT_RESET_AFTER355 cache.set(356 key=self._blocked_cache_key(), value="BLOCKED", timeout=retry_after357 )358 raise WebhookTooManyRequests(retry_after)359 return response360 def _blocked_cache_key(self) -> str:361 return f"{__title__}_webhook_{self.pk}_blocked"362 @staticmethod363 def create_message_link(name: str, url: str) -> str:364 """Create link for a Discord message"""365 return f"[{str(name)}]({str(url)})"366class Tracker(models.Model):367 ICON_SIZE = 128368 MAIN_MINIMUM_COUNT = 2369 MAIN_MINIMUM_SHARE = 0.25370 class ChannelPingType(models.TextChoices):371 NONE = "PN", "(none)"372 HERE = "PH", "@here"373 EVERYBODY = "PE", "@everybody"374 name = models.CharField(375 max_length=100,376 help_text="name to identify tracker. Will be shown on alerts posts.",377 unique=True,378 )379 description = models.TextField(380 blank=True,381 help_text=(382 "Brief description what this tracker is for. Will not be shown on alerts."383 ),384 )385 color = models.CharField(386 max_length=7,387 default="",388 blank=True,389 help_text=(390 "Optional color for embed on Discord - #000000 / "391 "black means no color selected"392 ),393 )394 origin_solar_system = models.ForeignKey(395 EveSolarSystem,396 on_delete=models.SET_DEFAULT,397 default=None,398 null=True,399 blank=True,400 related_name="+",401 help_text=(402 "Solar system to calculate distance and jumps from. "403 "When provided distance and jumps will be shown on killmail messages"404 ),405 )406 require_max_jumps = models.PositiveIntegerField(407 default=None,408 null=True,409 blank=True,410 help_text=(411 "Require all killmails to be max x jumps away from origin solar system"412 ),413 )414 require_max_distance = models.FloatField(415 default=None,416 null=True,417 blank=True,418 help_text=(419 "Require all killmails to be max x LY away from origin solar system"420 ),421 )422 exclude_attacker_alliances = models.ManyToManyField(423 EveAllianceInfo,424 related_name="+",425 default=None,426 blank=True,427 help_text="exclude killmails with attackers from one of these alliances",428 )429 require_attacker_alliances = models.ManyToManyField(430 EveAllianceInfo,431 related_name="+",432 default=None,433 blank=True,434 help_text="only include killmails with attackers from one of these alliances",435 )436 exclude_attacker_corporations = models.ManyToManyField(437 EveCorporationInfo,438 related_name="+",439 default=None,440 blank=True,441 help_text="exclude killmails with attackers from one of these corporations",442 )443 require_attacker_corporations = models.ManyToManyField(444 EveCorporationInfo,445 related_name="+",446 default=None,447 blank=True,448 help_text="only include killmails with attackers from one of these corporations",449 )450 exclude_attacker_states = models.ManyToManyField(451 State,452 related_name="+",453 default=None,454 blank=True,455 help_text=(456 "exclude killmails with characters belonging "457 "to users with these Auth states"458 ),459 )460 require_attacker_states = models.ManyToManyField(461 State,462 related_name="+",463 default=None,464 blank=True,465 help_text=(466 "only include killmails with characters belonging "467 "to users with these Auth states"468 ),469 )470 require_victim_alliances = models.ManyToManyField(471 EveAllianceInfo,472 related_name="+",473 default=None,474 blank=True,475 help_text=(476 "only include killmails where the victim belongs to one of these alliances"477 ),478 )479 require_victim_corporations = models.ManyToManyField(480 EveCorporationInfo,481 related_name="+",482 default=None,483 blank=True,484 help_text=(485 "only include killmails where the victim belongs "486 "to one of these corporations"487 ),488 )489 require_victim_states = models.ManyToManyField(490 State,491 related_name="+",492 default=None,493 blank=True,494 help_text=(495 "only include killmails where the victim characters belong "496 "to users with these Auth states"497 ),498 )499 identify_fleets = models.BooleanField(500 default=False,501 help_text="when true: kills are interpreted and shown as fleet kills",502 )503 exclude_blue_attackers = models.BooleanField(504 default=False,505 help_text=("exclude killmails with blue attackers"),506 )507 require_blue_victim = models.BooleanField(508 default=False,509 help_text=(510 "only include killmails where the victim has standing with our group"511 ),512 )513 require_min_attackers = models.PositiveIntegerField(514 default=None,515 null=True,516 blank=True,517 help_text="Require killmails to have at least given number of attackers",518 )519 require_max_attackers = models.PositiveIntegerField(520 default=None,521 null=True,522 blank=True,523 help_text="Require killmails to have no more than max number of attackers",524 )525 exclude_high_sec = models.BooleanField(526 default=False,527 help_text=(528 "exclude killmails from high sec. "529 "Also exclude high sec systems in route finder for jumps from origin."530 ),531 )532 exclude_low_sec = models.BooleanField(533 default=False, help_text="exclude killmails from low sec"534 )535 exclude_null_sec = models.BooleanField(536 default=False, help_text="exclude killmails from null sec"537 )538 exclude_w_space = models.BooleanField(539 default=False, help_text="exclude killmails from WH space"540 )541 require_regions = models.ManyToManyField(542 EveRegion,543 default=None,544 blank=True,545 related_name="+",546 help_text=("Only include killmails that occurred in one of these regions"),547 )548 require_constellations = models.ManyToManyField(549 EveConstellation,550 default=None,551 blank=True,552 related_name="+",553 help_text=("Only include killmails that occurred in one of these regions"),554 )555 require_solar_systems = models.ManyToManyField(556 EveSolarSystem,557 default=None,558 blank=True,559 related_name="+",560 help_text=("Only include killmails that occurred in one of these regions"),561 )562 require_min_value = models.PositiveIntegerField(563 default=None,564 null=True,565 blank=True,566 help_text="Require killmail's value to be greater or equal to the given value in M ISK",567 )568 require_attackers_ship_groups = models.ManyToManyField(569 EveGroup,570 related_name="+",571 default=None,572 blank=True,573 help_text=(574 "Only include killmails where at least one attacker "575 "is flying one of these ship groups"576 ),577 )578 require_attackers_ship_types = models.ManyToManyField(579 EveType,580 related_name="+",581 default=None,582 blank=True,583 help_text=(584 "Only include killmails where at least one attacker "585 "is flying one of these ship types"586 ),587 )588 require_victim_ship_groups = models.ManyToManyField(589 EveGroup,590 related_name="+",591 default=None,592 blank=True,593 help_text=(594 "Only include killmails where victim is flying one of these ship groups"595 ),596 )597 require_victim_ship_types = models.ManyToManyField(598 EveType,599 related_name="+",600 default=None,601 blank=True,602 help_text=(603 "Only include killmails where victim is flying one of these ship types"604 ),605 )606 exclude_npc_kills = models.BooleanField(607 default=False, help_text="exclude npc kills"608 )609 require_npc_kills = models.BooleanField(610 default=False, help_text="only include killmails that are npc kills"611 )612 webhook = models.ForeignKey(613 Webhook,614 on_delete=models.CASCADE,615 help_text="Webhook URL for a channel on Discord to sent all alerts to",616 )617 ping_type = models.CharField(618 max_length=2,619 choices=ChannelPingType.choices,620 default=ChannelPingType.NONE,621 verbose_name="channel pings",622 help_text="Option to ping every member of the channel",623 )624 ping_groups = models.ManyToManyField(625 Group,626 default=None,627 blank=True,628 verbose_name="group pings",629 related_name="+",630 help_text="Option to ping specific group members - ",631 )632 is_posting_name = models.BooleanField(633 default=True, help_text="whether posted messages include the tracker's name"634 )635 is_enabled = models.BooleanField(636 default=True,637 db_index=True,638 help_text="toogle for activating or deactivating a tracker",639 )640 objects = TrackerManager()641 def __str__(self) -> str:642 return self.name643 def save(self, *args, **kwargs):644 if self.color == "#000000":645 self.color = ""646 super().save(*args, **kwargs)647 @property648 def has_localization_clause(self) -> bool:649 """returns True if tracker has a clause that needs the killmais's solar system"""650 return (651 self.exclude_high_sec652 or self.exclude_low_sec653 or self.exclude_null_sec654 or self.exclude_w_space655 or self.require_max_distance is not None656 or self.require_max_jumps is not None657 or self.require_regions.all()658 or self.require_constellations.all()659 or self.require_solar_systems.all()660 )661 @property662 def has_type_clause(self) -> bool:663 """returns True if tracker has a clause that needs a type from the killmail,664 e.g. the ship type of the victim665 """666 return (667 self.require_attackers_ship_groups.all()668 or self.require_attackers_ship_types.all()669 or self.require_victim_ship_groups.all()670 or self.require_victim_ship_types.all()671 )672 def process_killmail(673 self, killmail: Killmail, ignore_max_age: bool = False674 ) -> Optional[Killmail]:675 """runs tracker on given killmail676 returns new killmail amended with tracker info if killmail matches677 else returns None678 """679 threshold_date = now() - timedelta(680 minutes=KILLTRACKER_KILLMAIL_MAX_AGE_FOR_TRACKER681 )682 if not ignore_max_age and killmail.time < threshold_date:683 return False684 # pre-calculate shared information685 solar_system = None686 distance = None687 jumps = None688 is_high_sec = None689 is_low_sec = None690 is_null_sec = None691 is_w_space = None692 matching_ship_type_ids = None693 if killmail.solar_system_id and (694 self.origin_solar_system or self.has_localization_clause695 ):696 solar_system, _ = EveSolarSystem.objects.get_or_create_esi(697 id=killmail.solar_system_id698 )699 is_high_sec = solar_system.is_high_sec700 is_low_sec = solar_system.is_low_sec701 is_null_sec = solar_system.is_null_sec702 is_w_space = solar_system.is_w_space703 if self.origin_solar_system:704 distance = meters_to_ly(705 self.origin_solar_system.distance_to(solar_system)706 )707 jumps = self.origin_solar_system.jumps_to(solar_system)708 # Make sure all ship types are in the local database709 if self.has_type_clause:710 EveType.objects.bulk_get_or_create_esi(711 ids=killmail.ship_type_distinct_ids()712 )713 # apply filters714 is_matching = True715 try:716 if is_matching and self.exclude_high_sec:717 is_matching = not is_high_sec718 if is_matching and self.exclude_low_sec:719 is_matching = not is_low_sec720 if is_matching and self.exclude_null_sec:721 is_matching = not is_null_sec722 if is_matching and self.exclude_w_space:723 is_matching = not is_w_space724 if is_matching and self.require_min_attackers:725 is_matching = len(killmail.attackers) >= self.require_min_attackers726 if is_matching and self.require_max_attackers:727 is_matching = len(killmail.attackers) <= self.require_max_attackers728 if is_matching and self.exclude_npc_kills:729 is_matching = not killmail.zkb.is_npc730 if is_matching and self.require_npc_kills:731 is_matching = killmail.zkb.is_npc732 if is_matching and self.require_min_value:733 is_matching = (734 killmail.zkb.total_value >= self.require_min_value * 1000000735 )736 if is_matching and self.require_max_distance:737 is_matching = distance is not None and (738 distance <= self.require_max_distance739 )740 if is_matching and self.require_max_jumps:741 is_matching = jumps is not None and (jumps <= self.require_max_jumps)742 if is_matching and self.require_regions.exists():743 is_matching = (744 solar_system745 and self.require_regions.filter(746 id=solar_system.eve_constellation.eve_region_id747 ).exists()748 )749 if is_matching and self.require_constellations.exists():750 is_matching = (751 solar_system752 and self.require_constellations.filter(753 id=solar_system.eve_constellation_id754 ).exists()755 )756 if is_matching and self.require_solar_systems.exists():757 is_matching = (758 solar_system759 and self.require_solar_systems.filter(id=solar_system.id).exists()760 )761 if is_matching and self.exclude_attacker_alliances.exists():762 is_matching = self.exclude_attacker_alliances.exclude(763 alliance_id__in=killmail.attackers_distinct_alliance_ids()764 ).exists()765 if is_matching and self.require_attacker_alliances.exists():766 is_matching = self.require_attacker_alliances.filter(767 alliance_id__in=killmail.attackers_distinct_alliance_ids()768 ).exists()769 if is_matching and self.exclude_attacker_corporations.exists():770 is_matching = self.exclude_attacker_corporations.exclude(771 corporation_id__in=killmail.attackers_distinct_corporation_ids()772 ).exists()773 if is_matching and self.require_attacker_corporations.exists():774 is_matching = self.require_attacker_corporations.filter(775 corporation_id__in=killmail.attackers_distinct_corporation_ids()776 ).exists()777 if is_matching and self.require_victim_alliances.exists():778 is_matching = self.require_victim_alliances.filter(779 alliance_id=killmail.victim.alliance_id780 ).exists()781 if is_matching and self.require_victim_corporations.exists():782 is_matching = self.require_victim_corporations.filter(783 corporation_id=killmail.victim.corporation_id784 ).exists()785 if is_matching and self.require_attacker_states.exists():786 is_matching = User.objects.filter(787 profile__state__in=list(self.require_attacker_states.all()),788 character_ownerships__character__character_id__in=(789 killmail.attackers_distinct_character_ids()790 ),791 ).exists()792 if is_matching and self.exclude_attacker_states.exists():793 is_matching = not User.objects.filter(794 profile__state__in=list(self.exclude_attacker_states.all()),795 character_ownerships__character__character_id__in=(796 killmail.attackers_distinct_character_ids()797 ),798 ).exists()799 if is_matching and self.require_victim_states.exists():800 is_matching = User.objects.filter(801 profile__state__in=list(self.require_victim_states.all()),802 character_ownerships__character__character_id=(803 killmail.victim.character_id804 ),805 ).exists()806 if is_matching and self.require_victim_ship_groups.exists():807 ship_types_matching_qs = EveType.objects.filter(808 eve_group_id__in=list(809 self.require_victim_ship_groups.values_list("id", flat=True)810 ),811 id=killmail.victim.ship_type_id,812 )813 is_matching = ship_types_matching_qs.exists()814 if is_matching:815 matching_ship_type_ids = list(816 ship_types_matching_qs.values_list("id", flat=True)817 )818 if is_matching and self.require_victim_ship_types.exists():819 ship_types_matching_qs = EveType.objects.filter(820 id__in=list(821 self.require_victim_ship_types.values_list("id", flat=True)822 ),823 id=killmail.victim.ship_type_id,824 )825 is_matching = ship_types_matching_qs.exists()826 if is_matching:827 matching_ship_type_ids = list(828 ship_types_matching_qs.values_list("id", flat=True)829 )830 if is_matching and self.require_attackers_ship_groups.exists():831 ship_types_matching_qs = EveType.objects.filter(832 id__in=set(killmail.attackers_ship_type_ids())833 ).filter(834 eve_group_id__in=list(835 self.require_attackers_ship_groups.values_list("id", flat=True)836 )837 )838 is_matching = ship_types_matching_qs.exists()839 if is_matching:840 matching_ship_type_ids = list(841 ship_types_matching_qs.values_list("id", flat=True)842 )843 if is_matching and self.require_attackers_ship_types.exists():844 ship_types_matching_qs = EveType.objects.filter(845 id__in=set(killmail.attackers_ship_type_ids())846 ).filter(847 id__in=list(848 self.require_attackers_ship_types.values_list("id", flat=True)849 )850 )851 is_matching = ship_types_matching_qs.exists()852 if is_matching:853 matching_ship_type_ids = list(854 ship_types_matching_qs.values_list("id", flat=True)855 )856 except AttributeError:857 is_matching = False858 if is_matching:859 killmail_new = deepcopy(killmail)860 killmail_new.tracker_info = TrackerInfo(861 tracker_pk=self.pk,862 jumps=jumps,863 distance=distance,864 main_org=self._killmail_main_attacker_org(killmail),865 main_ship_group=self._killmail_main_attacker_ship_group(killmail),866 matching_ship_type_ids=matching_ship_type_ids,867 )868 return killmail_new869 else:870 return None871 @classmethod872 def _killmail_main_attacker_org(cls, killmail) -> Optional[EntityCount]:873 """returns the main attacker group with count"""874 org_items = []875 for attacker in killmail.attackers:876 if attacker.alliance_id:877 org_items.append(878 EntityCount(879 id=attacker.alliance_id, category=EntityCount.CATEGORY_ALLIANCE880 )881 )882 if attacker.corporation_id:883 org_items.append(884 EntityCount(885 id=attacker.corporation_id,886 category=EntityCount.CATEGORY_CORPORATION,887 )888 )889 if org_items:890 org_items_2 = [891 EntityCount(id=x.id, category=x.category, count=org_items.count(x))892 for x in set(org_items)893 ]894 max_count = max([x.count for x in org_items_2])895 treshold = max(896 len(killmail.attackers) * cls.MAIN_MINIMUM_SHARE,897 cls.MAIN_MINIMUM_COUNT,898 )899 if max_count >= treshold:900 org_items_3 = [x for x in org_items_2 if x.count == max_count]901 if len(org_items_3) > 1:902 org_items_4 = [x for x in org_items_3 if x.is_alliance]903 if len(org_items_4) > 0:904 return org_items_4[0]905 return org_items_3[0]906 return None907 @classmethod908 def _killmail_main_attacker_ship_group(909 cls, killmail: Killmail910 ) -> Optional[EntityCount]:911 """returns the main attacker group with count"""912 ships_type_ids = killmail.attackers_ship_type_ids()913 ship_types = EveType.objects.filter(id__in=ships_type_ids).select_related(914 "eve_group"915 )916 ship_groups = list()917 for ships_type_id in ships_type_ids:918 try:919 ship_type = ship_types.get(id=ships_type_id)920 except EveType.DoesNotExist:921 continue922 ship_groups.append(923 EntityCount(924 id=ship_type.eve_group_id,925 category=EntityCount.CATEGORY_INVENTORY_GROUP,926 name=ship_type.eve_group.name,927 )928 )929 if ship_groups:930 ship_groups_2 = [931 EntityCount(932 id=x.id,933 category=x.category,934 name=x.name,935 count=ship_groups.count(x),936 )937 for x in set(ship_groups)938 ]939 max_count = max([x.count for x in ship_groups_2])940 treshold = max(941 len(killmail.attackers) * cls.MAIN_MINIMUM_SHARE,942 cls.MAIN_MINIMUM_COUNT,943 )944 if max_count >= treshold:945 return sorted(ship_groups_2, key=lambda x: x.count).pop()946 return None947 def generate_killmail_message(948 self, killmail: Killmail, intro_text: str = None949 ) -> int:950 """generate a message from given killmail and enqueue for later sending951 returns new queue size952 """953 embed = self._create_embed(killmail)954 content = self._create_content(intro_text)955 return self.webhook.enqueue_message(content=content, embeds=[embed])956 def _create_embed(self, killmail: Killmail) -> dhooks_lite.Embed:957 resolver = EveEntity.objects.bulk_resolve_names(ids=killmail.entity_ids())958 # victim959 if killmail.victim.alliance_id:960 victim_organization = EveEntity.objects.get(id=killmail.victim.alliance_id)961 victim_org_url = zkillboard.alliance_url(killmail.victim.alliance_id)962 elif killmail.victim.corporation_id:963 victim_organization = EveEntity.objects.get(964 id=killmail.victim.corporation_id965 )966 victim_org_url = zkillboard.corporation_url(killmail.victim.corporation_id)967 else:968 victim_organization = None969 victim_org_url = None970 if killmail.victim.corporation_id:971 victim_corporation_zkb_link = self._corporation_zkb_link(972 killmail.victim.corporation_id, resolver973 )974 else:975 victim_corporation_zkb_link = ""976 if killmail.victim.character_id:977 victim_character_zkb_link = self._character_zkb_link(978 killmail.victim.character_id,979 resolver,980 )981 victim_str = f"{victim_character_zkb_link} ({victim_corporation_zkb_link}) "982 elif killmail.victim.corporation_id:983 victim_str = victim_corporation_zkb_link984 else:985 victim_str = ""986 # final attacker987 for attacker in killmail.attackers:988 if attacker.is_final_blow:989 final_attacker = attacker990 break991 else:992 final_attacker = None993 if final_attacker:994 if final_attacker.corporation_id:995 final_attacker_corporation_zkb_link = self._corporation_zkb_link(996 final_attacker.corporation_id, resolver997 )998 else:999 final_attacker_corporation_zkb_link = ""1000 if final_attacker.character_id and final_attacker.corporation_id:1001 final_attacker_character_zkb_link = self._character_zkb_link(1002 final_attacker.character_id, resolver1003 )1004 final_attacker_str = (1005 f"{final_attacker_character_zkb_link} "1006 f"({final_attacker_corporation_zkb_link})"1007 )1008 elif final_attacker.corporation_id:1009 final_attacker_str = f"{final_attacker_corporation_zkb_link}"1010 elif final_attacker.faction_id:1011 final_attacker_str = (1012 f"**{resolver.to_name(final_attacker.faction_id)}**"1013 )1014 else:1015 final_attacker_str = "(Unknown final_attacker)"1016 final_attacker_ship_type_name = resolver.to_name(1017 final_attacker.ship_type_id1018 )1019 else:1020 final_attacker_str = ""1021 final_attacker_ship_type_name = ""1022 if killmail.solar_system_id:1023 solar_system, _ = EveSolarSystem.objects.get_or_create_esi(1024 id=killmail.solar_system_id1025 )1026 solar_system_link = self.webhook.create_message_link(1027 name=solar_system.name, url=dotlan.solar_system_url(solar_system.name)1028 )1029 region_name = solar_system.eve_constellation.eve_region.name1030 solar_system_text = f"{solar_system_link} ({region_name})"1031 else:1032 solar_system_text = ""1033 # self info1034 show_as_fleetkill = False1035 distance_text = ""1036 main_org_text = ""1037 main_org_name = ""1038 main_org_icon_url = eveimageserver.alliance_logo_url(1, size=self.ICON_SIZE)1039 main_ship_group_text = ""1040 tracked_ship_types_text = ""1041 embed_color = None1042 if killmail.tracker_info:1043 show_as_fleetkill = self.identify_fleets1044 embed_color = int(self.color[1:], 16) if self.color else None1045 if self.origin_solar_system:1046 origin_solar_system_link = self.webhook.create_message_link(1047 name=self.origin_solar_system.name,1048 url=dotlan.solar_system_url(self.origin_solar_system.name),1049 )1050 if killmail.tracker_info.distance is not None:1051 distance_str = f"{killmail.tracker_info.distance:,.1f}"1052 else:1053 distance_str = "?"1054 if killmail.tracker_info.jumps is not None:1055 jumps_str = killmail.tracker_info.jumps1056 else:1057 jumps_str = "?"1058 distance_text = (1059 f"\nDistance from {origin_solar_system_link}: "1060 f"{distance_str} LY | {jumps_str} jumps"1061 )1062 # main group1063 main_org = killmail.tracker_info.main_org1064 if main_org:1065 main_org_name = resolver.to_name(main_org.id)1066 if main_org.is_corporation:1067 main_org_link = self._corporation_zkb_link(main_org.id, resolver)1068 main_org_icon_url = eveimageserver.corporation_logo_url(1069 main_org.id, size=self.ICON_SIZE1070 )1071 else:1072 main_org_link = self._alliance_zkb_link(main_org.id, resolver)1073 main_org_icon_url = eveimageserver.alliance_logo_url(1074 main_org.id, size=self.ICON_SIZE1075 )1076 main_org_text = f" | Main group: {main_org_link} ({main_org.count})"1077 else:1078 show_as_fleetkill = False1079 # main ship group1080 main_ship_group = killmail.tracker_info.main_ship_group1081 if main_ship_group:1082 main_ship_group_text = f"\nMain ship class: **{main_ship_group.name}**"1083 # tracked attacker ships1084 matching_ship_type_ids = killmail.tracker_info.matching_ship_type_ids1085 if matching_ship_type_ids:1086 ship_types_text = "**, **".join(1087 sorted(1088 [1089 resolver.to_name(type_id)1090 for type_id in matching_ship_type_ids1091 ]1092 )1093 )1094 tracked_ship_types_text = (1095 f"\nTracked ship types involved: **{ship_types_text}**"1096 )1097 victim_ship_type_name = resolver.to_name(killmail.victim.ship_type_id)1098 description = (1099 f"{victim_str} lost their **{victim_ship_type_name}** "1100 f"in {solar_system_text} "1101 f"worth **{humanize_value(killmail.zkb.total_value)}** ISK.\n"1102 f"Final blow by {final_attacker_str} "1103 f"in a **{final_attacker_ship_type_name}**.\n"1104 f"Attackers: **{len(killmail.attackers):,}**{main_org_text}"1105 f"{main_ship_group_text}"1106 f"{tracked_ship_types_text}"1107 f"{distance_text}"1108 )1109 solar_system_name = resolver.to_name(killmail.solar_system_id)1110 if show_as_fleetkill:1111 title = f"{solar_system_name} | {main_org_name} | Fleetkill"1112 else:1113 title = f"{solar_system_name} | {victim_ship_type_name} | Killmail"1114 if show_as_fleetkill:1115 thumbnail_url = main_org_icon_url1116 else:1117 thumbnail_url = eveimageserver.type_icon_url(1118 killmail.victim.ship_type_id, size=self.ICON_SIZE1119 )1120 zkb_killmail_url = f"{ZKB_KILLMAIL_BASEURL}{killmail.id}/"1121 # TODO This is a workaround for Embed.Author.name. Address in dhooks_lite1122 author = (1123 dhooks_lite.Author(1124 name=victim_organization.name if victim_organization.name else "?",1125 url=victim_org_url,1126 icon_url=victim_organization.icon_url(),1127 )1128 if victim_organization and victim_org_url1129 else None1130 )1131 zkb_icon_url = urljoin(1132 site_absolute_url(), staticfiles_storage.url("killtracker/zkb_icon.png")1133 )1134 embed = dhooks_lite.Embed(1135 author=author,1136 description=description,1137 title=title,1138 url=zkb_killmail_url,1139 thumbnail=dhooks_lite.Thumbnail(url=thumbnail_url),1140 footer=dhooks_lite.Footer(text="zKillboard", icon_url=zkb_icon_url),1141 timestamp=killmail.time,1142 color=embed_color,1143 )1144 return embed1145 def _create_content(self, intro_text) -> str:1146 intro_parts = []1147 if self.ping_type == Tracker.ChannelPingType.EVERYBODY:1148 intro_parts.append("@everybody")1149 elif self.ping_type == Tracker.ChannelPingType.HERE:1150 intro_parts.append("@here")1151 if self.ping_groups.exists():1152 if "discord" in app_labels():1153 for group in self.ping_groups.all():1154 try:1155 role = DiscordUser.objects.group_to_role(group)1156 except HTTPError:1157 logger.warning(1158 "Failed to get Discord roles. Can not ping groups.",1159 exc_info=True,1160 )1161 else:1162 if role:1163 intro_parts.append(f"<@&{role['id']}>")1164 else:1165 logger.warning(1166 "Discord service needs to be installed in order "1167 "to use groups ping features."1168 )1169 if self.is_posting_name:1170 intro_parts.append(f"Tracker **{self.name}**:")1171 intro_parts_2 = []1172 if intro_text:1173 intro_parts_2.append(intro_text)1174 if intro_parts:1175 intro_parts_2.append(" ".join(intro_parts))1176 return "\n".join(intro_parts_2)1177 def _character_zkb_link(1178 self, entity_id: int, resolver: EveEntityNameResolver1179 ) -> str:1180 return self.webhook.create_message_link(1181 name=resolver.to_name(entity_id), url=zkillboard.character_url(entity_id)1182 )1183 def _corporation_zkb_link(1184 self, entity_id: int, resolver: EveEntityNameResolver1185 ) -> str:1186 return self.webhook.create_message_link(1187 name=resolver.to_name(entity_id), url=zkillboard.corporation_url(entity_id)1188 )1189 def _alliance_zkb_link(1190 self, entity_id: int, resolver: EveEntityNameResolver1191 ) -> str:1192 return self.webhook.create_message_link(1193 name=resolver.to_name(entity_id), url=zkillboard.alliance_url(entity_id)...

Full Screen

Full Screen

Exercice_4.py

Source:Exercice_4.py Github

copy

Full Screen

1"""2Exercice 4 de l'atelier 4 : Mots croisés3file = "Exercice_4.py"4author = "Baptiste Varamo & Jean-François Giammari"5credits = ["Baptiste Varamo","Jean-François Giammari"]6version = "1.0"7"""8from Exercice_2 import dictionnaire, mots_Nlettres9def mot_correspond(mot: str, motif: str) -> bool:10 """11 Check if the string may or may not match the given pattern string12 mot -- The word13 motif -- The pattern14 return True if match15 """16 is_matching = True17 if len(mot) != len(motif):18 is_matching = False19 else:20 length = len(mot)21 i = 022 while i < length and is_matching:23 if motif[i] != "." and mot[i] != motif[i]:24 is_matching = False25 i += 126 return is_matching27def presente(lettre: str, mot: str) -> int:28 """29 Define the place of a letter in a word30 mot -- The word31 lettre -- The letter32 return index or -1 if the letter dont exist in the word33 """34 return mot.find(lettre)35def mot_possible(mot: str, lettres: str) -> bool:36 """37 Define if the word is writable with the letters38 mot -- The word39 lettres -- The letters40 return True if is writable41 """42 is_matching = True43 length = len(mot)44 i = 045 while i < length and is_matching:46 if lettres.find(mot[i]) == -1:47 is_matching = False48 else:49 lettres = lettres.replace(mot[i], '', 1);50 i += 151 return is_matching52def mot_optimaux(dico: str, lettres: str) -> list:53 """54 Define the list of possible word with the letters55 dico -- The dictionnary56 lettres -- The letters usable57 return list of possible word58 """59 dico = dictionnaire(dico)60 lst_playable = []61 length = len(lettres)62 for i in range(length, 0, -1):63 lst_NFiltered = mots_Nlettres(dico, i)64 for e in lst_NFiltered:65 if mot_possible(e,lettres):66 lst_playable.append(e)67 return lst_playable68def test_exercice4():69 """70 Test for exercice 471 """72 print("Test mot_correspond TRUE (cheval c..v.l) : ", mot_correspond("cheval", "c..v.l"))73 print("Test mot_correspond FALSE (cheval c..v..l) : ", mot_correspond("cheval", "c..v..l"))74 print("Test presente 2 (e,cheval) : ", presente("e", "cheval"))75 print("Test presente -1 (x,cheval) : ", presente("x", "cheval"))76 print("Test mot_possible TRUE (lapin, abilnpq) : ", mot_possible("lapin", "abilnpq"))77 print("Test mot_possible FALSE (cheval, abilnpq) : ", mot_possible("cheval", "abilnpq"))78 print("Test mot_possible TRUE (chapeau, abcehpuva): ", mot_possible("chapeau", "abcehpuva"))79 print("Test mot_possible FALSE (chapeau, abcehpuv) : ", mot_possible("chapeau", "abcehpuv"))80 print("Test mot_optimaux : ", mot_optimaux("littre.txt", "chipeau"))...

Full Screen

Full Screen

util.py

Source:util.py Github

copy

Full Screen

1from flask import session2from functools import wraps3import bcrypt4def hash_password(plain_text_password):5 # By using bcrypt, the salt is saved into the hash itself6 hashed_bytes = bcrypt.hashpw(plain_text_password.encode('utf-8'), bcrypt.gensalt())7 return hashed_bytes.decode('utf-8')8def verify_password(plain_text_password, hashed_password):9 hashed_bytes_password = hashed_password.encode('utf-8')10 return bcrypt.checkpw(plain_text_password.encode('utf-8'), hashed_bytes_password)11def check_login(wrapped_function):12 @wraps(wrapped_function)13 def decorated_function(*args, **kwargs):14 if "id" not in session:15 pass16 return wrapped_function(*args, **kwargs)17 return decorated_function18if __name__ == '__main__':19 # Test the above functions manually20 original_password = 'my_very_secureP4ssword!' # From registration form21 print('original_password: ' + original_password)22 hashed_password = hash_password(original_password) # This shall be saved in the DB23 print('hashed_password: ' + hashed_password)24 user_input_password = 'Hey Siri, what is my password?' # From a login form, a mistyped input25 is_matching = verify_password(user_input_password, hashed_password)26 print('is_matching: ' + str(is_matching))27 user_input_password = 'my_very_secureP4ssword!' # From a login form, the correct input28 is_matching = verify_password(user_input_password, hashed_password)...

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run pytest-bdd automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful