Clean up base modules

This commit is contained in:
jeremystretch 2023-04-13 14:37:56 -04:00
parent 59a6b3e71b
commit 2dc50b6108
20 changed files with 118 additions and 27 deletions

View File

@ -2,7 +2,7 @@ from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
from django.db import transaction from django.db import transaction
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django_pglocks import advisory_lock from django_pglocks import advisory_lock
from drf_spectacular.utils import extend_schema, extend_schema_view from drf_spectacular.utils import extend_schema
from rest_framework import status from rest_framework import status
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.routers import APIRootView from rest_framework.routers import APIRootView
@ -15,7 +15,7 @@ from ipam.models import *
from netbox.api.viewsets import NetBoxModelViewSet from netbox.api.viewsets import NetBoxModelViewSet
from netbox.api.viewsets.mixins import ObjectValidationMixin from netbox.api.viewsets.mixins import ObjectValidationMixin
from netbox.config import get_config from netbox.config import get_config
from utilities.constants import ADVISORY_LOCK_KEYS from netbox.constants import ADVISORY_LOCK_KEYS
from utilities.utils import count_related from utilities.utils import count_related
from . import serializers from . import serializers
from ipam.models import L2VPN, L2VPNTermination from ipam.models import L2VPN, L2VPNTermination

View File

@ -5,3 +5,14 @@ NESTED_SERIALIZER_PREFIX = 'Nested'
RQ_QUEUE_DEFAULT = 'default' RQ_QUEUE_DEFAULT = 'default'
RQ_QUEUE_HIGH = 'high' RQ_QUEUE_HIGH = 'high'
RQ_QUEUE_LOW = 'low' RQ_QUEUE_LOW = 'low'
# Keys for PostgreSQL advisory locks. These are arbitrary bigints used by the advisory_lock
# context manager. When a lock is acquired, one of these keys will be used to identify said lock.
# When adding a new key, pick something arbitrary and unique so that it is easily searchable in
# query logs.
ADVISORY_LOCK_KEYS = {
'available-prefixes': 100100,
'available-ips': 100200,
'available-vlans': 100300,
'available-asns': 100400,
}

View File

@ -10,6 +10,13 @@ from rest_framework.utils import formatting
from netbox.api.exceptions import GraphQLTypeNotFound, SerializerNotFound from netbox.api.exceptions import GraphQLTypeNotFound, SerializerNotFound
from .utils import dynamic_import from .utils import dynamic_import
__all__ = (
'get_graphql_type_for_model',
'get_serializer_for_model',
'get_view_name',
'is_api_request',
)
def get_serializer_for_model(model, prefix=''): def get_serializer_for_model(model, prefix=''):
""" """

View File

@ -31,21 +31,6 @@ FILTER_TREENODE_NEGATION_LOOKUP_MAP = dict(
n='in' n='in'
) )
# Keys for PostgreSQL advisory locks. These are arbitrary bigints used by
# the advisory_lock contextmanager. When a lock is acquired,
# one of these keys will be used to identify said lock.
#
# When adding a new key, pick something arbitrary and unique so
# that it is easily searchable in query logs.
ADVISORY_LOCK_KEYS = {
'available-prefixes': 100100,
'available-ips': 100200,
'available-vlans': 100300,
'available-asns': 100400,
}
# #
# HTTP Request META safe copy # HTTP Request META safe copy
# #

View File

