mirror of
https://github.com/peeringdb/peeringdb.git
synced 2024-05-11 05:55:09 +00:00
* fix next redirect when using U2F 2FA auth (#1191) * Added self identifier to API * fix migrations hierarchy after merging in previous support branch * campus object Co-authored-by: Stefan Pratter <stefan@20c.com> * fix out of bound error message add city / country to campus view * fix tests * relock poetry * linting * linting * fix docs regen * regen docs * linting * refactor self entity view to support carrier and campus object types and also make it easier to support additional object types in the future * remove debug message --------- Co-authored-by: Gajanan Patil <dipaksavaliya.python@gmail.com>
271 lines
7.0 KiB
Python
271 lines
7.0 KiB
Python
"""
|
|
Defines django-haystack search indexes.
|
|
"""
|
|
|
|
from django.conf import settings
|
|
from django.db.models import Q
|
|
from haystack import indexes
|
|
|
|
from peeringdb_server.models import (
|
|
Campus,
|
|
Facility,
|
|
InternetExchange,
|
|
IXLanPrefix,
|
|
Network,
|
|
NetworkIXLan,
|
|
Organization,
|
|
)
|
|
from peeringdb_server.search import unaccent
|
|
|
|
|
|
class EntityIndex(indexes.SearchIndex):
|
|
|
|
"""
|
|
Search index for org, net, ix and fac entities.
|
|
"""
|
|
|
|
text = indexes.CharField(document=True, use_template=True)
|
|
status = indexes.CharField(model_attr="status")
|
|
|
|
class Meta:
|
|
relations = []
|
|
|
|
def get_model(self):
|
|
pass
|
|
|
|
def _append_filter(self, filters, filter):
|
|
if filters:
|
|
filters |= filter
|
|
else:
|
|
filters = filter
|
|
return filters
|
|
|
|
def build_queryset(self, using=None, start_date=None, end_date=None):
|
|
relations = self.Meta.relations
|
|
qset = self.index_queryset()
|
|
|
|
if not start_date and not end_date:
|
|
qset = qset.filter(status="ok")
|
|
|
|
if relations:
|
|
qset = qset.select_related(*relations)
|
|
|
|
if start_date:
|
|
qset = qset.filter(updated__gte=start_date)
|
|
|
|
if end_date:
|
|
qset = qset.filter(updated__lte=end_date)
|
|
|
|
if not relations or (not start_date and not end_date):
|
|
return qset
|
|
|
|
filters = None
|
|
|
|
filter_map = [
|
|
(start_date, "updated__gte"),
|
|
(end_date, "updated__lte"),
|
|
]
|
|
|
|
for date, filter in filter_map:
|
|
if not date:
|
|
continue
|
|
|
|
# filter by object's updated times
|
|
|
|
filters = self._append_filter(filters, Q(**{filter: date}))
|
|
|
|
# filter by object's relevant relationship updated times
|
|
|
|
for relation in relations:
|
|
_filter = Q(
|
|
**{
|
|
f"{relation}__{filter}": date,
|
|
}
|
|
)
|
|
filters = self._append_filter(filters, _filter)
|
|
|
|
if filters:
|
|
qset = qset.filter(filters)
|
|
|
|
return qset
|
|
|
|
def get_updated_field(self):
|
|
"""
|
|
Use this field to determine object age. This
|
|
is required for the --age parameter to function
|
|
in the update_index command.
|
|
"""
|
|
return "updated"
|
|
|
|
def prepare(self, obj):
|
|
self.prepared_data = super().prepare(obj)
|
|
self.prepared_data["text"] = unaccent(self.prepared_data["text"])
|
|
return self.prepared_data
|
|
|
|
|
|
class MainEntity(EntityIndex):
|
|
name = indexes.CharField()
|
|
auto = indexes.EdgeNgramField()
|
|
result_name = indexes.CharField(model_attr="search_result_name", indexed=False)
|
|
|
|
def prepare_auto(self, obj):
|
|
return self.prepare_name(obj)
|
|
|
|
def prepare_name(self, obj):
|
|
return unaccent(f"{obj.name} {obj.aka} {obj.name_long}")
|
|
|
|
def prepare(self, obj):
|
|
data = super().prepare(obj)
|
|
data["boost"] = settings.SEARCH_MAIN_ENTITY_BOOST
|
|
return data
|
|
|
|
|
|
class OrganizationIndex(MainEntity, indexes.Indexable):
|
|
def get_model(self):
|
|
return Organization
|
|
|
|
|
|
class CampusIndex(MainEntity, indexes.Indexable):
|
|
def get_model(self):
|
|
return Campus
|
|
|
|
|
|
class InternetExchangeIndex(MainEntity, indexes.Indexable):
|
|
org_id = indexes.IntegerField(indexed=False, model_attr="org_id")
|
|
|
|
class Meta:
|
|
relations = ["org"]
|
|
|
|
def get_model(self):
|
|
return InternetExchange
|
|
|
|
|
|
class NetworkIndex(MainEntity, indexes.Indexable):
|
|
org_id = indexes.IntegerField(indexed=False, model_attr="org_id")
|
|
asn = indexes.IntegerField(indexed=False, model_attr="asn")
|
|
|
|
class Meta:
|
|
relations = ["org"]
|
|
|
|
def get_model(self):
|
|
return Network
|
|
|
|
def prepare_auto(self, obj):
|
|
asn = obj.asn
|
|
return f"{self.prepare_name(obj)} AS{asn} AS-{asn} {asn}"
|
|
|
|
|
|
class FacilityIndex(MainEntity, indexes.Indexable):
|
|
org_id = indexes.IntegerField(indexed=False, model_attr="org_id")
|
|
|
|
class Meta:
|
|
relations = ["org"]
|
|
|
|
def get_model(self):
|
|
return Facility
|
|
|
|
|
|
class NetworkIXLanIndex(EntityIndex, indexes.Indexable):
|
|
ix_id = indexes.IntegerField(indexed=False, model_attr="ixlan__ix__id")
|
|
ix_org_id = indexes.IntegerField(indexed=False, model_attr="ixlan__ix__org_id")
|
|
ix_result_name = indexes.CharField(indexed=False)
|
|
|
|
net_id = indexes.IntegerField(indexed=False, model_attr="network_id")
|
|
net_org_id = indexes.IntegerField(indexed=False, model_attr="network__org_id")
|
|
net_result_name = indexes.CharField(indexed=False)
|
|
|
|
net_sub_result_name = indexes.CharField(indexed=False)
|
|
ix_sub_result_name = indexes.CharField(indexed=False)
|
|
|
|
ipaddr4 = indexes.CharField(indexed=False)
|
|
ipaddr6 = indexes.CharField(indexed=False)
|
|
|
|
class Meta:
|
|
relations = ["network", "ixlan__ix", "network__org", "ixlan__ix__org"]
|
|
|
|
def get_model(self):
|
|
return NetworkIXLan
|
|
|
|
def prepare_ix_result_name(self, obj):
|
|
return obj.ixlan.ix.search_result_name
|
|
|
|
def prepare_net_result_name(self, obj):
|
|
return obj.network.search_result_name
|
|
|
|
def prepare_ix_sub_result_name(self, obj):
|
|
if obj.ipaddr4 and obj.ipaddr6:
|
|
return f"{obj.ipaddr4} {obj.ipaddr6}"
|
|
elif obj.ipaddr4:
|
|
return f"{obj.ipaddr4}"
|
|
elif obj.ipaddr6:
|
|
return f"{obj.ipaddr6}"
|
|
|
|
def prepare_net_sub_result_name(self, obj):
|
|
ips = self.prepare_ix_sub_result_name(obj)
|
|
return f"{obj.ixlan.ix.search_result_name} {ips}"
|
|
|
|
def prepare_ipaddr4(self, obj):
|
|
if obj.ipaddr4:
|
|
return str(obj.ipaddr4)
|
|
else:
|
|
return ""
|
|
|
|
def prepare_ipaddr6(self, obj):
|
|
if obj.ipaddr6:
|
|
return str(obj.ipaddr6)
|
|
else:
|
|
return ""
|
|
|
|
|
|
class IXLanPrefixIndex(EntityIndex, indexes.Indexable):
|
|
ix_id = indexes.IntegerField(indexed=False, model_attr="ixlan__ix__id")
|
|
ix_org_id = indexes.IntegerField(indexed=False, model_attr="ixlan__ix__org_id")
|
|
ix_result_name = indexes.CharField(indexed=False)
|
|
|
|
class Meta:
|
|
relations = ["ixlan__ix", "ixlan__ix__org"]
|
|
|
|
def get_model(self):
|
|
return IXLanPrefix
|
|
|
|
def prepare_ix_result_name(self, obj):
|
|
return obj.ixlan.ix.search_result_name
|
|
|
|
def prepare_ix_sub_result_name(self, obj):
|
|
return obj.prefix
|
|
|
|
|
|
# The following models are currently not indexed
|
|
"""
|
|
class NetworkFacilityIndex(EntityIndex, indexes.Indexable):
|
|
class Meta:
|
|
relations = ["network", "facility", "network__org", "facility__org"]
|
|
|
|
def get_model(self):
|
|
return NetworkFacility
|
|
|
|
|
|
class InternetExchangeFacilityIndex(EntityIndex, indexes.Indexable):
|
|
class Meta:
|
|
relations = ["ix", "ix__org", "facility", "facility__org"]
|
|
|
|
def get_model(self):
|
|
return InternetExchangeFacility
|
|
|
|
|
|
|
|
class NetworkContactIndex(EntityIndex, indexes.Indexable):
|
|
class Meta:
|
|
relations = ["network", "network__org"]
|
|
|
|
def get_model(self):
|
|
return NetworkContact
|
|
|
|
|
|
class IXLanIndex(EntityIndex, indexes.Indexable):
|
|
class Meta:
|
|
relations = ["ix", "ix__org"]
|
|
|
|
def get_model(self):
|
|
"""
|