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 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 Posts(db.Model): __tablename__ = 'posts' id = db.Column(db.Integer, primary_key=True, autoincrement=True) author_id = db.Column(db.Integer) title = db.Column(db.String(60)) content = db.Column(db.TEXT) publication_datetime = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
class Config(db.Model): id = db.Column(db.Integer, primary_key=True) option = db.Column(db.String(50)) value = db.Column(db.String(50)) @classmethod def get(cls, db_key): query = cls.query.filter(cls.option == db_key).first() if query is None: return None return query.value @classmethod def set(cls, db_key, db_val): query = cls.query.filter(cls.option == db_key) for item in query: db.session.delete(item) new_option = cls(option=db_key, value=db_val) db.session.add(new_option) db.session.commit()
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 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 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 ContractMapper(db.Model): id = db.Column(db.Integer, primary_key=True) address = db.Column(db.String(50)) contract_name = db.Column(db.String(100)) dapp_name = db.Column(db.String(100)) def __repr__(self): return f'ContractMapper({self.address}, {self.name})' def __str__(self): return f"{self.name}" @staticmethod def searchName(address): DappsMapper = { '0x594ec762b59978c97c82bc36ab493ed8b1f1f368'.lower(): 'Realitio', '0x701cabaf65ed3974925fb94988842a29d2ce7aa3'.lower(): 'Realitio', '0xd47f72a2d1d0e91b0ec5e5f5d02b2dc26d00a14d'.lower(): 'Realitio', '0xd7e143715a4244634d74201959372e81a3623a2a'.lower(): 'Realitio', '0x126697b552b83f08c7ebebae8d13eae2871e4e1e'.lower(): 'Realitio', '0xb72103ee8819f2480c25d306eeab7c3382fba612'.lower(): 'Curate', '0x1E9c3b5f57974beAdbd8C28Ba918d85b8477C618'.lower(): 'Curate', '0x941b4A0dfDC7f15275A4cb6913b395647BB69Fc3'.lower(): 'Curate', '0x6f15Ca438992d9a4d7281E7E80381C4d904B2A24'.lower(): 'Curate', '0x99A0f0e0d9Ee776D791D2E55c215d05ccF7286fC'.lower(): 'Curate', '0x7884a7ADf697e18357087FE8F994669042Af4ae9'.lower(): 'Curate', '0x8eFfF9BB64ED3d766a26a18e873cf171E67BeCf2'.lower(): 'Curate', '0x250aa88c8f54f5e70b94214380342f0d53e42f6c'.lower(): 'Curate', '0x7f112a0dc0ac7be95ac3c58532485f60726bb42c'.lower(): 'Curate', '0x0d67440946949fe293b45c52efd8a9b3d51e2522'.lower(): 'T2CR', '0x916deab80dfbc7030277047cd18b233b3ce5b4ab'.lower(): 'T2CR', '0xcb4aae35333193232421e86cd2e9b6c91f3b125f'.lower(): 'T2CR', '0xe0cf18e8630545aa553f88079c75dae56b8fb304'.lower(): 'T2CR', '0xebcf3bca271b26ae4b162ba560e243055af0e679'.lower(): 'T2CR', '0x46580533db92c418a79f91b46df70283daef7f99'.lower(): 'Escrow', '0x135c573503f70dc290b1d60fe2e7f7eb114febd6'.lower(): 'Dispute Resolver', '0xc9a3cd210cc9c11982c3acf7b7bf9b1083242cb6'.lower(): 'Dispute Resolver', '0x799cb978dea5d6ca00ccb1794d3c3d4c89e40cd1'.lower(): 'Dispute Resolver', '0xd8bf5114796ed28aa52cff61e1b9ef4ec1f69a54'.lower(): 'Dispute Resolver', '0xf65c7560d6ce320cc3a16a07f1f65aab66396b9e'.lower(): 'Dispute Resolver', '0xc7e49251807780dFBbCA72778890B80bd946590B'.lower(): 'Onboarding Tester', '0xF339047C85d0dd2645F2bD802a1e8a5e7AF61053'.lower(): 'Curate', '0x2E3B10aBf091cdc53cC892A50daBDb432e220398'.lower(): 'Curate', '0xD8F8019c025C2Ba6745543D9a3C338DE1b98C103'.lower(): 'Linguo' } contract = ContractMapper().query.filter( ContractMapper.address == address.lower()).first() if contract: if contract.dapp_name != "Unknown": return contract.dapp_name else: print(f"Unknown dapp name with address {address}") return contract.contract_name else: logger.debug( "Searching in HardCoded / Etherscan and adding to the database" ) if address.lower() in list(DappsMapper.keys()): dappName = DappsMapper[address.lower()] else: dappName = "Unknown" name = Etherscan.getContractName(address) if not name: name = "Unknown" logger.info( f"The address {address} could not be found neither in the Database or Etherscan" ) db.session.add( ContractMapper(address=address, contract_name=name, dapp_name=dappName)) db.session.commit() logger.info( f"Contract {address} added to the DataBase with name {name}") return dappName
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