import itertools from sqlalchemy import func from .base import pgdb from .claim_name import ClaimName from .claim_value import ClaimValue from .dna_account import DNAAccountActivity from .views import dna_accounts_global_claims class Product: def __init__(self, resource_group, account): self.resource_group = resource_group self.account = account ( self.created_at, self.updated_at, self.is_disabled, ) = self._get_status_data() self.claims = self._get_claims() self.claims_tree = self._get_claims_tree() self.activity = self._get_activity() @property def name(self): return self.resource_group.name @property def code(self): return self.resource_group.id @property def first_login(self): return self.activity.first_login if self.activity else None @property def last_login(self): return self.activity.last_login if self.activity else None @property def last_activity(self): return self.activity.last_activity if self.activity else None def _get_status_data(self): return ( pgdb.session.query( func.min(dna_accounts_global_claims.c.created_at), func.max(dna_accounts_global_claims.c.updated_at), func.coalesce( func.bool_or(dna_accounts_global_claims.c.is_disabled), True, ), ) .join(ClaimValue) .join( ClaimName, dna_accounts_global_claims.c.claim_name_id == ClaimName.id, ) .filter( dna_accounts_global_claims.c.dna_account_id == self.account.id, ClaimName.resource_group == self.resource_group, ) .first() ) def _get_claims(self): result = { cn: [] for cn in self.resource_group.claim_names.filter_by( is_deleted=False ).order_by("id") } for cn, cv in self.account.fetch_claims( resource_group=self.resource_group ): result.setdefault(cn, []).append(cv) return result def _get_claims_tree(self): result = { cn: self._build_claim_values_tree(values) if cn.parent or (cn.claim_values_source and cn.claim_values_source) else values for cn, values in self.claims.items() } return result def _build_claim_values_tree(self, values): tree = {} with_parents = (v for v in values if v.parent) without_parents = (v for v in values if not v.parent) sorted_values = itertools.chain( sorted(with_parents, key=lambda v: v.parent.friendly), sorted(without_parents, key=lambda v: v.friendly), ) for value in sorted_values: if value.parent: tree.setdefault(value.parent, []).append(value) else: tree.setdefault(None, []).append(value) return tree def _get_activity(self): return DNAAccountActivity.query.filter_by( dna_account_id=self.account.id, resource_group_id=self.resource_group.id, ).first() def __eq__(self, other): return ( isinstance(other, self.__class__) and self.resource_group == other.resource_group and self.account == other.account )