mirror of
https://github.com/inventree/InvenTree.git
synced 2026-10-14 14:11:55 +00:00
fix style nitpicks (#12995)
* disable restriction (for now) * reduce duplication * remove duplication in scim view * fix diff * fix reassign * remove statment that is always wrong * log with full context * allign order to anguage defaults * adress shelldre:S7688
This commit is contained in:
1 parent
600dc1a75b
commit
104adebbf4
13 files changed
+94
-111
No files matched your search
@@ -199,7 +199,7 @@ def load_config_data(set_cache: bool = False) -> map | None:
|
||||
try:
|
||||
data = yaml.safe_load(cfg)
|
||||
except yaml.parser.ParserError as error:
|
||||
logger.error(
|
||||
logger.exception(
|
||||
"INVE-E13: Error reading InvenTree configuration file '%s': %s",
|
||||
cfg_file,
|
||||
error,
|
||||
|
||||
@@ -2423,9 +2423,7 @@ class OrderCalendarExport(ICalFeed):
|
||||
whether or not to show completed orders. Defaults to false
|
||||
"""
|
||||
|
||||
instance_url = get_base_url()
|
||||
|
||||
instance_url = instance_url.replace('http://', '').replace('https://', '')
|
||||
instance_url = get_base_url().replace('http://', '').replace('https://', '')
|
||||
timezone = settings.TIME_ZONE
|
||||
file_name = 'calendar.ics'
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ from plugin.base.supplier import helpers as supplier
|
||||
from plugin.mixins import SettingsMixin
|
||||
|
||||
PartData = TypeVar('PartData')
|
||||
NOT_IMPLEMENTED_ERROR = 'This method needs to be overridden.'
|
||||
|
||||
|
||||
class SupplierMixin(SettingsMixin, Generic[PartData]):
|
||||
@@ -50,25 +51,25 @@ class SupplierMixin(SettingsMixin, Generic[PartData]):
|
||||
# --- Methods to be overridden by plugins ---
|
||||
def get_suppliers(self) -> list[supplier.Supplier]:
|
||||
"""Return a list of available suppliers."""
|
||||
raise NotImplementedError('This method needs to be overridden.')
|
||||
raise NotImplementedError(NOT_IMPLEMENTED_ERROR)
|
||||
|
||||
def get_search_results(
|
||||
self, supplier_slug: str, term: str
|
||||
) -> list[supplier.SearchResult]:
|
||||
"""Return a list of search results for the given search term."""
|
||||
raise NotImplementedError('This method needs to be overridden.')
|
||||
raise NotImplementedError(NOT_IMPLEMENTED_ERROR)
|
||||
|
||||
def get_import_data(self, supplier_slug: str, part_id: str) -> PartData:
|
||||
"""Return the import data for the given part ID."""
|
||||
raise NotImplementedError('This method needs to be overridden.')
|
||||
raise NotImplementedError(NOT_IMPLEMENTED_ERROR)
|
||||
|
||||
def get_pricing_data(self, data: PartData) -> dict[int, tuple[float, str]]:
|
||||
"""Return a dictionary of pricing data for the given part data."""
|
||||
raise NotImplementedError('This method needs to be overridden.')
|
||||
raise NotImplementedError(NOT_IMPLEMENTED_ERROR)
|
||||
|
||||
def get_parameters(self, data: PartData) -> list[supplier.ImportParameter]:
|
||||
"""Return a list of parameters for the given part data."""
|
||||
raise NotImplementedError('This method needs to be overridden.')
|
||||
raise NotImplementedError(NOT_IMPLEMENTED_ERROR)
|
||||
|
||||
def import_part(
|
||||
self,
|
||||
@@ -86,7 +87,7 @@ class SupplierMixin(SettingsMixin, Generic[PartData]):
|
||||
- create related parts
|
||||
- add attachments to the part
|
||||
"""
|
||||
raise NotImplementedError('This method needs to be overridden.')
|
||||
raise NotImplementedError(NOT_IMPLEMENTED_ERROR)
|
||||
|
||||
def import_manufacturer_part(
|
||||
self, data: PartData, *, part: part_models.Part
|
||||
@@ -101,7 +102,7 @@ class SupplierMixin(SettingsMixin, Generic[PartData]):
|
||||
- Adding parameters to the manufacturer part
|
||||
- Adding attachments to the manufacturer part
|
||||
"""
|
||||
raise NotImplementedError('This method needs to be overridden.')
|
||||
raise NotImplementedError(NOT_IMPLEMENTED_ERROR)
|
||||
|
||||
def import_supplier_part(
|
||||
self,
|
||||
@@ -116,7 +117,7 @@ class SupplierMixin(SettingsMixin, Generic[PartData]):
|
||||
- Creating a new supplier part
|
||||
- Creating supplier price breaks
|
||||
"""
|
||||
raise NotImplementedError('This method needs to be overridden.')
|
||||
raise NotImplementedError(NOT_IMPLEMENTED_ERROR)
|
||||
|
||||
# --- Helper methods for importing parts ---
|
||||
def download_image(self, img_url: str):
|
||||
|
||||
@@ -7,7 +7,7 @@ from django.shortcuts import get_object_or_404
|
||||
|
||||
import structlog
|
||||
from drf_spectacular.utils import extend_schema
|
||||
from pydantic import ValidationError
|
||||
from pydantic import BaseModel, ValidationError
|
||||
from rest_framework.decorators import (
|
||||
api_view,
|
||||
authentication_classes,
|
||||
@@ -70,9 +70,19 @@ class ScimParser(JSONParser):
|
||||
media_type = 'application/scim+json'
|
||||
|
||||
|
||||
def scim_dump(obj) -> dict:
|
||||
"""Serialize a scim2_models object to a plain (JSON-safe) dict."""
|
||||
return obj.model_dump(mode='json', exclude_none=True, by_alias=True)
|
||||
class ScimResponse(Response):
|
||||
"""Custom Response class for SCIM protocol responses."""
|
||||
|
||||
def __init__(self, data, *args, **kwargs):
|
||||
"""Like Response but with the scim suff auto-solved."""
|
||||
if isinstance(data, DjangoUser):
|
||||
data = user_to_scim(data)
|
||||
elif isinstance(data, DjangoGroup):
|
||||
data = group_to_scim(data)
|
||||
|
||||
if isinstance(data, BaseModel):
|
||||
data = data.model_dump(mode='json', exclude_none=True, by_alias=True)
|
||||
super().__init__(data, *args, content_type='application/scim+json', **kwargs)
|
||||
|
||||
|
||||
def scim_error(status: int, detail: str, scim_type: str | None = None) -> Response:
|
||||
@@ -83,9 +93,7 @@ def scim_error(status: int, detail: str, scim_type: str | None = None) -> Respon
|
||||
scim_type=scim_type,
|
||||
detail=detail,
|
||||
)
|
||||
return Response(
|
||||
scim_dump(error), status=status, content_type='application/scim+json'
|
||||
)
|
||||
return ScimResponse(error, status=status)
|
||||
|
||||
|
||||
class ScimAPIView(APIView):
|
||||
@@ -168,7 +176,7 @@ class ServiceProviderConfigView(ScimAPIView):
|
||||
)
|
||||
],
|
||||
)
|
||||
return Response(scim_dump(config), content_type='application/scim+json')
|
||||
return ScimResponse(config)
|
||||
|
||||
|
||||
class ResourceTypesView(ScimAPIView):
|
||||
@@ -202,9 +210,7 @@ class ResourceTypesView(ScimAPIView):
|
||||
resource_type = self.resource_types.get(name)
|
||||
if not resource_type:
|
||||
return scim_error(404, f"ResourceType '{name}' not found")
|
||||
return Response(
|
||||
scim_dump(resource_type), content_type='application/scim+json'
|
||||
)
|
||||
return ScimResponse(resource_type)
|
||||
|
||||
resources = list(self.resource_types.values())
|
||||
response = ListResponse[ResourceType](
|
||||
@@ -214,7 +220,7 @@ class ResourceTypesView(ScimAPIView):
|
||||
start_index=1,
|
||||
resources=resources,
|
||||
)
|
||||
return Response(scim_dump(response), content_type='application/scim+json')
|
||||
return ScimResponse(response)
|
||||
|
||||
|
||||
class SchemasView(ScimAPIView):
|
||||
@@ -233,7 +239,7 @@ class SchemasView(ScimAPIView):
|
||||
schema = schemas.get(schema_id)
|
||||
if not schema:
|
||||
return scim_error(404, f"Schema '{schema_id}' not found")
|
||||
return Response(scim_dump(schema), content_type='application/scim+json')
|
||||
return ScimResponse(schema)
|
||||
|
||||
resources = list(schemas.values())
|
||||
response = ListResponse[Schema](
|
||||
@@ -243,7 +249,7 @@ class SchemasView(ScimAPIView):
|
||||
start_index=1,
|
||||
resources=resources,
|
||||
)
|
||||
return Response(scim_dump(response), content_type='application/scim+json')
|
||||
return ScimResponse(response)
|
||||
|
||||
|
||||
class BaseResourceView(ScimAPIView):
|
||||
@@ -291,7 +297,7 @@ class BaseResourceView(ScimAPIView):
|
||||
start_index=start_index,
|
||||
resources=resources,
|
||||
)
|
||||
return Response(scim_dump(response), content_type='application/scim+json')
|
||||
return ScimResponse(response)
|
||||
|
||||
|
||||
class UsersView(BaseResourceView):
|
||||
@@ -325,11 +331,8 @@ class UsersView(BaseResourceView):
|
||||
|
||||
logger.info('SCIM: provisioned new user', username=user.username)
|
||||
|
||||
return Response(
|
||||
scim_dump(user_to_scim(user)),
|
||||
status=201,
|
||||
content_type='application/scim+json',
|
||||
headers={'Location': user_location(user.pk)},
|
||||
return ScimResponse(
|
||||
user, status=201, headers={'Location': user_location(user.pk)}
|
||||
)
|
||||
|
||||
|
||||
@@ -343,9 +346,7 @@ class UserDetailView(ScimAPIView):
|
||||
def get(self, request, pk, *args, **kwargs):
|
||||
"""Retrieve a single user."""
|
||||
user = self.get_object(pk)
|
||||
return Response(
|
||||
scim_dump(user_to_scim(user)), content_type='application/scim+json'
|
||||
)
|
||||
return ScimResponse(user)
|
||||
|
||||
def put(self, request, pk, *args, **kwargs):
|
||||
"""Replace a user's attributes."""
|
||||
@@ -353,9 +354,7 @@ class UserDetailView(ScimAPIView):
|
||||
scim_user = User.model_validate(request.data)
|
||||
apply_scim_to_user(scim_user, user)
|
||||
user.save()
|
||||
return Response(
|
||||
scim_dump(user_to_scim(user)), content_type='application/scim+json'
|
||||
)
|
||||
return ScimResponse(user)
|
||||
|
||||
def patch(self, request, pk, *args, **kwargs):
|
||||
"""Apply a SCIM PATCH operation set to a user."""
|
||||
@@ -368,9 +367,7 @@ class UserDetailView(ScimAPIView):
|
||||
apply_scim_to_user(scim_user, user)
|
||||
user.save()
|
||||
|
||||
return Response(
|
||||
scim_dump(user_to_scim(user)), content_type='application/scim+json'
|
||||
)
|
||||
return ScimResponse(user)
|
||||
|
||||
def delete(self, request, pk, *args, **kwargs):
|
||||
"""Deactivate a user.
|
||||
@@ -414,11 +411,8 @@ class GroupsView(BaseResourceView):
|
||||
|
||||
logger.info('SCIM: provisioned new group', name=group.name)
|
||||
|
||||
return Response(
|
||||
scim_dump(group_to_scim(group)),
|
||||
status=201,
|
||||
content_type='application/scim+json',
|
||||
headers={'Location': group_location(group.pk)},
|
||||
return ScimResponse(
|
||||
group, status=201, headers={'Location': group_location(group.pk)}
|
||||
)
|
||||
|
||||
|
||||
@@ -432,9 +426,7 @@ class GroupDetailView(ScimAPIView):
|
||||
def get(self, request, pk, *args, **kwargs):
|
||||
"""Retrieve a single group."""
|
||||
group = self.get_object(pk)
|
||||
return Response(
|
||||
scim_dump(group_to_scim(group)), content_type='application/scim+json'
|
||||
)
|
||||
return ScimResponse(group)
|
||||
|
||||
def put(self, request, pk, *args, **kwargs):
|
||||
"""Replace a group's attributes and membership."""
|
||||
@@ -443,9 +435,7 @@ class GroupDetailView(ScimAPIView):
|
||||
apply_scim_to_group(scim_group, group)
|
||||
group.save()
|
||||
set_group_members(group, scim_group.members)
|
||||
return Response(
|
||||
scim_dump(group_to_scim(group)), content_type='application/scim+json'
|
||||
)
|
||||
return ScimResponse(group)
|
||||
|
||||
def patch(self, request, pk, *args, **kwargs):
|
||||
"""Apply a SCIM PATCH operation set to a group (used mainly for membership changes)."""
|
||||
@@ -459,9 +449,7 @@ class GroupDetailView(ScimAPIView):
|
||||
group.save()
|
||||
set_group_members(group, scim_group.members)
|
||||
|
||||
return Response(
|
||||
scim_dump(group_to_scim(group)), content_type='application/scim+json'
|
||||
)
|
||||
return ScimResponse(group)
|
||||
|
||||
def delete(self, request, pk, *args, **kwargs):
|
||||
"""Remove a group."""
|
||||
|
||||
@@ -338,9 +338,9 @@ export function BomCompareDrawer({
|
||||
// Show only *common* parts
|
||||
rows = rows.filter((row) => row.match);
|
||||
break;
|
||||
default:
|
||||
case 'all':
|
||||
break;
|
||||
default:
|
||||
}
|
||||
|
||||
// Return rows, sorted by part name
|
||||
|
||||
Reference in new issue
Block a user