class Round(db.Model): id = db.Column(db.Integer, primary_key=True) round_num = db.Column(db.Integer) disputeID = db.Column(db.Integer, db.ForeignKey("dispute.id"), nullable=False) draws_in_round = db.Column(db.Integer) commits_in_round = db.Column(db.Integer) appeal_start = db.Column(db.Integer) appeal_end = db.Column(db.Integer) vote_lengths = db.Column(db.Integer) tokens_at_stake_per_juror = db.Column(db.Integer) total_fees_for_jurors = db.Column(db.Integer) votes_in_each_round = db.Column(db.Integer) repartitions_in_each_round = db.Column(db.Integer) penalties_in_each_round = db.Column(db.Integer) subcourtID = db.Column(db.Integer, db.ForeignKey("court.id"), nullable=False) def votes(self): return Vote.query.filter_by(round_id=self.id).order_by( Vote.account.asc()).all() def delete_recursive(self): votes = Vote.query.filter(Vote.round_id == self.id) for v in votes: logger.info("Deleting Vote %s" % v.id) db.session.delete(v) db.session.commit() logger.info("Deleting round %s" % self.id) db.session.delete(self) db.session.commit() @property def majority_reached(self): votes_cast = [] votes_cast.append( Vote.query.filter(Vote.round_id == self.id).filter( Vote.vote == 1).filter(Vote.choice == 1).count()) votes_cast.append( Vote.query.filter(Vote.round_id == self.id).filter( Vote.vote == 1).filter(Vote.choice == 2).count()) votes_cast.append( Vote.query.filter(Vote.round_id == self.id).filter( Vote.vote == 1).filter(Vote.choice == 0).count()) return any(x >= self.draws_in_round / 2 for x in votes_cast) @property def winning_choice(self): # votes = Vote.query.filter(Vote.round_id == self.id).count() votes_query = db.session.execute( "select choice,count(*) as num_votes from vote \ where round_id = :round_id and vote=1 \ group by choice order by num_votes desc", { 'round_id': self.id }).first() return (votes_query[0])
class Deposit(db.Model): id = db.Column(db.Integer, primary_key=True) address = db.Column(db.String(50)) cdate = db.Column(db.DateTime) amount = db.Column(db.Float) txid = db.Column(db.String(50)) court_id = db.Column(db.Integer, db.ForeignKey("court.id"), nullable=False) token_contract = db.Column(db.String(50)) # FIXME @classmethod def total(cls): return cls.query.with_entities(func.sum(cls.amount)).all()[0][0]
class Vote(db.Model): id = db.Column(db.Integer, primary_key=True) round_id = db.Column(db.Integer, db.ForeignKey("round.id"), nullable=False) account = db.Column(db.String(50)) commit = db.Column(db.Integer) choice = db.Column(db.Integer) vote = db.Column(db.Integer) date = db.Column(db.DateTime) def __str__(self): return f'Vote(juror={self.account}, choice={self.choice}, vote={self.vote}, commit={self.commit})' def __eq__(self, other): if isinstance(other, self.__class__): attrs_match = ((self.account.lower() == other.account.lower()) and (self.commit == other.commit) and (self.choice == other.choice) and (self.vote == other.vote)) return attrs_match else: return False def __ne__(self, other): return not self.__eq__(other) @property def is_winner(self): """ Check if the vote is winner in its round """ round = Round.query.get(self.round_id) if not round.majority_reached: return False return self.choice == round.winning_choice @property def vote_str(self): map_votes = {0: 'Refuse to Arbitrate', 1: 'Yes', 2: 'No', 3: 'Pending'} try: if self.vote == 1: return map_votes[self.choice] else: return map_votes[3] except KeyError: logger.error("Key error not found when mapping the vote string") logger.error( "The vote has the properties: ID:{}, Vote:{}, Choice{}".format( self.id, self.vote, self.choice)) return ''
class JurorStake(db.Model): id = db.Column(db.Integer, primary_key=True) address = db.Column(db.String(50)) subcourtID = db.Column(db.Integer, db.ForeignKey("court.id"), nullable=False) timestamp = db.Column(db.DateTime) setStake = db.Column(db.Float) txid = db.Column(db.String(100)) blocknumber = db.Column(db.Integer) @staticmethod def last_blocknumber(): return JurorStake.query.order_by( JurorStake.id.desc()).first().blocknumber
class Vote(db.Model): id = db.Column(db.Integer, primary_key=True) round_id = db.Column(db.Integer, db.ForeignKey("round.id"), nullable=False) account = db.Column(db.String(50)) commit = db.Column(db.Integer) choice = db.Column(db.Integer) vote = db.Column(db.Integer) date = db.Column(db.DateTime) @property def is_winner(self): round = Round.query.get(self.round_id) if not round.majority_reached: return False return self.choice == round.winning_choice
class Round(db.Model): id = db.Column(db.Integer, primary_key=True) round_num = db.Column(db.Integer) disputeID = db.Column(db.Integer, db.ForeignKey("dispute.id"), nullable=False) draws_in_round = db.Column(db.Integer) commits_in_round = db.Column(db.Integer) appeal_start = db.Column(db.Integer) appeal_end = db.Column(db.Integer) vote_lengths = db.Column(db.Integer) tokens_at_stake_per_juror = db.Column(db.Float) total_fees_for_jurors = db.Column(db.Float) votes_in_each_round = db.Column(db.Integer) repartitions_in_each_round = db.Column(db.Float) penalties_in_each_round = db.Column(db.Float) subcourtID = db.Column(db.Integer, db.ForeignKey("court.id"), nullable=False) def __str__(self): return f'Round(court={self.subcourtID}, dispute_id={self.disputeID}, number={self.round_num}, drawns={self.draws_in_round}, commits={self.commits_in_round})' def __eq__(self, other): classes_match = isinstance(other, self.__class__) a, b = deepcopy(self.__dict__), deepcopy(other.__dict__) # compare based on equality our attributes, ignoring SQLAlchemy internal stuff avoid_fields = [ '_sa_instance_state', 'id', 'appeal_start', 'appeal_end', 'vote_lengths', 'votes_in_each_round' ] for field in avoid_fields: a.pop(field, None) b.pop(field, None) attrs_match = (a == b) return classes_match and attrs_match def __ne__(self, other): return not self.__eq__(other) def votes(self): return Vote.query.filter_by(round_id=self.id).order_by( Vote.account.asc()).all() def votes_drawn_order(self): return Vote.query.filter_by(round_id=self.id).order_by( Vote.id.asc()).all() def vote_count(self): count = {'Yes': 0, 'No': 0, 'Refuse': 0, 'Pending': 0} for v in self.votes(): count[v.vote_str] += 1 return count def delete_recursive(self): votes = Vote.query.filter(Vote.round_id == self.id) for v in votes: logger.info("Deleting Vote %s" % v.id) db.session.delete(v) db.session.commit() logger.info("Deleting round %s" % self.id) db.session.delete(self) db.session.commit() @property def majority_reached(self): votes_cast = [] votes_cast.append( Vote.query.filter(Vote.round_id == self.id).filter( Vote.vote == 1).filter(Vote.choice == 1).count()) votes_cast.append( Vote.query.filter(Vote.round_id == self.id).filter( Vote.vote == 1).filter(Vote.choice == 2).count()) votes_cast.append( Vote.query.filter(Vote.round_id == self.id).filter( Vote.vote == 1).filter(Vote.choice == 0).count()) return any(x >= self.draws_in_round / 2 for x in votes_cast) @property def winning_choice(self): # votes = Vote.query.filter(Vote.round_id == self.id).count() votes_query = db.session.execute( "select choice,count(*) as num_votes from vote \ where round_id = :round_id and vote=1 \ group by choice order by num_votes desc", { 'round_id': self.id }).first() return (votes_query[0])
class Court(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(50)) address = db.Column(db.String(50)) parent = db.Column(db.Integer, db.ForeignKey("court.id"), nullable=True) minStake = db.Column(db.Float) feeForJuror = db.Column(db.Float) voteStake = db.Column(db.Integer) meanStaked = db.Column(db.Float) maxStaked = db.Column(db.Float) totalStaked = db.Column(db.Float) activeJurors = db.Column(db.Integer) disputesLast30days = db.Column(db.Integer) minStakeUSD = db.Column(db.Float) def disputes(self, days=None): """ Return the disputes in the previous days. If days is None, return all the disputes in that Court Parameters ---------- days : int, optional Number of days to count the disputes backwards. The default is None. Returns ------- List List of all the Disputes """ if days: filter_after = (datetime.now() - timedelta(days=days)).replace( hour=0, minute=0, second=0) return Dispute.query \ .filter(Dispute.subcourtID == self.id, Dispute.timestamp >= filter_after) \ .order_by(Dispute.id.desc()).all() else: return Dispute.query.filter( Dispute.subcourtID == self.id).order_by( Dispute.id.desc()).all() def disputes_paginated(self, page=0, per_page=10): """ Return the disputes of the court, paginated Parameters ---------- page : int, optional Current page, by default is 0 per_page : int, optional Amount of disputes per page. By default is 10 Returns ------- List List of all the Disputes """ return Dispute.query.filter(Dispute.subcourtID == self.id).order_by( Dispute.id.desc()).paginate(page, per_page, error_out=False) @property def openCases(self): return Dispute.query.filter(Dispute.ruled == 0).filter( Dispute.subcourtID == self.id).count() @property def ruledCases(self): return Dispute.query.filter(Dispute.ruled == 1).filter( Dispute.subcourtID == self.id).count() def get_recursive_childs(self, node=0): query = f""" WITH RECURSIVE cte_court (id, name, parent) AS ( SELECT e.id, e.name, e.parent FROM court e WHERE e.id = {node} UNION ALL SELECT e.id, e.name, e.parent FROM court e JOIN cte_court c ON c.id = e.parent ) SELECT * FROM cte_court ORDER BY cte_court.id; """ return [{ 'id': child[0], 'name': child[1] } for child in db.session.execute(query)] @property def children_ids(self): return [ child.id for child in Court.query.filter(Court.parent == self.id) ] @property def children_names(self): return [ child.name for child in Court.query.filter(Court.parent == self.id) ] @property def childrens(self): return [child for child in Court.query.filter(Court.parent == self.id)] @property def fees_paid(self): disputes = Dispute.query.filter_by(subcourtID=self.id) eth_fees_paid = 0 pnk_distributed = 0 for dispute in disputes: rounds = dispute.rounds() for r in rounds: eth_fees_paid += r.total_fees_for_jurors pnk_distributed += r.penalties_in_each_round return {'eth': eth_fees_paid, 'pnk': pnk_distributed} @staticmethod def getAllCourtChilds(courtID): childs = set(Court(id=courtID).children_ids) allChilds = [] while childs: child = childs.pop() allChilds.append(child) childs.update(Court(id=child).children_ids) return allChilds @staticmethod def getParent(courtID): return Court.query.filter_by(id=courtID).first().parent @property def ncourts(self): return Court.query.count() @property def jurors(self): courts_childs = Court.getAllCourtChilds(self.id) courts_childs.append(self.id) if len(courts_childs) > 1: courts_id = tuple(courts_childs) else: courts_id = f'({courts_childs[0]})' query = f""" SELECT address, SUM(setStake) as staked FROM ( SELECT address, setStake FROM juror_stake WHERE id IN ( SELECT MAX(id) FROM juror_stake WHERE subcourtID in {courts_id} GROUP BY address, subcourtID ) ) as Jurors WHERE setStake > 0 GROUP BY address ORDER BY setStake DESC """ execute = db.session.execute(query).fetchall() jurors = {} for juror in execute: jurors[juror[0]] = juror[1] return jurors @property def map_name(self): if self.name: return self.name else: return self.query.filter(Court.id == self.id).first().name def yes_no_coherency(self): coherency = {'Refuse': 0, 'Yes': 0, 'No': 0} incoherents = {'Refuse': 0, 'Yes': 0, 'No': 0, 'Pending': 0} for d in self.disputes(): data = d.yes_no_coherency() if data: for key, value in data['coherents'].items(): coherency[key] += value for key, value in data['incoherents'].items(): incoherents[key] += value totals = {'coherents': sum([value for value in coherency.values()])} totals['incoherents'] = sum([value for value in incoherents.values()]) totals['percentage_coherents'] = totals['coherents'] / ( totals['coherents'] + totals['incoherents']) if all([value == 0 for value in coherency.values()]): return None else: return { 'coherents': coherency, 'incoherents': incoherents, 'totals': totals } def juror_stats(self): jurors = self.jurors try: court_mean = statistics.mean(jurors.values()) except Exception as e: court_mean = 0 logger.info(f"Could not get the mean value of the court {self.id}") logger.error(e) try: court_median = statistics.median(jurors.values()) except Exception as e: court_median = 0 logger.info( f"Could not get the median value of the court {self.id}") logger.error(e) try: court_max = max(jurors.values()) except Exception as e: court_max = 0 logger.info(f"Could not get the max value of the court {self.id}") logger.error(e) return { 'length': len(jurors.values()), 'mean': court_mean, 'median': court_median, 'max': court_max, 'total': sum(jurors.values()) } @staticmethod def updateStatsAllCourts(): courts = db.session.query(Court.id).all() pnkPrice = float(Config.get('PNKprice')) for court in courts: c = Court.query.filter_by(id=court.id).first() stats = c.juror_stats() c.meanStaked = int(stats['mean']) c.maxStaked = int(stats['max']) c.totalStaked = int(stats['total']) c.activeJurors = stats['length'] c.disputesLast30days = len(c.disputes(30)) c.minStakeUSD = c.minStake * pnkPrice db.session.add(c) db.session.commit() logger.debug("Stats of Courts updated")
class Dispute(db.Model): id = db.Column(db.Integer, primary_key=True) number_of_choices = db.Column(db.Integer) subcourtID = db.Column(db.Integer, db.ForeignKey("court.id"), nullable=False) status = db.Column(db.Integer) arbitrated = db.Column(db.String(50)) current_ruling = db.Column(db.Integer) period = db.Column(db.Integer) last_period_change = db.Column(db.DateTime) ruled = db.Column(db.Boolean) creator = db.Column(db.String(50)) txid = db.Column(db.String(100)) timestamp = db.Column(db.DateTime) blocknumber = db.Column(db.Integer) def __eq__(self, other): classes_match = isinstance(other, self.__class__) a, b = deepcopy(self.__dict__), deepcopy(other.__dict__) # compare based on equality our attributes, ignoring SQLAlchemy internal stuff a.pop('_sa_instance_state', None) b.pop('_sa_instance_state', None) attrs_match = (a == b) return classes_match and attrs_match def __str__(self): return f'Dispute(id={self.id}, court={self.subcourtID}, period={self.period}, ruled={self.ruled}, current_ruling={self.current_ruling})' def __ne__(self, other): return not self.__eq__(other) def rounds(self): return Round.query.filter_by(disputeID=self.id).all() @property def court(self): return Court.query.get(self.subcourtID) @property def period_name(self): period_name = { 0: "Evidence", 1: "Commit", 2: "Vote", 3: "Appeal", 4: "Execution", } return period_name[self.period] @property def winner_choice_str(self): choice_name = { 0: 'Refuse to Arbitrate', 1: 'Yes', 2: 'No', 3: 'Tie', 4: 'Not Ruled yet' } if self.winning_choice is not None: return choice_name[self.winning_choice] else: return choice_name[4] def delete_recursive(self): rounds = Round.query.filter(Round.disputeID == self.id) for r in rounds: r.delete_recursive() logger.info("Deleting Dispute %s" % self.id) db.session.delete(self) db.session.commit() @property def openCases(self): return self.query.filter(Dispute.ruled == 0).count() @property def ruledCases(self): return self.query.filter(Dispute.ruled == 1).count() @staticmethod def mostActiveCourt(days=7): """ Most active cour in the last days Parameters ---------- days : int, optional DESCRIPTION. Last Days to filter. The default is 7. Returns ------- Court object with the most active Court in the last days. """ filter_after = datetime.today() - timedelta(days=days) disputes = Dispute.query.filter( Dispute.timestamp >= filter_after).all() counts = {} for dispute in disputes: try: counts[dispute.subcourtID] += 1 except KeyError: counts[dispute.subcourtID] = 1 try: mostActive = max(counts, key=counts.get) return {mostActive: counts[mostActive]} except Exception: return None @staticmethod def timeEvolution(): """ Return the timestamp and Dispute amounts """ disputes = db.session.query(Dispute.id, Dispute.timestamp).all() allDisputes = [] for dispute in disputes: allDisputes.append({ 'timestamp': dispute.timestamp, 'id': dispute.id }) return allDisputes @staticmethod def disputesCountByCourt(): data = Dispute.query.with_entities(Dispute.subcourtID, func.count(Dispute.id)).\ group_by(Dispute.subcourtID).all() result = {} for item in data: result[Court(id=item[0]).map_name] = item[1] return result @staticmethod def disputesCountByArbitrated(): data = Dispute.query.with_entities(Dispute.arbitrated, func.count(Dispute.id)).\ group_by(Dispute.arbitrated).all() result = {} for item in data: name = ContractMapper.searchName(item[0]) if name in list(result.keys()): result[name] += item[1] else: result[name] = item[1] return result @staticmethod def disputesByArbitrated(address): disputes = Dispute.query.filter( func.lower(Dispute.arbitrated) == address.lower()).order_by( Dispute.id.desc()).all() return list(disputes) @staticmethod def disputesByCreator(address): disputes = Dispute.query.filter( func.lower(Dispute.creator) == address.lower()).order_by( Dispute.id.desc()).all() return list(disputes) @staticmethod def disputesByCreator_paginated(address, page=0, per_page=10): return Dispute.query.filter( func.lower(Dispute.creator) == address.lower()).order_by( Dispute.id.desc()).paginate(page, per_page, error_out=False) @property def winning_choice(self): max_round_id = self.rounds()[-1].id if Dispute.query.filter_by(id=self.id).first().ruled: votes_query = db.session.execute( "select choice,count(*) as num_votes from vote \ where round_id = :round_id and vote=1 \ group by choice order by num_votes desc", { 'round_id': max_round_id }).fetchall() num_of_votes = [count[1] for count in votes_query] if len(num_of_votes) == 0: # all the votes are still pending return None if (len(num_of_votes) > 1) and (all(count == num_of_votes[0] for count in num_of_votes)): # it's a tie return 3 else: return votes_query[0].items()[0][1] else: return None def coherency(self): """ Percentage of coherent votes with the final result """ if Dispute.query.filter_by(id=self.id).first().ruled: coherent_votes = 0 no_coherent_votes = 0 rounds = self.rounds() for r in rounds: for vote in r.votes(): if self.winning_choice != 3: # if it's not a tie if (vote.vote) and (vote.choice == self.winning_choice): coherent_votes += 1 elif not vote.vote: # if didn't vote, don't count it # TODO! review if this is fine pass else: no_coherent_votes += 1 else: # if it's a tie, if voted it's coherent, if not, isn't if vote.vote: coherent_votes += 1 else: no_coherent_votes += 1 if coherent_votes + no_coherent_votes: return coherent_votes / (coherent_votes + no_coherent_votes) else: return None else: return None def yes_no_coherency(self): """ Number of votes for yes or no that are coherent with the final result """ coherency = {'Refuse': 0, 'Yes': 0, 'No': 0} incoherents = {'Refuse': 0, 'Yes': 0, 'No': 0, 'Pending': 0} mapper = {0: 'Refuse', 1: 'Yes', 2: 'No'} if Dispute.query.filter_by(id=self.id).first().ruled: for r in self.rounds(): for vote in r.votes(): if self.winning_choice != 3: # if it's not a tie if (vote.vote) and (vote.choice == self.winning_choice): coherency[mapper[vote.choice]] += 1 elif not vote.vote: incoherents['Pending'] += 1 else: incoherents[mapper[vote.choice]] += 1 else: # if it's a tie, if voted it's coherent, if not, isn't if vote.vote: coherency[mapper[vote.choice]] += 1 else: incoherents['Pending'] += 1 return {'coherents': coherency, 'incoherents': incoherents} else: return None
class Court(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(50)) address = db.Column(db.String(50)) parent = db.Column(db.Integer, db.ForeignKey("court.id"), nullable=True) minStake = db.Column(db.Float) feeForJuror = db.Column(db.Float) voteStake = db.Column(db.Integer) meanStaked = db.Column(db.Float) maxStaked = db.Column(db.Float) totalStaked = db.Column(db.Float) activeJurors = db.Column(db.Integer) disputesLast30days = db.Column(db.Integer) minStakeUSD = db.Column(db.Float) def disputes(self, days=None): """ Return the disputes in the previous days. If days is None, return all the disputes in that Court Parameters ---------- days : int, optional Number of days to count the disputes backwards. The default is None. Returns ------- List List of all the Disputes """ if days: filter_after = (datetime.now() - timedelta(days=days)).replace( hour=0, minute=0, second=0) return Dispute.query \ .filter(Dispute.subcourtID == self.id, Dispute.timestamp >= filter_after) \ .order_by(Dispute.id.desc()).all() else: return Dispute.query.filter( Dispute.subcourtID == self.id).order_by( Dispute.id.desc()).all() def children_ids(self): children_ids = [] children = Court.query.filter(Court.parent == self.id) for child in children: children_ids.append(child.id) return children_ids @staticmethod def getAllCourtChilds(courtID): childs = set(Court(id=courtID).children_ids()) allChilds = [] while childs: child = childs.pop() allChilds.append(child) childs.update(Court(id=child).children_ids()) return allChilds @property def ncourts(self): return Court.query.count() @property def jurors(self): allStakes = db.session.execute( "SELECT id,address,setStake, subcourtID \ FROM juror_stake \ WHERE id IN ( \ SELECT MAX(id) \ FROM juror_stake \ GROUP BY address,subcourtID);") stakedJurors = {} courts_id = self.getAllCourtChilds(self.id) courts_id.append(self.id) for stake in allStakes: if stake.setStake > 0 and stake.subcourtID in courts_id: if stake.address.lower() in stakedJurors.keys(): stakedJurors[stake.address.lower()] += stake.setStake else: stakedJurors[stake.address.lower()] = stake.setStake return stakedJurors @property def map_name(self): if self.name: return self.name else: return self.query.filter(Court.id == self.id).first().name def juror_stats(self): jurors = self.jurors try: court_mean = statistics.mean(jurors.values()) except Exception as e: court_mean = 0 logger.info(f"Could not get the mean value of the court {self.id}") logger.error(e) try: court_median = statistics.median(jurors.values()) except Exception as e: court_median = 0 logger.info( f"Could not get the median value of the court {self.id}") logger.error(e) try: court_max = max(jurors.values()) except Exception as e: court_max = 0 logger.info(f"Could not get the max value of the court {self.id}") logger.error(e) return { 'length': len(jurors.values()), 'mean': court_mean, 'median': court_median, 'max': court_max, 'total': sum(jurors.values()) } @staticmethod def updateStatsAllCourts(): courts = db.session.query(Court.id).all() pnkPrice = float(Config.get('PNKprice')) for court in courts: c = Court.query.filter_by(id=court.id).first() stats = c.juror_stats() c.meanStaked = int(stats['mean']) c.maxStaked = int(stats['max']) c.totalStaked = int(stats['total']) c.activeJurors = stats['length'] c.disputesLast30days = len(c.disputes(30)) c.minStakeUSD = c.minStake * pnkPrice db.session.add(c) db.session.commit() logger.debug("Stats of Courts updated")
class Dispute(db.Model): id = db.Column(db.Integer, primary_key=True) number_of_choices = db.Column(db.Integer) subcourtID = db.Column(db.Integer, db.ForeignKey("court.id"), nullable=False) status = db.Column(db.Integer) arbitrated = db.Column(db.String(50)) current_ruling = db.Column(db.Integer) period = db.Column(db.Integer) last_period_change = db.Column(db.DateTime) ruled = db.Column(db.Boolean) creator = db.Column(db.String(50)) txid = db.Column(db.String(100)) timestamp = db.Column(db.DateTime) blocknumber = db.Column(db.Integer) def rounds(self): return Round.query.filter_by(disputeID=self.id).all() @property def court(self): return Court.query.get(self.subcourtID) @property def period_name(self): period_name = { 0: "Evidence", 1: "Commit", 2: "Vote", 3: "Appeal", 4: "Execution", } return period_name[self.period] def delete_recursive(self): rounds = Round.query.filter(Round.disputeID == self.id) for r in rounds: r.delete_recursive() logger.info("Deleting Dispute %s" % self.id) db.session.delete(self) db.session.commit() @property def openCases(self): openCases = self.query.filter(Dispute.ruled == 0).all() return len(openCases) @property def ruledCases(self): ruledCases = self.query.filter(Dispute.ruled == 1).all() return len(ruledCases) @staticmethod def mostActiveCourt(days=7): """ Most active cour in the last days Parameters ---------- days : int, optional DESCRIPTION. Last Days to filter. The default is 7. Returns ------- Court object with the most active Court in the last days. """ filter_after = datetime.today() - timedelta(days=days) disputes = Dispute.query.filter( Dispute.timestamp >= filter_after).all() counts = {} for dispute in disputes: try: counts[dispute.subcourtID] += 1 except KeyError: counts[dispute.subcourtID] = 1 try: mostActive = max(counts, key=counts.get) return {mostActive: counts[mostActive]} except Exception: return None @staticmethod def timeEvolution(): """ Return the timestamp and Dispute amounts """ disputes = db.session.query(Dispute.id, Dispute.timestamp).all() allDisputes = [] for dispute in disputes: allDisputes.append({ 'timestamp': dispute.timestamp, 'id': dispute.id }) return allDisputes @staticmethod def disputesCountByCourt(): data = Dispute.query.with_entities(Dispute.subcourtID, func.count(Dispute.id)).\ group_by(Dispute.subcourtID).all() result = {} for item in data: result[Court(id=item[0]).map_name] = item[1] return result @staticmethod def disputesCountByCreator(): data = Dispute.query.with_entities(Dispute.creator, func.count(Dispute.id)).\ group_by(Dispute.creator).all() result = {} for item in data: name = ContractMapper.searchName(item[0]) if name in list(result.keys()): result[name] += item[1] else: result[name] = item[1] return result