# SPDX-FileCopyrightText: 2022 The Tor Project, Inc.
#
# SPDX-License-Identifier: BSD-3-Clause
import datetime
import logging
from django.db import models
from django.db.models import Q
from onbasca.base import constants
from . import BaseModel
logger = logging.getLogger(__name__)
# KeyValues to keep for now
BWFILE_KEYS = [
"timestamp",
"version",
"destinations_countries",
"earliest_bandwidth",
"file_created",
"generator_started",
"latest_bandwidth",
# The following could be renamed as
# 'consensus_size', 'eligible_count', 'eligible_percent', 'min_count',
# 'min_percent',
"minimum_number_eligible_relays",
"minimum_percent_eligible_relays",
"number_consensus_relays",
"number_eligible_relays",
"percent_eligible_relays",
"recent_consensus_count",
# Next could be included in the future
# 'measurements',
"recent_measurements_excluded_error_count",
# Next 5 should not be needed in the future
"recent_measurements_excluded_few_count",
"recent_measurements_excluded_near_count",
"recent_measurements_excluded_old_count",
"recent_priority_list_count",
"recent_priority_relay_count",
"scanner_country",
"software",
"software_version",
"time_to_report_half_network",
"tor_version",
]
[docs]
class BwFileManagerBase(models.Manager):
pass
[docs]
class BwFileBase(BaseModel):
objects = BwFileManagerBase()
file_created = models.DateTimeField(
unique=True, editable=True, null=True, blank=True
)
latest_bandwidth = models.DateTimeField(null=True, blank=True)
scanner_country = models.CharField(
max_length=2,
null=True,
blank=True,
)
software = models.CharField(
max_length=64, null=True, blank=True, default="onbasca"
)
# logger.debug("Software version: %s.", __version__)
software_version = models.CharField(max_length=32, null=True, blank=True)
tor_version = models.CharField(
max_length=64,
null=True,
blank=True,
# default=Scanner.load().tor_version,
)
def __str__(self):
return "{}".format(self.file_created)
# for admin
[docs]
def consensus_routerstatuses_count(self):
if self.consensus:
return self.consensus.routerstatus_set.all().count()
return 0
[docs]
def relaybw_set_count(self):
return self.relaybw_set.count()
[docs]
def relaybw_set_vote_count(self):
return self.relaybw_set.filter(
Q(vote=True) | Q(vote__isnull=True)
).count()
[docs]
def to_str_v15(self):
headers = [
str(int(self.file_created.timestamp())),
"{}={}".format("version", self.version),
]
BWFILE_KEYS.remove("timestamp")
BWFILE_KEYS.remove("version")
for key in BWFILE_KEYS:
value = getattr(self, key, "")
# if value:
if isinstance(value, datetime.datetime):
value = value.strftime(constants.DATETIME_FORMAT)
headers.append("{}={}".format(key, value))
headers_str = "\n".join(headers)
relay_lines_str = "\n".join(
[
relaybw.to_str()
for relaybw in self.relaybw_set.order_by("-vote", "bw")
]
)
return "{}\n{}\n{}".format(
headers_str, constants.TERMINATOR, relay_lines_str
)
[docs]
def to_str(self):
return self.to_str_v15()