@ -3,6 +3,7 @@ from rest_framework.exceptions import APIException
__all__ = ( __all__ = (
'AbortRequest', 'AbortRequest',
'AbortScript',
'AbortTransaction', 'AbortTransaction',
'PermissionsViolation', 'PermissionsViolation',
'RQWorkerNotRunningException', 'RQWorkerNotRunningException',

View File

@ -1,21 +1,23 @@
from collections import defaultdict from collections import defaultdict
from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.fields import GenericForeignKey
from django.core.validators import RegexValidator
from django.db import models from django.db import models
from utilities.ordering import naturalize from utilities.ordering import naturalize
from .forms import ColorSelect from .forms import ColorSelect
from .validators import ColorValidator
ColorValidator = RegexValidator( __all__ = (
regex='^[0-9a-f]{6}$', 'ColorField',
message='Enter a valid hexadecimal RGB color code.', 'NaturalOrderingField',
code='invalid' 'NullableCharField',
'RestrictedGenericForeignKey',
) )
# Deprecated: Retained only to ensure successful migration from early releases # Deprecated: Retained only to ensure successful migration from early releases
# Use models.CharField(null=True) instead # Use models.CharField(null=True) instead
# TODO: Remove in v4.0
class NullableCharField(models.CharField): class NullableCharField(models.CharField):
description = "Stores empty values as NULL rather than ''" description = "Stores empty values as NULL rather than ''"

View File

@ -1,5 +1,9 @@
import hashlib import hashlib
__all__ = (
'sha256_hash',
)
def sha256_hash(filepath): def sha256_hash(filepath):
""" """

View File

@ -6,6 +6,22 @@ from django_filters.constants import EMPTY_VALUES
from drf_spectacular.utils import extend_schema_field from drf_spectacular.utils import extend_schema_field
from drf_spectacular.types import OpenApiTypes from drf_spectacular.types import OpenApiTypes
__all__ = (
'ContentTypeFilter',
'MACAddressFilter',
'MultiValueCharFilter',
'MultiValueDateFilter',
'MultiValueDateTimeFilter',
'MultiValueDecimalFilter',
'MultiValueMACAddressFilter',
'MultiValueNumberFilter',
'MultiValueTimeFilter',
'MultiValueWWNFilter',
'NullableCharFieldFilter',
'NumericArrayFilter',
'TreeNodeMultipleChoiceFilter',
)
def multivalue_field_factory(field_class): def multivalue_field_factory(field_class):
""" """

View File

@ -1,20 +1,23 @@
import functools import functools
import graphql
from django.core.exceptions import FieldDoesNotExist from django.core.exceptions import FieldDoesNotExist
from django.db.models import ForeignKey, Prefetch from django.db.models import ForeignKey
from django.db.models.constants import LOOKUP_SEP from django.db.models.constants import LOOKUP_SEP
from django.db.models.fields.reverse_related import ManyToOneRel from django.db.models.fields.reverse_related import ManyToOneRel
from graphene import InputObjectType from graphene import InputObjectType
from graphene.types.generic import GenericScalar from graphene.types.generic import GenericScalar
from graphene.types.resolver import default_resolver from graphene.types.resolver import default_resolver
from graphene_django import DjangoObjectType from graphene_django import DjangoObjectType
from graphql import FieldNode, GraphQLObjectType, GraphQLResolveInfo, GraphQLSchema from graphql import GraphQLResolveInfo, GraphQLSchema
from graphql.execution.execute import get_field_def from graphql.execution.execute import get_field_def
from graphql.language.ast import FragmentSpreadNode, InlineFragmentNode, VariableNode from graphql.language.ast import FragmentSpreadNode, InlineFragmentNode, VariableNode
from graphql.pyutils import Path from graphql.pyutils import Path
from graphql.type.definition import GraphQLInterfaceType, GraphQLUnionType from graphql.type.definition import GraphQLInterfaceType, GraphQLUnionType
__all__ = (
'gql_query_optimizer',
)
def gql_query_optimizer(queryset, info, **options): def gql_query_optimizer(queryset, info, **options):
return QueryOptimizer(info).optimize(queryset) return QueryOptimizer(info).optimize(queryset)

View File

@ -1,5 +1,10 @@
from urllib.parse import urlparse from urllib.parse import urlparse
__all__ = (
'is_embedded',
'is_htmx',
)
def is_htmx(request): def is_htmx(request):
""" """

View File

@ -1,6 +1,10 @@
import markdown import markdown
from markdown.inlinepatterns import SimpleTagPattern from markdown.inlinepatterns import SimpleTagPattern
__all__ = (
'StrikethroughExtension',
)
STRIKE_RE = r'(~{2})(.+?)(~{2})' STRIKE_RE = r'(~{2})(.+?)(~{2})'

View File

@ -3,6 +3,10 @@ from timezone_field import TimeZoneField
from netbox.config import ConfigItem from netbox.config import ConfigItem
__all__ = (
'custom_deconstruct',
)
SKIP_FIELDS = ( SKIP_FIELDS = (
TimeZoneField, TimeZoneField,

View File

@ -4,6 +4,11 @@ from mptt.querysets import TreeQuerySet as TreeQuerySet_
from django.db.models import Manager from django.db.models import Manager
from .querysets import RestrictedQuerySet from .querysets import RestrictedQuerySet
__all__ = (
'TreeManager',
'TreeQuerySet',
)
class TreeQuerySet(TreeQuerySet_, RestrictedQuerySet): class TreeQuerySet(TreeQuerySet_, RestrictedQuerySet):
""" """

View File

@ -1,5 +1,10 @@
import re import re
__all__ = (
'naturalize',
'naturalize_interface',
)
INTERFACE_NAME_REGEX = r'(^(?P<type>[^\d\.:]+)?)' \ INTERFACE_NAME_REGEX = r'(^(?P<type>[^\d\.:]+)?)' \
r'((?P<slot>\d+)/)?' \ r'((?P<slot>\d+)/)?' \
r'((?P<subslot>\d+)/)?' \ r'((?P<subslot>\d+)/)?' \

View File

@ -2,6 +2,12 @@ from django.core.paginator import Paginator, Page
from netbox.config import get_config from netbox.config import get_config
__all__ = (
'EnhancedPage',
'EnhancedPaginator',
'get_paginate_count',
)
class EnhancedPaginator(Paginator): class EnhancedPaginator(Paginator):
default_page_lengths = ( default_page_lengths = (

View File

@ -1,5 +1,10 @@
from django.contrib.postgres.aggregates import JSONBAgg from django.contrib.postgres.aggregates import JSONBAgg
from django.db.models import F, Func from django.db.models import Func
__all__ = (
'CollateAsChar',
'EmptyGroupByJSONBAgg',
)
class CollateAsChar(Func): class CollateAsChar(Func):

View File

@ -3,6 +3,11 @@ from django.db.models import Prefetch, QuerySet
from users.constants import CONSTRAINT_TOKEN_USER from users.constants import CONSTRAINT_TOKEN_USER
from utilities.permissions import permission_is_exempt, qs_filter_from_constraints from utilities.permissions import permission_is_exempt, qs_filter_from_constraints
__all__ = (
'RestrictedPrefetch',
'RestrictedQuerySet',
)
class RestrictedPrefetch(Prefetch): class RestrictedPrefetch(Prefetch):
""" """

View File

@ -1,3 +1,8 @@
__all__ = (
'linkify_phone',
)
def linkify_phone(value): def linkify_phone(value):
""" """
Render a telephone number as a hyperlink. Render a telephone number as a hyperlink.

View File

@ -4,6 +4,10 @@ from django.views.generic import View
from netbox.registry import registry from netbox.registry import registry
__all__ = (
'get_model_urls',
)
def get_model_urls(app_label, model_name): def get_model_urls(app_label, model_name):
""" """

View File

@ -1,10 +1,24 @@
import re import re
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.core.validators import _lazy_re_compile, BaseValidator, URLValidator from django.core.validators import BaseValidator, RegexValidator, URLValidator, _lazy_re_compile
from netbox.config import get_config from netbox.config import get_config
__all__ = (
'ColorValidator',
'EnhancedURLValidator',
'ExclusionValidator',
'validate_regex',
)
ColorValidator = RegexValidator(
regex='^[0-9a-f]{6}$',
message='Enter a valid hexadecimal RGB color code.',
code='invalid'
)
class EnhancedURLValidator(URLValidator): class EnhancedURLValidator(URLValidator):
""" """