Skip to content
Commits on Source (7)
......@@ -22,7 +22,7 @@ class BuildingSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Building
exclude = ()
exclude = []
class RoomSerializer(serializers.HyperlinkedModelSerializer):
......@@ -32,7 +32,7 @@ class RoomSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Room
exclude = ()
exclude = []
class ManufacturerSerializer(serializers.HyperlinkedModelSerializer):
......@@ -41,13 +41,13 @@ class ManufacturerSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Manufacturer
exclude = ()
exclude = []
class TypeAttributeSerializer(serializers.ModelSerializer):
class Meta:
model = TypeAttribute
exclude = ("devicetype", )
exclude = ["devicetype"]
class TypeSerializer(serializers.HyperlinkedModelSerializer):
......@@ -57,7 +57,7 @@ class TypeSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Type
exclude = ()
exclude = []
class TemplateSerializer(serializers.HyperlinkedModelSerializer):
......@@ -66,7 +66,7 @@ class TemplateSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Template
exclude = ()
exclude = []
class LendingDisplaySerializer(serializers.ModelSerializer):
......@@ -75,14 +75,13 @@ class LendingDisplaySerializer(serializers.ModelSerializer):
class Meta:
model = Lending
exclude = ()
exclude = []
class PictureSerializer(serializers.ModelSerializer):
class Meta:
model = Picture
fields = ("id", "image", "caption")
fields = ["id", "image", "caption"]
class DeviceSerializer(serializers.HyperlinkedModelSerializer):
......@@ -92,7 +91,10 @@ class DeviceSerializer(serializers.HyperlinkedModelSerializer):
room = serializers.SlugRelatedField(slug_field="name", queryset=Room.objects.select_related("building").all())
devicetype = serializers.SlugRelatedField(slug_field="name", queryset=Type.objects.all())
ip_addresses = serializers.SlugRelatedField(
many=True, source="ipaddress_set", slug_field="address", queryset=IpAddress.objects.all(),
many=True,
source="ipaddress_set",
slug_field="address",
queryset=IpAddress.objects.all(),
)
creator = serializers.StringRelatedField(read_only=True)
creator_url = serializers.HyperlinkedIdentityField(view_name="user-api-detail")
......@@ -104,7 +106,7 @@ class DeviceSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Device
exclude = ("bookmarkers", )
exclude = ["bookmarkers"]
class DeviceIDSerializer(serializers.ModelSerializer):
......@@ -112,7 +114,7 @@ class DeviceIDSerializer(serializers.ModelSerializer):
class Meta:
model = Device
exclude = ("bookmarkers", )
exclude = ["bookmarkers"]
class DeviceListSerializer(serializers.HyperlinkedModelSerializer):
......@@ -122,7 +124,7 @@ class DeviceListSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Device
fields = ("url", "id", "name", "department")
fields = ["url", "id", "name", "department"]
class DeviceRoomSerializer(serializers.HyperlinkedModelSerializer):
......@@ -132,7 +134,7 @@ class DeviceRoomSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Device
fields = ("url", "id", "room")
fields = ["url", "id", "room"]
class LendingSerializer(serializers.ModelSerializer):
......@@ -140,7 +142,7 @@ class LendingSerializer(serializers.ModelSerializer):
class Meta:
model = Lending
exclude = ("lenddate", "duedate_email", "returndate")
exclude = ["lenddate", "duedate_email", "returndate"]
def validate(self, attrs):
if "smalldevice" in attrs and "device" in attrs:
......@@ -180,13 +182,13 @@ class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Lageruser
exclude = ("password", )
exclude = ["password"]
class UserAvatarSerializer(serializers.ModelSerializer):
class Meta:
model = Lageruser
fields = ("username", "avatar")
fields = ["username", "avatar"]
class UserListSerializer(serializers.HyperlinkedModelSerializer):
......@@ -195,7 +197,7 @@ class UserListSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Lageruser
fields = ("url", "id", "username", "first_name", "last_name", "email")
fields = ["url", "id", "username", "first_name", "last_name", "email"]
class GroupSerializer(serializers.HyperlinkedModelSerializer):
......@@ -206,7 +208,7 @@ class GroupSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Group
exclude = ()
exclude = []
class IpAddressSerializer(serializers.HyperlinkedModelSerializer):
......@@ -217,4 +219,4 @@ class IpAddressSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = IpAddress
exclude = ()
exclude = []
......@@ -187,7 +187,6 @@ class DeviceApiLend(generics.CreateAPIView):
class DeviceApiReturn(APIView):
def post(self, request, *args, **kwargs):
if "lending" not in request.DATA:
return Response({"error": "you need to provide a valid lending id"}, status=status.HTTP_400_BAD_REQUEST)
......@@ -213,7 +212,6 @@ class DeviceApiReturn(APIView):
template = None
messages.error(self.request, _("MAIL NOT SENT - Template for room change does not exist"))
if template is not None:
template.send(self.request, data={"device": device, "user": self.request.user})
reversion.set_comment(_("Device returned and moved to room {0}").format(device.room))
device.save()
......
......@@ -17,7 +17,6 @@ logger = logging.getLogger(__name__)
class DeviceDetails(View):
@staticmethod
def get(request, device):
device = get_object_or_404(Device, pk=device)
......@@ -26,15 +25,12 @@ class DeviceDetails(View):
except Exception as e:
logger.error(e)
return HttpResponse(_("Could not load data."))
context = {
"device_info": device_info.raw_entries
}
context = {"device_info": device_info.raw_entries}
_update_provided_data(device, device_info)
return render(request, "devicedata/device_info.html", context)
class DeviceDetailsJson(View):
@staticmethod
def get(request, device):
device = get_object_or_404(Device, pk=device)
......@@ -42,19 +38,20 @@ class DeviceDetailsJson(View):
if provider is None:
return JsonResponse({})
device_info = provider.get_device_info(device)
raw_entries = [{"name": entry.name,
"type": entry.type,
"raw_value": as_nested_list(entry.raw_value)} for entry in device_info.raw_entries]
raw_entries = [
{"name": entry.name, "type": entry.type, "raw_value": as_nested_list(entry.raw_value)}
for entry in device_info.raw_entries
]
new_entries = _update_provided_data(device, device_info)
formatted_entries = [{"name": entry.name,
"value": entry.formatted_value,
"stored_at": timesince(entry.stored_at)} for entry in new_entries]
formatted_entries = [
{"name": entry.name, "value": entry.formatted_value, "stored_at": timesince(entry.stored_at)}
for entry in new_entries
]
return JsonResponse({"raw_entries": raw_entries, "formatted_entries": formatted_entries})
class DeviceSoftware(View):
@staticmethod
def get(request, device):
device = get_object_or_404(Device, pk=device)
......@@ -63,7 +60,5 @@ class DeviceSoftware(View):
except Exception as e:
logger.error(e)
return HttpResponse(_("Could not load data."))
context = {
"software_info": software_info
}
context = {"software_info": software_info}
return render(request, "devicedata/software_info.html", context)
......@@ -5,7 +5,6 @@ from lagerregal.devices.models import Device
class Command(BaseCommand):
def add_arguments(self, parser):
parser.add_argument("device_ids", nargs="*", type=int)
......
......@@ -6,7 +6,6 @@ from lagerregal.devices.models import Device
class Command(BaseCommand):
def add_arguments(self, parser):
parser.add_argument("device_ids", nargs="*", type=int)
parser.add_argument("-f", "--force", action="store_true", dest="force")
......
......@@ -53,7 +53,6 @@ class SoftwareEntry:
class BaseProvider(ABC):
@abstractmethod
def get_device_info(self, device):
pass
......@@ -70,7 +69,6 @@ class BaseProvider(ABC):
def build_full_hostname(device):
hostname = device.hostname.lower()
if len(hostname) > 0:
if hasattr(settings, "HOST_BASE_DOMAIN") and not hostname.endswith(
settings.HOST_BASE_DOMAIN):
if hasattr(settings, "HOST_BASE_DOMAIN") and not hostname.endswith(settings.HOST_BASE_DOMAIN):
hostname += "." + settings.HOST_BASE_DOMAIN
return hostname
......@@ -13,12 +13,12 @@ from lagerregal.devicedata.providers.opsirpc import OpsiConnection
class OpsiDeviceInfo(BaseDeviceInfo):
def format_chassis(self):
entries = self.find_entries("CHASSIS")
if len(entries) > 0:
self.formatted_entries.append(
FormattedDeviceInfoEntry(_("Serial Number"), entries[0].raw_value["serialNumber"]))
FormattedDeviceInfoEntry(_("Serial Number"), entries[0].raw_value["serialNumber"])
)
self.formatted_entries.append(FormattedDeviceInfoEntry(_("Type"), entries[0].raw_value["chassisType"]))
def format_system(self):
......@@ -27,8 +27,11 @@ class OpsiDeviceInfo(BaseDeviceInfo):
self.formatted_entries.append(FormattedDeviceInfoEntry(_("Manufacturer"), entries[0].raw_value["vendor"]))
hostname = build_full_hostname(self.device)
if entries[0].raw_value["hostId"] != hostname:
self.formatted_entries.append(FormattedDeviceInfoEntry(_("Hostname"), "<span class='text-warning'>"
+ entries[0].raw_value["hostId"] + "</span>"))
self.formatted_entries.append(
FormattedDeviceInfoEntry(
_("Hostname"), "<span class='text-warning'>" + entries[0].raw_value["hostId"] + "</span>"
)
)
else:
self.formatted_entries.append(FormattedDeviceInfoEntry(_("Hostname"), entries[0].raw_value["hostId"]))
self.formatted_entries.append(FormattedDeviceInfoEntry(_("Last Seen"), entries[0].raw_value["lastseen"]))
......@@ -46,7 +49,8 @@ class OpsiDeviceInfo(BaseDeviceInfo):
total_capacity = format_bytes(sum(capacities))
formatted_capacities = ", ".join([format_bytes(capacity) for capacity in capacities])
self.formatted_entries.append(
FormattedDeviceInfoEntry(_("Memory"), f"{total_capacity} ({formatted_capacities})"))
FormattedDeviceInfoEntry(_("Memory"), f"{total_capacity} ({formatted_capacities})")
)
def format_storage(self):
entries = self.find_entries("HARDDISK_DRIVE")
......@@ -55,7 +59,8 @@ class OpsiDeviceInfo(BaseDeviceInfo):
if "USB" not in entry.raw_value["name"]:
drives.append(entry.raw_value)
formatted_capacities = "<br />".join(
f"{drive['model']} {format_bytes(drive['size'], power=1000)}" for drive in drives)
f"{drive['model']} {format_bytes(drive['size'], power=1000)}" for drive in drives
)
self.formatted_entries.append(FormattedDeviceInfoEntry(_("Storage"), formatted_capacities))
def format_network(self):
......
......@@ -10,7 +10,6 @@ opsicon_logger = logging.getLogger(__name__)
class OpsiError(Exception):
def __init__(self, expression, opsierrorclass, message):
"""
......@@ -24,7 +23,6 @@ class OpsiError(Exception):
class OpsiConnection:
def __init__(self, url, username=None, password=None, certfile=None, legal_methods_path=None):
# 0 is not a valid id
"""
......@@ -76,9 +74,11 @@ class OpsiConnection:
if name in self.legal_methods:
def _rpc_call(*args, **kwargs):
self.id += 1
payload = {"method": name,
"params": [list(args)[1:], kwargs] if len(kwargs) > 0 else list(args)[1:],
"id": self.id}
payload = {
"method": name,
"params": [list(args)[1:], kwargs] if len(kwargs) > 0 else list(args)[1:],
"id": self.id,
}
opsicon_logger.debug("Interpreting as rpc call: \n%s}" % payload)
return self.__rpc_request(self.session, payload)
......
......@@ -19,7 +19,6 @@ from lagerregal.devicedata.providers.helpers import format_bytes
class PuppetDeviceInfo(BaseDeviceInfo):
def format_serialnumber(self):
entries = self.find_entries("sp_serial_number")
entries.extend(self.find_entries("serialnumber"))
......@@ -36,8 +35,11 @@ class PuppetDeviceInfo(BaseDeviceInfo):
if len(entries) > 0:
hostname = build_full_hostname(self.device)
if entries[0].raw_value != hostname:
self.formatted_entries.append(FormattedDeviceInfoEntry(_("Hostname"), "<span class='text-warning'>"
+ entries[0].raw_value + "</span>"))
self.formatted_entries.append(
FormattedDeviceInfoEntry(
_("Hostname"), "<span class='text-warning'>" + entries[0].raw_value + "</span>"
)
)
else:
self.formatted_entries.append(FormattedDeviceInfoEntry(_("Hostname"), entries[0].raw_value))
......@@ -50,15 +52,13 @@ class PuppetDeviceInfo(BaseDeviceInfo):
entries = self.find_entries("processors")
if len(entries) > 0:
processors = {processor for processor in entries[0].raw_value["models"]}
self.formatted_entries.append(
FormattedDeviceInfoEntry(_("Processor"), "<br />".join(processors)))
self.formatted_entries.append(FormattedDeviceInfoEntry(_("Processor"), "<br />".join(processors)))
def format_memory(self):
entries = self.find_entries("memory")
if len(entries) > 0:
system = entries[0].raw_value["system"]
self.formatted_entries.append(
FormattedDeviceInfoEntry(_("Memory"), format_bytes(system["total_bytes"])))
self.formatted_entries.append(FormattedDeviceInfoEntry(_("Memory"), format_bytes(system["total_bytes"])))
def format_storage(self):
entries = self.find_entries("disks")
......
......@@ -66,7 +66,7 @@ class DevicegroupList(PermissionRequiredMixin, PaginationMixin, ListView):
# Call the base implementation first to get a context
context = super().get_context_data(**kwargs)
context["breadcrumbs"] = [
(reverse("devicegroup-list"), _("Devicegroups"))
(reverse("devicegroup-list"), _("Devicegroups")),
]
context["viewform"] = DepartmentViewForm(initial={
"sorting": self.viewsorting,
......@@ -106,7 +106,8 @@ class DevicegroupDetail(PermissionRequiredMixin, DetailView):
# add devicegroup to breadcrumbs
context["breadcrumbs"] = [
(reverse("devicegroup-list"), _("Devicegroups")),
(reverse("devicegroup-detail", kwargs={"pk": self.object.pk}), self.object)]
(reverse("devicegroup-detail", kwargs={"pk": self.object.pk}), self.object),
]
devices = Device.objects.filter(group=context["devicegroup"], archived=None)
context["device_list"] = devices.order_by("inventorynumber")
......@@ -131,7 +132,8 @@ class DevicegroupCreate(PermissionRequiredMixin, CreateView):
# add "create new device" to breadcrumbs
context["breadcrumbs"] = [
(reverse("devicegroup-list"), _("Devicegroups")),
("", _("Create new devicegroup"))]
("", _("Create new devicegroup")),
]
return context
......@@ -150,7 +152,8 @@ class DevicegroupUpdate(PermissionRequiredMixin, UpdateView):
context["breadcrumbs"] = [
(reverse("devicegroup-list"), _("Devicegroups")),
(reverse("devicegroup-detail", kwargs={"pk": self.object.pk}), self.object),
("", _("Edit"))]
("", _("Edit")),
]
return context
......@@ -169,6 +172,7 @@ class DevicegroupDelete(PermissionRequiredMixin, DeleteView):
context["breadcrumbs"] = [
(reverse("devicegroup-list"), _("Devicegroups")),
(reverse("devicegroup-detail", kwargs={"pk": self.object.pk}), self.object),
("", _("Delete"))]
("", _("Delete")),
]
return context
......@@ -147,7 +147,7 @@ class PreviewMail(View):
"room": request.GET.get("device[room]", ""),
"serialnumber": request.GET.get("device[serialnumber]", ""),
"templending": request.GET.get("device[templending]", ""),
"webinterface": request.GET.get("device[webinterface]", "")
"webinterface": request.GET.get("device[webinterface]", ""),
}
if template == "":
return HttpResponse("")
......@@ -168,18 +168,22 @@ class PreviewMail(View):
del device["room"]
template = get_object_or_404(MailTemplate, pk=template)
datadict = {"device": device, "user": {
"username": request.user.username,
"first_name": request.user.first_name,
"last_name": request.user.last_name
}}
data = {"subject": pystache.render(template.subject, datadict),
"body": pystache.render(template.body, datadict).replace("\n", "<br />")}
datadict = {
"device": device,
"user": {
"username": request.user.username,
"first_name": request.user.first_name,
"last_name": request.user.last_name,
},
}
data = {
"subject": pystache.render(template.subject, datadict),
"body": pystache.render(template.body, datadict).replace("\n", "<br />"),
}
return HttpResponse(json.dumps(data), content_type="application/json")
class LoadMailtemplate(View):
def get(self, request):
template = request.GET["template"]
recipients = request.GET.get("recipients[]", [])
......@@ -190,8 +194,9 @@ class LoadMailtemplate(View):
if isinstance(recipients, str):
recipients = [recipients]
newrecipients = [obj for obj in recipients]
newrecipients += [obj.content_type.name[0].lower() + str(obj.object_id) for obj in
template.default_recipients.all()]
newrecipients += [
obj.content_type.name[0].lower() + str(obj.object_id) for obj in template.default_recipients.all()
]
newrecipients = list(set(newrecipients))
data["recipients"] = newrecipients
return HttpResponse(json.dumps(data), content_type="application/json")
......@@ -213,8 +218,12 @@ class UserLendings(View):
device["pk"],
]
for device in user.lending_set.filter(returndate=None).values(
"pk", "device__name", "device__inventorynumber",
"device__serialnumber", "smalldevice", "duedate",
"pk",
"device__name",
"device__inventorynumber",
"device__serialnumber",
"smalldevice",
"duedate",
)
]
......
......@@ -2,5 +2,7 @@ from django.conf import settings # import the settings file
def get_settings(request):
return {"SITE_NAME": settings.SITE_NAME,
"LABEL_TEMPLATES": settings.LABEL_TEMPLATES}
return {
"SITE_NAME": settings.SITE_NAME,
"LABEL_TEMPLATES": settings.LABEL_TEMPLATES,
}
......@@ -27,7 +27,7 @@ CHARMODIFIER = (
("icontains", _("Contains")),
("istartswith", _("Starts with")),
("iendswith", _("Ends with")),
("iexact", _("Exact"))
("iexact", _("Exact")),
)
CATEGORIES = (
......@@ -40,7 +40,7 @@ CATEGORIES = (
("overdue", _("Overdue Devices")),
("returnsoon", _("Return soon Devices")),
("temporary", _("Short term Devices")),
("bookmark", _("Bookmarked Devices"))
("bookmark", _("Bookmarked Devices")),
)
VIEWSORTING_DEVICES = (
......@@ -68,7 +68,7 @@ VIEWSORTING = (
DEPARTMENT_OPTIONS = [
("all", _("All Departments")),
("my", _("My Departments"))
("my", _("My Departments")),
]
......@@ -90,9 +90,7 @@ def get_emailrecipientlist(special=None):
objects = []
if special:
objects.append(
(_("Special"), [(value, key) for key, value in special.items()])
)
objects.append((_("Special"), [(value, key) for key, value in special.items()]))
objects.append(
(_("Groups"), [("g" + str(group.id), group.name) for group in Group.objects.all().order_by("name")])
......@@ -108,7 +106,8 @@ class IpAddressForm(forms.Form):
error_css_class = "has-error"
ipaddresses = forms.ModelMultipleChoiceField(
IpAddress.objects.filter(device=None, user=None),
widget=Select2MultipleWidget(attrs={"data-token-separators": '[",", " "]'}))
widget=Select2MultipleWidget(attrs={"data-token-separators": '[",", " "]'}),
)
class IpAddressPurposeForm(forms.Form):
......@@ -118,20 +117,33 @@ class IpAddressPurposeForm(forms.Form):
class LendForm(forms.Form):
error_css_class = "has-error"
owner = forms.ModelChoiceField(Lageruser.objects.filter(is_active=True).order_by("last_name"),
widget=Select2Widget(),
label=_("Lent to"))
device = forms.ModelChoiceField(Device.objects.all(), widget=Select2Widget(),
label=_("Device"), required=False)
smalldevice = forms.CharField(widget=forms.TextInput(attrs={"class": "form-control form-control-sm"}),
required=False)
duedate = forms.DateField(required=False, input_formats=("%Y-%m-%d", "%m/%d/%Y", "%m/%d/%y", "%b %d %Y",
"%b %d, %Y", "%d %b %Y", "%d %b, %Y", "%B %d %Y",
"%B %d, %Y", "%d %B %Y", "%d %B, %Y", "%d.%m.%Y",
"%d.%m.%y"),
widget=forms.TextInput(attrs={"class": "form-control form-control-sm"}))
room = forms.ModelChoiceField(Room.objects.select_related("building").all(), required=False,
widget=Select2Widget())
owner = forms.ModelChoiceField(
Lageruser.objects.filter(is_active=True).order_by("last_name"), widget=Select2Widget(), label=_("Lent to")
)
device = forms.ModelChoiceField(Device.objects.all(), widget=Select2Widget(), label=_("Device"), required=False)
smalldevice = forms.CharField(
widget=forms.TextInput(attrs={"class": "form-control form-control-sm"}), required=False
)
duedate = forms.DateField(
required=False,
input_formats=(
"%Y-%m-%d",
"%m/%d/%Y",
"%m/%d/%y",
"%b %d %Y",
"%b %d, %Y",
"%d %b %Y",
"%d %b, %Y",
"%B %d %Y",
"%B %d, %Y",
"%d %B %Y",
"%d %B, %Y",
"%d.%m.%Y",
"%d.%m.%y",
),
widget=forms.TextInput(attrs={"class": "form-control form-control-sm"}),
)
room = forms.ModelChoiceField(Room.objects.select_related("building").all(), required=False, widget=Select2Widget())
def clean(self):
cleaned_data = super().clean()
......@@ -225,27 +237,26 @@ class DeviceGroupFilterForm(FilterForm):
class DeviceForm(forms.ModelForm):
error_css_class = "has-error"
uses = forms.MultipleChoiceField(choices=Device.objects.none(), required=False,
widget=Select2MultipleWidget())
emailrecipients = forms.MultipleChoiceField(required=False,
widget=Select2MultipleWidget())
emailtemplate = forms.ModelChoiceField(queryset=MailTemplate.objects.all(), required=False, label=_("Template"),
widget=Select2Widget())
uses = forms.MultipleChoiceField(choices=Device.objects.none(), required=False, widget=Select2MultipleWidget())
emailrecipients = forms.MultipleChoiceField(required=False, widget=Select2MultipleWidget())
emailtemplate = forms.ModelChoiceField(
queryset=MailTemplate.objects.all(), required=False, label=_("Template"), widget=Select2Widget()
)
emailedit = forms.BooleanField(required=False, label=_("Edit template"))
emailsubject = forms.CharField(required=False, label=_("Subject"))
emailbody = forms.CharField(widget=forms.Textarea(), required=False, label=_("Body"))
description = forms.CharField(widget=forms.Textarea(attrs={"style": "height:80px"}), max_length=1000,
required=False)
description = forms.CharField(
widget=forms.Textarea(attrs={"style": "height:80px"}), max_length=1000, required=False
)
webinterface = forms.URLField(max_length=60, required=False)
creator = forms.ModelChoiceField(queryset=Lageruser.objects.all(), widget=forms.HiddenInput())
comment = forms.CharField(required=False)
devicetype = forms.ModelChoiceField(Type.objects.annotate(size=Count("device")), required=False,
widget=Select2Widget())
manufacturer = forms.ModelChoiceField(Manufacturer.objects.all(), required=False,
widget=Select2Widget())
room = forms.ModelChoiceField(Room.objects.select_related("building").all(), required=False,
widget=Select2Widget())
devicetype = forms.ModelChoiceField(
Type.objects.annotate(size=Count("device")), required=False, widget=Select2Widget()
)
manufacturer = forms.ModelChoiceField(Manufacturer.objects.all(), required=False, widget=Select2Widget())
room = forms.ModelChoiceField(Room.objects.select_related("building").all(), required=False, widget=Select2Widget())
class Meta:
model = Device
......@@ -256,14 +267,16 @@ class DeviceForm(forms.ModelForm):
unclean_data = []
if cleaned_data["emailrecipients"] and not cleaned_data["emailtemplate"]:
self._errors["emailtemplate"] = self.error_class(
[_("You specified recipients, but didn't select a template")])
[_("You specified recipients, but didn't select a template")]
)
for key, attribute in cleaned_data.items():
if key.startswith("attribute_") and attribute != "":
attributenumber = key.split("_")[1]
typeattribute = get_object_or_404(TypeAttribute, pk=attributenumber)
if typeattribute.regex is not None and re.match(typeattribute.regex, attribute) is None:
self._errors[key] = self.error_class(
[_(f"Doesn't match the given regex \"{typeattribute.regex}\".")])
[_(f'Doesn\'t match the given regex "{typeattribute.regex}".')]
)
unclean_data.append(key)
for i in unclean_data:
del cleaned_data[i]
......@@ -274,20 +287,22 @@ class DeviceForm(forms.ModelForm):
# if edit
if kwargs["instance"]:
CHOICES = [(x.id, "".join((x.name, " [", str(x.id), "]"))) for x in
Device.objects.filter(trashed=None).exclude(pk=kwargs["instance"].id).order_by("name")]
self.fields["uses"].choices = CHOICES
self.fields["uses"].choices = [
(x.id, f"{x.name} [{x.id}]")
for x in Device.objects.filter(trashed=None).exclude(pk=kwargs["instance"].id).order_by("name")
]
self.initial["uses"] = [x.id for x in Device.objects.filter(used_in=kwargs["instance"].id)]
self.fields["used_in"].queryset = Device.objects.filter(trashed=None).exclude(pk=kwargs["instance"].id)
# if create
else:
CHOICES = [(x.id, "".join((x.name, " [", str(x.id), "]"))) for x in
Device.objects.filter(used_in=None, trashed=None).order_by("name")]
self.fields["uses"].choices = CHOICES
self.fields["uses"].choices = [
(x.id, f"{x.name} [{x.id}]")
for x in Device.objects.filter(used_in=None, trashed=None).order_by("name")
]
self.fields["used_in"].queryset = Device.objects.filter(trashed=None)
self.fields["used_in"].label_from_instance = lambda obj: "%s [%s]" % (obj.name, obj.id)
self.fields["used_in"].label_from_instance = lambda obj: f"{obj.name} [{obj.id}]"
self.fields["emailrecipients"].choices = get_emailrecipientlist()
if self.data != {}:
......@@ -313,16 +328,16 @@ class DeviceForm(forms.ModelForm):
attributes = []
for attribute in attributes:
# generate extra fields in the number specified via extra_fields
self.fields[f"attribute_{attribute.pk}"] = \
forms.CharField(label=attribute.name,
widget=forms.TextInput(attrs={"class": "extra_attribute form-control"}), required=False)
self.fields[f"attribute_{attribute.pk}"] = forms.CharField(
label=attribute.name,
widget=forms.TextInput(attrs={"class": "extra_attribute form-control"}),
required=False,
)
if f"attribute_{attribute.pk}" in self.data:
self.fields[f"attribute_{attribute.pk}"].initial = self.data[
f"attribute_{attribute.pk}"]
self.fields[f"attribute_{attribute.pk}"].initial = self.data[f"attribute_{attribute.pk}"]
else:
try:
self.fields[f"attribute_{attribute.pk}"].initial = attributevalues.get(
typeattribute=attribute.pk)
self.fields[f"attribute_{attribute.pk}"].initial = attributevalues.get(typeattribute=attribute.pk)
except Exception:
pass
......@@ -333,7 +348,8 @@ class DeviceFormAutomatic(forms.ModelForm):
ipaddresses = forms.ModelMultipleChoiceField(
IpAddress.objects.filter(device=None, user=None),
required=False,
widget=Select2MultipleWidget(attrs={"data-token-separators": '[",", " "]'}))
widget=Select2MultipleWidget(attrs={"data-token-separators": '[",", " "]'}),
)
class Meta:
model = Device
......@@ -357,7 +373,7 @@ class DeviceFormAutomatic(forms.ModelForm):
def save(self):
device = super().save()
device.hostname = "{0}-{1}-{2:06d}".format(
device.hostname = "{}-{}-{:06d}".format(
self.cleaned_data["department"].short_name,
self.cleaned_data["operating_system"],
device.pk,
......@@ -376,7 +392,8 @@ class AddForm(forms.ModelForm):
error_css_class = "has-error"
classname = forms.ChoiceField(
choices=[("manufacturer", "manufacturer"), ("devicetype", "devicetype"), ("room", "room"), ("group", "group")],
widget=forms.HiddenInput())
widget=forms.HiddenInput(),
)
def clean(self):
cleaned_data = super().clean()
......@@ -409,9 +426,12 @@ class DeviceTrashForm(forms.Form):
error_css_class = "has-error"
send_mail = forms.BooleanField(required=False, initial=True, label=_("Send E-Mail"))
generate_pdf = forms.BooleanField(required=False, initial=True, label=_("Generate PDF"))
reason = forms.CharField(required=False, label=_("Reason"),
widget=forms.Textarea(attrs={"style": "height:60px"}),
help_text=_("The reason will be printed on the generated PDF and added to the E-Mail sent"))
reason = forms.CharField(
required=False,
label=_("Reason"),
widget=forms.Textarea(attrs={"style": "height:60px"}),
help_text=_("The reason will be printed on the generated PDF and added to the E-Mail sent"),
)
class DeviceStorageForm(forms.Form):
......
......@@ -6,7 +6,7 @@ os_mapping = {
"w7": "win",
"w10": "win",
"win7": "win",
"win10": "win"
"win10": "win",
}
......@@ -17,10 +17,10 @@ class Command(BaseCommand):
old_name = device.name
device.name = device.name.split(" - ")[0]
device.save()
print("Renamed", old_name, "to", device.name)
self.stdout.write(f"Renamed {old_name} to {device.name}")
devices = Device.objects.filter(name__regex=r"\([a-zA-Z0-9\s]{8,50}\)")
for device in devices:
old_name = device.name
device.name = device.name.split(" (")[0]
device.save()
print("Renamed", old_name, "to", device.name)
self.stdout.write(f"Renamed {old_name} to {device.name}")
......@@ -7,7 +7,7 @@ os_mapping = {
"w7": "win",
"w10": "win",
"win7": "win",
"win10": "win"
"win10": "win",
}
......@@ -25,5 +25,5 @@ class Command(BaseCommand):
if osname == entry[0]:
device.operating_system = osname
device.save()
print("Set", device, "to", osname)
self.stdout.write(f"Set {device} to {osname}")
continue
......@@ -15,7 +15,18 @@ from lagerregal.users.models import Lageruser
class PagedResultsSearchObject(LDAPObject):
page_size = 50
def paged_search_ext_s(self, base, scope, filterstr="(objectClass=*)", attrlist=None, attrsonly=0, serverctrls=None, clientctrls=None, timeout=-1, sizelimit=0):
def paged_search_ext_s(
self,
base,
scope,
filterstr="(objectClass=*)",
attrlist=None,
attrsonly=0,
serverctrls=None,
clientctrls=None,
timeout=-1,
sizelimit=0,
):
"""
Behaves exactly like LDAPObject.search_ext_s() but internally uses the
simple paged results control to retrieve search results in chunks.
......@@ -28,7 +39,7 @@ class PagedResultsSearchObject(LDAPObject):
# Send first search request
msgid = self.search_ext(
*settings.LDAP_USER_SEARCH,
serverctrls=(serverctrls or []) + [req_ctrl]
serverctrls=(serverctrls or []) + [req_ctrl],
)
result_pages = 0
......@@ -39,11 +50,7 @@ class PagedResultsSearchObject(LDAPObject):
all_results.extend(rdata)
result_pages += 1
# Extract the simple paged results response control
pctrls = [
c
for c in rctrls
if c.controlType == SimplePagedResultsControl.controlType
]
pctrls = [c for c in rctrls if c.controlType == SimplePagedResultsControl.controlType]
if pctrls:
if pctrls[0].cookie:
# Copy cookie from response control to request control
......@@ -57,7 +64,7 @@ class PagedResultsSearchObject(LDAPObject):
class Command(BaseCommand):
def handle(self, *args, **options):
if not settings.USE_LDAP:
print("You have to enable the USE_LDAP setting to use the ldap import.")
self.stdout.write("You have to enable the USE_LDAP setting to use the ldap import.")
return
# ldap.set_option(ldap.OPT_DEBUG_LEVEL, 4095)
search = PagedResultsSearchObject(settings.AUTH_LDAP_SERVER_URI)
......@@ -72,7 +79,7 @@ class Command(BaseCommand):
for dn, userdata in users:
# paged results contains weird ldap references..
if not isinstance(userdata, dict):
print(userdata)
self.stdout.write(str(userdata))
continue
username = userdata["sAMAccountName"][0].decode("utf-8")
saveuser = False
......@@ -148,15 +155,15 @@ class Command(BaseCommand):
except Exception:
pass
print(f"{dn} does not have a value for the attribute {attr}")
self.stdout.write(f"{dn} does not have a value for the attribute {attr}")
if saveuser:
if user.is_active == expired:
if expired:
print(f"{dn} has expired")
self.stdout.write(f"{dn} has expired")
else:
print(f"{dn} has been reactivated")
self.stdout.write(f"{dn} has been reactivated")
for field, (old_value, new_value) in changes.items():
print(f"{dn} changed {field} from {old_value} to {new_value}")
self.stdout.write(f"{dn} changed {field} from {old_value} to {new_value}")
user.save()
if user.main_department:
if user.main_department not in user.departments.all():
......@@ -168,5 +175,5 @@ class Command(BaseCommand):
updated_users += 1
if created_users > 0 or updated_users > 0:
print(f"imported {created_users} new users.")
print(f"updated {updated_users} exisitng users.")
self.stdout.write(f"imported {created_users} new users.")
self.stdout.write(f"updated {updated_users} exisitng users.")
......@@ -58,13 +58,19 @@ class Device(models.Model):
webinterface = models.CharField(_("Webinterface"), max_length=60, blank=True)
templending = models.BooleanField(default=False, verbose_name=_("For short term lending"))
currentlending = models.ForeignKey("Lending", related_name="currentdevice", null=True, blank=True,
on_delete=models.SET_NULL)
currentlending = models.ForeignKey(
"Lending", related_name="currentdevice", null=True, blank=True, on_delete=models.SET_NULL
)
manual = models.FileField(upload_to=utils.get_file_location, null=True, blank=True)
contact = models.ForeignKey(Lageruser, related_name="as_contact",
help_text=_("Person to contact about using this device"), blank=True,
null=True, on_delete=models.SET_NULL)
contact = models.ForeignKey(
Lageruser,
related_name="as_contact",
help_text=_("Person to contact about using this device"),
blank=True,
null=True,
on_delete=models.SET_NULL,
)
archived = models.DateTimeField(null=True, blank=True)
trashed = models.DateTimeField(null=True, blank=True)
......@@ -76,7 +82,7 @@ class Device(models.Model):
department = models.ForeignKey(Department, null=True, blank=True, related_name="devices", on_delete=models.SET_NULL)
is_private = models.BooleanField(default=False)
used_in = models.ForeignKey("self", null=True, blank=True, on_delete=models.SET_NULL,)
used_in = models.ForeignKey("self", null=True, blank=True, on_delete=models.SET_NULL)
def __str__(self):
return self.name
......@@ -89,7 +95,7 @@ class Device(models.Model):
("managment_mails", _("Emails for managment")),
("support_mails", _("Emails for support")),
("lend_device", _("Can lend Device")),
("view_devicedetails", _("View Device Details"))
("view_devicedetails", _("View Device Details")),
)
def get_absolute_url(self):
......@@ -153,7 +159,8 @@ class Device(models.Model):
@staticmethod
def devices_for_departments(departments=[]):
return Device.objects.filter(department__in=departments).exclude(
~Q(department__in=departments), is_private=True)
~Q(department__in=departments), is_private=True
)
class DeviceInformationType(models.Model):
......
......@@ -20,7 +20,6 @@ def get_verbose_name(object):
@register.simple_tag
def history_compare(old, new):
if not isinstance(new, str):
try:
new = new.name
......@@ -42,12 +41,12 @@ def history_compare(old, new):
@register.filter("is_select")
def is_select(form_field_obj):
return (form_field_obj.field.widget.__class__.__name__ == "Select2Widget")
return form_field_obj.field.widget.__class__.__name__ == "Select2Widget"
@register.filter("is_selectmultiple")
def is_selectmultiple(form_field_obj):
return (form_field_obj.field.widget.__class__.__name__ == "Select2MultipleWidget")
return form_field_obj.field.widget.__class__.__name__ == "Select2MultipleWidget"
@register.filter(name="is_checkbox")
......@@ -63,13 +62,10 @@ def add_class(value, css_class):
string = str(value)
match = class_re.search(string)
if match:
m = re.search(r"^%s$|^%s\s|\s%s\s|\s%s$" % (css_class, css_class,
css_class, css_class),
match.group(1))
m = re.search(rf"^{css_class}$|^{css_class}\s|\s{css_class}\s|\s{css_class}$", match.group(1))
if m is not None:
return mark_safe(class_re.sub(match.group(1) + " " + css_class,
string))
return mark_safe(class_re.sub(match.group(1) + " " + css_class, string))
else:
return mark_safe(string.replace(">", ' class="%s">' % css_class))
return value
......@@ -143,9 +139,7 @@ def splitstr(arg1, arg2):
@register.inclusion_tag("snippets/deletebutton.html")
def deletebutton(viewname, *args):
return {
"url": reverse(viewname, args=args)
}
return {"url": reverse(viewname, args=args)}
@register.simple_tag(takes_context=True)
......
......@@ -23,7 +23,6 @@ from lagerregal.users.models import Lageruser
class DeviceTests(TestCase):
def setUp(self):
"""method for setting up a client for testing"""
self.client = Client()
......@@ -354,8 +353,9 @@ class ManufacturerTests(TestCase):
manufacturer = mommy.make(Manufacturer)
self.assertTrue(isinstance(manufacturer, Manufacturer))
self.assertEqual(str(manufacturer), manufacturer.name)
self.assertEqual(manufacturer.get_absolute_url(),
reverse("manufacturer-detail", kwargs={"pk": manufacturer.pk}))
self.assertEqual(
manufacturer.get_absolute_url(), reverse("manufacturer-detail", kwargs={"pk": manufacturer.pk})
)
self.assertEqual(manufacturer.get_edit_url(), reverse("manufacturer-edit", kwargs={"pk": manufacturer.pk}))
def test_list_view(self):
......@@ -487,7 +487,9 @@ class DeviceInformationTests(TestCase):
def test_device_information_creation(self):
device_information = mommy.make(DeviceInformation)
self.assertEqual(str(device_information), str(device_information.infotype) + ": " + device_information.information)
self.assertEqual(
str(device_information), str(device_information.infotype) + ": " + device_information.information
)
class PictureTests(TestCase):
......
This diff is collapsed.