xapian #1

Merged
cayop merged 26 commits from xapian into master 2024-09-17 10:11:28 +00:00
14 changed files with 233 additions and 678 deletions
Showing only changes of commit e2f9855954 - Show all commits

View File

@ -76,5 +76,3 @@ class InventaryMixin(DashboardView, TemplateView):
except Exception: except Exception:
pass pass
return super().get(request, *args, **kwargs) return super().get(request, *args, **kwargs)

View File

@ -44,7 +44,9 @@
<input type="checkbox" name="devices" value="{{ dev.id }}" /> <input type="checkbox" name="devices" value="{{ dev.id }}" />
</td> </td>
<td> <td>
<a href="{% url 'device:details' dev.pk %}">{{ dev.type }} {{ dev.manufacturer }} {{ dev.model }}</a> <a href="{% url 'device:details' dev.id %}">
{{ dev.type }} {{ dev.manufacturer }} {{ dev.model }}
</a>
</td> </td>
</tr> </tr>
</tbody> </tbody>

View File

@ -1,7 +1,11 @@
import json
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.db.models import Count from django.db.models import Count
from dashboard.mixins import InventaryMixin, DetailsMixin from dashboard.mixins import InventaryMixin, DetailsMixin
from device.models import Device from device.models import Device
from snapshot.xapian import search
from snapshot.models import Annotation
from lot.models import Lot from lot.models import Lot
@ -13,11 +17,29 @@ class UnassignedDevicesView(InventaryMixin):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
devices = Device.objects.filter( annotations = Annotation.objects.filter(
owner=self.request.user owner=self.request.user).filter(
).annotate(num_lots=Count('lot')).filter(num_lots=0) key="hidalgo1").order_by('created')
# 'created').distinct('value')
# ).annotate(num_lots=Count('lot')).filter(num_lots=0)
hids = {}
ids = []
for x in annotations:
if not hids.get(x.key):
hids[x.key] = x.uuid
ids.append(str(x.uuid))
devices = []
for xa in search(ids):
# import pdb; pdb.set_trace()
snap = json.loads(xa.document.get_data())
dev = snap.get("device", {})
dev["id"] = snap["uuid"]
devices.append(dev)
context.update({ context.update({
'devices': devices, 'devices': devices
}) })
return context return context

View File

@ -4,7 +4,7 @@
{% block content %} {% block content %}
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<h3>{{ object.pk }}</h3> <h3>{{ object.uuid }}</h3>
</div> </div>
</div> </div>
@ -45,7 +45,7 @@
<h5 class="card-title">Details</h5> <h5 class="card-title">Details</h5>
<div class="row mb-3"> <div class="row mb-3">
<div class="col-lg-3 col-md-4 label "> <div class="col-lg-3 col-md-4 label ">
(<a href="{% url 'device:edit' object.id %}">Edit Device</a>) (<a href="{% url 'device:edit' object.uuid %}">Edit Device</a>)
</div> </div>
<div class="col-lg-9 col-md-8"> <div class="col-lg-9 col-md-8">
{% if object.hid %}Snapshot{% else %}Placeholder{% endif %} {% if object.hid %}Snapshot{% else %}Placeholder{% endif %}
@ -54,7 +54,7 @@
<div class="row"> <div class="row">
<div class="col-lg-3 col-md-4 label ">Phid</div> <div class="col-lg-3 col-md-4 label ">Phid</div>
<div class="col-lg-9 col-md-8">{{ object.id }}</div> <div class="col-lg-9 col-md-8">{{ object.uuid }}</div>
</div> </div>
<div class="row"> <div class="row">
@ -69,22 +69,17 @@
<div class="row"> <div class="row">
<div class="col-lg-3 col-md-4 label">Manufacturer</div> <div class="col-lg-3 col-md-4 label">Manufacturer</div>
<div class="col-lg-9 col-md-8">{{ object.manufacturer|default:"" }}</div> <div class="col-lg-9 col-md-8">{{ object.device.manufacturer|default:"" }}</div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-lg-3 col-md-4 label">Model</div> <div class="col-lg-3 col-md-4 label">Model</div>
<div class="col-lg-9 col-md-8">{{ object.model|default:"" }}</div> <div class="col-lg-9 col-md-8">{{ object.device.model|default:"" }}</div>
</div>
<div class="row">
<div class="col-lg-3 col-md-4 label">Part Number</div>
<div class="col-lg-9 col-md-8">{{ object.part_number|default:"" }}</div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-lg-3 col-md-4 label">Serial Number</div> <div class="col-lg-3 col-md-4 label">Serial Number</div>
<div class="col-lg-9 col-md-8">{{ object.serial_number|default:"" }}</div> <div class="col-lg-9 col-md-8">{{ object.device.serialNumber|default:"" }}</div>
</div> </div>
</div> </div>
@ -92,7 +87,7 @@
<h5 class="card-title">Physical Properties</h5> <h5 class="card-title">Physical Properties</h5>
<div class="row mb-3"> <div class="row mb-3">
<div class="col-lg-3 col-md-4 label "> <div class="col-lg-3 col-md-4 label ">
(<a href="{% url 'device:physical_edit' object.pk %}">Edit Physical Properties</a>) (<a href="{% url 'device:physical_edit' object.uuid %}">Edit Physical Properties</a>)
</div> </div>
</div> </div>

View File

@ -5,7 +5,7 @@ app_name = 'device'
urlpatterns = [ urlpatterns = [
path("add/", views.NewDeviceView.as_view(), name="add"), path("add/", views.NewDeviceView.as_view(), name="add"),
path("edit/<int:pk>/", views.EditDeviceView.as_view(), name="edit"), path("edit/<uuid:pk>/", views.EditDeviceView.as_view(), name="edit"),
path("<int:pk>/", views.DetailsView.as_view(), name="details"), path("<uuid:pk>/", views.DetailsView.as_view(), name="details"),
path("physical/<int:pk>/", views.PhysicalView.as_view(), name="physical_edit"), path("physical/<uuid:pk>/", views.PhysicalView.as_view(), name="physical_edit"),
] ]

View File

@ -1,3 +1,5 @@
import json
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@ -5,7 +7,10 @@ from django.views.generic.edit import (
CreateView, CreateView,
UpdateView, UpdateView,
) )
from django.views.generic.base import TemplateView
from dashboard.mixins import DashboardView, DetailsMixin from dashboard.mixins import DashboardView, DetailsMixin
from snapshot.models import Annotation
from snapshot.xapian import search
from device.models import Device, PhysicalProperties from device.models import Device, PhysicalProperties
@ -64,12 +69,35 @@ class EditDeviceView(DashboardView, UpdateView):
return kwargs return kwargs
class DetailsView(DetailsMixin): class DetailsView2(DetailsMixin):
template_name = "details.html" template_name = "details.html"
title = _("Device") title = _("Device")
breadcrumb = "Device / Details" breadcrumb = "Device / Details"
model = Device model = Device
class DetailsView(DashboardView, TemplateView):
template_name = "details.html"
title = _("Device")
breadcrumb = "Device / Details"
def get(self, request, *args, **kwargs):
# import pdb; pdb.set_trace()
self.pk = kwargs['pk']
annotation = get_object_or_404(Annotation, owner=self.request.user, uuid=self.pk)
for xa in search([str(self.pk)]):
self.object = json.loads(xa.document.get_data())
return super().get(request, *args, **kwargs)
return super().get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context.update({
'object': self.object,
})
return context
class PhysicalView(DashboardView, UpdateView): class PhysicalView(DashboardView, UpdateView):
template_name = "physical_properties.html" template_name = "physical_properties.html"

View File

@ -10,6 +10,8 @@ For the full list of settings and their values, see
https://docs.djangoproject.com/en/5.0/ref/settings/ https://docs.djangoproject.com/en/5.0/ref/settings/
""" """
import xapian
from pathlib import Path from pathlib import Path
from django.contrib.messages import constants as messages from django.contrib.messages import constants as messages
from decouple import config, Csv from decouple import config, Csv
@ -92,11 +94,10 @@ WSGI_APPLICATION = "dhub.wsgi.application"
DATABASES = { DATABASES = {
"default": { "default": {
"ENGINE": "django.db.backends.sqlite3", "ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "db.sqlite3", "NAME": BASE_DIR / "db/db.sqlite3",
} }
} }
# Password validation # Password validation
# https://docs.djangoproject.com/en/5.0/ref/settings/#auth-password-validators # https://docs.djangoproject.com/en/5.0/ref/settings/#auth-password-validators

View File

@ -0,0 +1,41 @@
# Generated by Django 5.0.6 on 2024-07-15 09:20
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("snapshot", "0003_remove_snapshot_start_time"),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name="anotation",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("created", models.DateTimeField(auto_now_add=True)),
("uuid", models.UUIDField(unique=True)),
("key", models.CharField(max_length=256)),
("value", models.CharField(max_length=256)),
(
"owner",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to=settings.AUTH_USER_MODEL,
),
),
],
),
]

View File

@ -0,0 +1,44 @@
# Generated by Django 5.0.6 on 2024-07-15 09:21
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("snapshot", "0004_anotation"),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name="Annotation",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("created", models.DateTimeField(auto_now_add=True)),
("uuid", models.UUIDField(unique=True)),
("key", models.CharField(max_length=256)),
("value", models.CharField(max_length=256)),
(
"owner",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to=settings.AUTH_USER_MODEL,
),
),
],
),
migrations.DeleteModel(
name="anotation",
),
]

View File

@ -1,5 +1,5 @@
from django.db import models from django.db import models
from utils.constants import STR_SM_SIZE from utils.constants import STR_SM_SIZE, STR_EXTEND_SIZE
from user.models import User from user.models import User
from device.models import Computer, Component from device.models import Computer, Component
@ -29,3 +29,11 @@ class Snapshot(models.Model):
computer = models.ForeignKey(Computer, on_delete=models.CASCADE) computer = models.ForeignKey(Computer, on_delete=models.CASCADE)
components = models.ManyToManyField(Component) components = models.ManyToManyField(Component)
class Annotation(models.Model):
created = models.DateTimeField(auto_now_add=True)
uuid = models.UUIDField(unique=True)
owner = models.ForeignKey(User, on_delete=models.CASCADE)
key = models.CharField(max_length=STR_EXTEND_SIZE)
value = models.CharField(max_length=STR_EXTEND_SIZE)

View File

@ -1,15 +1,15 @@
import os import os
import json import json
import shutil import shutil
import xapian
import hashlib import hashlib
from datetime import datetime from datetime import datetime
from django.conf import settings from snapshot.models import Snapshot, Annotation
from device.models import Device, Computer from snapshot.xapian import search, indexer, database
from snapshot.models import Snapshot
HID = [ HID_ALGO1 = [
"manufacturer", "manufacturer",
"model", "model",
"chassis", "chassis",
@ -23,651 +23,44 @@ class Build:
self.json = snapshot_json self.json = snapshot_json
self.user = user self.user = user
self.hid = None self.hid = None
self.result = False
self.save_disk() self.index()
self.json_device = self.json["device"] self.create_annotation()
self.json_components = self.json["components"]
self.uuid = self.json["uuid"]
self.get_hid()
self.gen_computer()
self.gen_components()
self.gen_actions()
self.gen_snapshot()
self.result = True def index(self):
self.move_json() matches = search(self.json['uuid'], limit=1)
if matches.size() > 0:
def save_disk(self):
snapshot_path = settings.SNAPSHOT_PATH
user = self.user.email
uuid = self.json.get("uuid", "")
now = datetime.now().strftime("%Y-%m-%d-%H-%M")
filename = f"{now}_{user}_{uuid}.json"
path_dir_base = os.path.join(snapshot_path, user)
path_upload = os.path.join(path_dir_base, 'upload')
path_name = os.path.join(path_upload, filename)
self.filename = path_name
self.path_dir_base = path_dir_base
if not os.path.isdir(path_dir_base):
os.system(f'mkdir -p {path_upload}')
with open(path_name, 'w') as file:
file.write(json.dumps(self.json))
def move_json(self):
if not self.result:
return return
shutil.copy(self.filename, self.path_dir_base) snap = json.dumps(self.json)
os.remove(self.filename) doc = xapian.Document()
doc.set_data(snap)
def get_hid(self): indexer.set_document(doc)
hid = "" indexer.index_text(snap)
for f in HID:
hid += "-" + self.json_device[f]
self.hid = hid
def gen_computer(self): # Add the document to the database.
self.device = Device.objects.filter( database.add_document(doc)
hid=self.hid,
active=True, def get_hid_14(self):
reliable=True, device = self.json['device']
owner=self.user manufacturer = device.get("manufacturer", '')
).first() model = device.get("model", '')
chassis = device.get("chassis", '')
if self.device: serial_number = device.get("serialNumber", '')
return sku = device.get("sku", '')
hid = f"{manufacturer}{model}{chassis}{serial_number}{sku}"
chid = hashlib.sha3_256(self.hid.encode()).hexdigest() return hashlib.sha3_256(hid.encode()).hexdigest()
self.device = Device.objects.create(
serial_number=self.json_device["serialNumber"], def create_annotation(self):
manufacturer=self.json_device["manufacturer"], uuid = self.json['uuid']
version=self.json_device["version"],
model=self.json_device["model"],
type=self.json_device["type"],
hid=self.hid,
chid=chid,
owner = self.user owner = self.user
key = 'hidalgo1'
value = self.get_hid_14()
Annotation.objects.create(
uuid=uuid,
owner=owner,
key=key,
value=value
) )
Computer.objects.create(
device=self.device,
sku=self.json_device["sku"],
chassis=self.json_device["chassis"]
)
def gen_snapshot(self):
self.snapshot = Snapshot.objects.create(
uuid = self.uuid,
version = self.json["version"],
computer = self.device.computer,
sid = self.json.get("sid", ""),
settings_version = self.json.get("settings_version", ""),
end_time = self.json.get("endTime"),
owner=self.user
)
def gen_components(self):
pass
def gen_actions(self):
pass
# class ParseSnapshot:
# def __init__(self, snapshot, default="n/a"):
# self.default = default
# self.dmidecode_raw = snapshot["hwmd"]["dmidecode"]
# self.smart_raw = snapshot["hwmd"]["smart"]
# self.hwinfo_raw = snapshot["hwmd"]["hwinfo"]
# self.lshw_raw = snapshot["hwmd"]["lshw"]
# self.lscpi_raw = snapshot["hwmd"]["lspci"]
# self.sanitize_raw = snapshot.get("sanitize", [])
# self.device = {"actions": []}
# self.components = []
# self.monitors = []
# self.dmi = DMIParse(self.dmidecode_raw)
# self.smart = self.loads(self.smart_raw)
# self.lshw = self.loads(self.lshw_raw)
# self.hwinfo = self.parse_hwinfo()
# self.set_computer()
# self.get_hwinfo_monitors()
# self.set_components()
# self.snapshot_json = {
# "type": "Snapshot",
# "device": self.device,
# "software": "Workbench",
# # "software": snapshot["software"],
# "components": self.components,
# "uuid": snapshot['uuid'],
# "version": "15.0.0",
# # "version": snapshot['version'],
# "settings_version": snapshot['settings_version'],
# "endTime": snapshot["timestamp"],
# "elapsed": 1,
# "sid": snapshot["sid"],
# }
# def get_snapshot(self):
# return Snapshot().load(self.snapshot_json)
# def set_computer(self):
# self.device['manufacturer'] = self.dmi.manufacturer().strip()
# self.device['model'] = self.dmi.model().strip()
# self.device['serialNumber'] = self.dmi.serial_number()
# self.device['type'] = self.get_type()
# self.device['sku'] = self.get_sku()
# self.device['version'] = self.get_version()
# self.device['system_uuid'] = self.get_uuid()
# self.device['family'] = self.get_family()
# self.device['chassis'] = self.get_chassis_dh()
# def set_components(self):
# self.get_cpu()
# self.get_ram()
# self.get_mother_board()
# self.get_graphic()
# self.get_data_storage()
# self.get_display()
# self.get_sound_card()
# self.get_networks()
# def get_cpu(self):
# for cpu in self.dmi.get('Processor'):
# serial = cpu.get('Serial Number')
# if serial == 'Not Specified' or not serial:
# serial = cpu.get('ID').replace(' ', '')
# self.components.append(
# {
# "actions": [],
# "type": "Processor",
# "speed": self.get_cpu_speed(cpu),
# "cores": int(cpu.get('Core Count', 1)),
# "model": cpu.get('Version'),
# "threads": int(cpu.get('Thread Count', 1)),
# "manufacturer": cpu.get('Manufacturer'),
# "serialNumber": serial,
# "generation": None,
# "brand": cpu.get('Family'),
# "address": self.get_cpu_address(cpu),
# }
# )
# def get_ram(self):
# for ram in self.dmi.get("Memory Device"):
# if ram.get('size') == 'No Module Installed':
# continue
# if not ram.get("Speed"):
# continue
# self.components.append(
# {
# "actions": [],
# "type": "RamModule",
# "size": self.get_ram_size(ram),
# "speed": self.get_ram_speed(ram),
# "manufacturer": ram.get("Manufacturer", self.default),
# "serialNumber": ram.get("Serial Number", self.default),
# "interface": ram.get("Type", "DDR"),
# "format": ram.get("Form Factor", "DIMM"),
# "model": ram.get("Part Number", self.default),
# }
# )
# def get_mother_board(self):
# for moder_board in self.dmi.get("Baseboard"):
# self.components.append(
# {
# "actions": [],
# "type": "Motherboard",
# "version": moder_board.get("Version"),
# "serialNumber": moder_board.get("Serial Number", "").strip(),
# "manufacturer": moder_board.get("Manufacturer", "").strip(),
# "biosDate": self.get_bios_date(),
# "ramMaxSize": self.get_max_ram_size(),
# "ramSlots": len(self.dmi.get("Memory Device")),
# "slots": self.get_ram_slots(),
# "model": moder_board.get("Product Name", "").strip(),
# "firewire": self.get_firmware_num(),
# "pcmcia": self.get_pcmcia_num(),
# "serial": self.get_serial_num(),
# "usb": self.get_usb_num(),
# }
# )
# def get_graphic(self):
# nodes = get_nested_dicts_with_key_value(self.lshw, 'class', 'display')
# for c in nodes:
# if not c['configuration'].get('driver', None):
# continue
# self.components.append(
# {
# "actions": [],
# "type": "GraphicCard",
# "memory": self.get_memory_video(c),
# "manufacturer": c.get("vendor", self.default),
# "model": c.get("product", self.default),
# "serialNumber": c.get("serial", self.default),
# }
# )
# def get_memory_video(self, c):
# # get info of lspci
# # pci_id = c['businfo'].split('@')[1]
# # lspci.get(pci_id) | grep size
# # lspci -v -s 00:02.0
# return None
# def get_data_storage(self):
# for sm in self.smart:
# if sm.get('smartctl', {}).get('exit_status') == 1:
# continue
# model = sm.get('model_name')
# manufacturer = None
# if model and len(model.split(" ")) > 1:
# mm = model.split(" ")
# model = mm[-1]
# manufacturer = " ".join(mm[:-1])
# self.components.append(
# {
# "actions": self.sanitize(sm),
# "type": self.get_data_storage_type(sm),
# "model": model,
# "manufacturer": manufacturer,
# "serialNumber": sm.get('serial_number'),
# "size": self.get_data_storage_size(sm),
# "variant": sm.get("firmware_version"),
# "interface": self.get_data_storage_interface(sm),
# }
# )
# def sanitize(self, disk):
# disk_sanitize = None
# for d in self.sanitize_raw:
# s = d.get('device_info', {}).get('export_data', {})
# s = s.get('block', {}).get('serial')
# if s == disk.get('serial_number'):
# disk_sanitize = d
# break
# if not disk_sanitize:
# return []
# steps = []
# step_type = 'EraseBasic'
# if d.get("method", {}).get('name') == 'Baseline Cryptographic':
# step_type = 'EraseCrypto'
# if disk.get('type') == 'EraseCrypto':
# step_type = 'EraseCrypto'
# erase = {
# 'type': step_type,
# 'severity': "Info",
# 'steps': steps,
# 'startTime': None,
# 'endTime': None,
# }
# severities = []
# for step in disk_sanitize.get('steps', []):
# severity = "Info"
# if not step['success']:
# severity = "Error"
# steps.append(
# {
# 'severity': severity,
# 'startTime': unix_isoformat(step['start_time']),
# 'endTime': unix_isoformat(step['end_time']),
# 'type': 'StepRandom',
# }
# )
# severities.append(severity)
# erase['endTime'] = unix_isoformat(step['end_time'])
# if not erase['startTime']:
# erase['startTime'] = unix_isoformat(step['start_time'])
# if "Error" in severities:
# erase['severity'] = "Error"
# return [erase]
# def get_networks(self):
# nodes = get_nested_dicts_with_key_value(self.lshw, 'class', 'network')
# for c in nodes:
# capacity = c.get('capacity')
# units = c.get('units')
# speed = None
# if capacity and units:
# speed = unit.Quantity(capacity, units).to('Mbit/s').m
# wireless = bool(c.get('configuration', {}).get('wireless', False))
# self.components.append(
# {
# "actions": [],
# "type": "NetworkAdapter",
# "model": c.get('product'),
# "manufacturer": c.get('vendor'),
# "serialNumber": c.get('serial'),
# "speed": speed,
# "variant": c.get('version', 1),
# "wireless": wireless,
# }
# )
# def get_sound_card(self):
# nodes = get_nested_dicts_with_key_value(self.lshw, 'class', 'multimedia')
# for c in nodes:
# self.components.append(
# {
# "actions": [],
# "type": "SoundCard",
# "model": c.get('product'),
# "manufacturer": c.get('vendor'),
# "serialNumber": c.get('serial'),
# }
# )
# def get_display(self): # noqa: C901
# TECHS = 'CRT', 'TFT', 'LED', 'PDP', 'LCD', 'OLED', 'AMOLED'
# for c in self.monitors:
# resolution_width, resolution_height = (None,) * 2
# refresh, serial, model, manufacturer, size = (None,) * 5
# year, week, production_date = (None,) * 3
# for x in c:
# if "Vendor: " in x:
# manufacturer = x.split('Vendor: ')[-1].strip()
# if "Model: " in x:
# model = x.split('Model: ')[-1].strip()
# if "Serial ID: " in x:
# serial = x.split('Serial ID: ')[-1].strip()
# if " Resolution: " in x:
# rs = x.split(' Resolution: ')[-1].strip()
# if 'x' in rs:
# resolution_width, resolution_height = [
# int(r) for r in rs.split('x')
# ]
# if "Frequencies: " in x:
# try:
# refresh = int(float(x.split(',')[-1].strip()[:-3]))
# except Exception:
# pass
# if 'Year of Manufacture' in x:
# year = x.split(': ')[1]
# if 'Week of Manufacture' in x:
# week = x.split(': ')[1]
# if "Size: " in x:
# size = self.get_size_monitor(x)
# technology = next((t for t in TECHS if t in c[0]), None)
# if year and week:
# d = '{} {} 0'.format(year, week)
# production_date = datetime.strptime(d, '%Y %W %w').isoformat()
# self.components.append(
# {
# "actions": [],
# "type": "Display",
# "model": model,
# "manufacturer": manufacturer,
# "serialNumber": serial,
# 'size': size,
# 'resolutionWidth': resolution_width,
# 'resolutionHeight': resolution_height,
# "productionDate": production_date,
# 'technology': technology,
# 'refreshRate': refresh,
# }
# )
# def get_hwinfo_monitors(self):
# for c in self.hwinfo:
# monitor = None
# external = None
# for x in c:
# if 'Hardware Class: monitor' in x:
# monitor = c
# if 'Driver Info' in x:
# external = c
# if monitor and not external:
# self.monitors.append(c)
# def get_size_monitor(self, x):
# i = 1 / 25.4
# t = x.split('Size: ')[-1].strip()
# tt = t.split('mm')
# if not tt:
# return 0
# sizes = tt[0].strip()
# if 'x' not in sizes:
# return 0
# w, h = [int(x) for x in sizes.split('x')]
# return numpy.sqrt(w**2 + h**2) * i
# def get_cpu_address(self, cpu):
# default = 64
# for ch in self.lshw.get('children', []):
# for c in ch.get('children', []):
# if c['class'] == 'processor':
# return c.get('width', default)
# return default
# def get_usb_num(self):
# return len(
# [
# u
# for u in self.dmi.get("Port Connector")
# if "USB" in u.get("Port Type", "").upper()
# ]
# )
# def get_serial_num(self):
# return len(
# [
# u
# for u in self.dmi.get("Port Connector")
# if "SERIAL" in u.get("Port Type", "").upper()
# ]
# )
# def get_firmware_num(self):
# return len(
# [
# u
# for u in self.dmi.get("Port Connector")
# if "FIRMWARE" in u.get("Port Type", "").upper()
# ]
# )
# def get_pcmcia_num(self):
# return len(
# [
# u
# for u in self.dmi.get("Port Connector")
# if "PCMCIA" in u.get("Port Type", "").upper()
# ]
# )
# def get_bios_date(self):
# return self.dmi.get("BIOS")[0].get("Release Date", self.default)
# def get_firmware(self):
# return self.dmi.get("BIOS")[0].get("Firmware Revision", '1')
# def get_max_ram_size(self):
# size = 0
# for slot in self.dmi.get("Physical Memory Array"):
# capacity = slot.get("Maximum Capacity", '0').split(" ")[0]
# size += int(capacity)
# return size
# def get_ram_slots(self):
# slots = 0
# for x in self.dmi.get("Physical Memory Array"):
# slots += int(x.get("Number Of Devices", 0))
# return slots
# def get_ram_size(self, ram):
# try:
# memory = ram.get("Size", "0")
# memory = memory.split(' ')
# if len(memory) > 1:
# size = int(memory[0])
# units = memory[1]
# return base2.Quantity(size, units).to('MiB').m
# return int(size.split(" ")[0])
# except Exception as err:
# logger.error("get_ram_size error: {}".format(err))
# return 0
# def get_ram_speed(self, ram):
# size = ram.get("Speed", "0")
# return int(size.split(" ")[0])
# def get_cpu_speed(self, cpu):
# speed = cpu.get('Max Speed', "0")
# return float(speed.split(" ")[0]) / 1024
# def get_sku(self):
# return self.dmi.get("System")[0].get("SKU Number", self.default).strip()
# def get_version(self):
# return self.dmi.get("System")[0].get("Version", self.default).strip()
# def get_uuid(self):
# return self.dmi.get("System")[0].get("UUID", '').strip()
# def get_family(self):
# return self.dmi.get("System")[0].get("Family", '')
# def get_chassis(self):
# return self.dmi.get("Chassis")[0].get("Type", '_virtual')
# def get_type(self):
# chassis_type = self.get_chassis()
# return self.translation_to_devicehub(chassis_type)
# def translation_to_devicehub(self, original_type):
# lower_type = original_type.lower()
# CHASSIS_TYPE = {
# 'Desktop': [
# 'desktop',
# 'low-profile',
# 'tower',
# 'docking',
# 'all-in-one',
# 'pizzabox',
# 'mini-tower',
# 'space-saving',
# 'lunchbox',
# 'mini',
# 'stick',
# ],
# 'Laptop': [
# 'portable',
# 'laptop',
# 'convertible',
# 'tablet',
# 'detachable',
# 'notebook',
# 'handheld',
# 'sub-notebook',
# ],
# 'Server': ['server'],
# 'Computer': ['_virtual'],
# }
# for k, v in CHASSIS_TYPE.items():
# if lower_type in v:
# return k
# return self.default
# def get_chassis_dh(self):
# CHASSIS_DH = {
# 'Tower': {'desktop', 'low-profile', 'tower', 'server'},
# 'Docking': {'docking'},
# 'AllInOne': {'all-in-one'},
# 'Microtower': {'mini-tower', 'space-saving', 'mini'},
# 'PizzaBox': {'pizzabox'},
# 'Lunchbox': {'lunchbox'},
# 'Stick': {'stick'},
# 'Netbook': {'notebook', 'sub-notebook'},
# 'Handheld': {'handheld'},
# 'Laptop': {'portable', 'laptop'},
# 'Convertible': {'convertible'},
# 'Detachable': {'detachable'},
# 'Tablet': {'tablet'},
# 'Virtual': {'_virtual'},
# }
# chassis = self.get_chassis()
# lower_type = chassis.lower()
# for k, v in CHASSIS_DH.items():
# if lower_type in v:
# return k
# return self.default
# def get_data_storage_type(self, x):
# # TODO @cayop add more SSDS types
# SSDS = ["nvme"]
# SSD = 'SolidStateDrive'
# HDD = 'HardDrive'
# type_dev = x.get('device', {}).get('type')
# trim = x.get('trim', {}).get("supported") in [True, "true"]
# return SSD if type_dev in SSDS or trim else HDD
# def get_data_storage_interface(self, x):
# interface = x.get('device', {}).get('protocol', 'ATA')
# try:
# DataStorageInterface(interface.upper())
# except ValueError as err:
# txt = "Sid: {}, interface {} is not in DataStorageInterface Enum".format(
# self.sid, interface
# )
# self.errors("{}".format(err))
# self.errors(txt, severity=Severity.Warning)
# return "ATA"
# def get_data_storage_size(self, x):
# total_capacity = x.get('user_capacity', {}).get('bytes')
# if not total_capacity:
# return 1
# # convert bytes to Mb
# return total_capacity / 1024**2
# def parse_hwinfo(self):
# hw_blocks = self.hwinfo_raw.split("\n\n")
# return [x.split("\n") for x in hw_blocks]
# def loads(self, x):
# if isinstance(x, str):
# return json.loads(x)
# return x
# def errors(self, txt=None, severity=Severity.Error):
# if not txt:
# return self._errors
# logger.error(txt)
# self._errors.append(txt)
# error = SnapshotsLog(
# description=txt,
# snapshot_uuid=self.uuid,
# severity=severity,
# sid=self.sid,
# version=self.version,
# )
# error.save()

View File

@ -5,7 +5,7 @@ from django.urls import reverse_lazy
from dashboard.mixins import DashboardView from dashboard.mixins import DashboardView
from snapshot.models import Snapshot from snapshot.models import Snapshot
from snapshot.forms import UploadForm # from snapshot.forms import UploadForm
# from django.shortcuts import render # from django.shortcuts import render
# from rest_framework import viewsets # from rest_framework import viewsets
# from snapshot.serializers import SnapshotSerializer # from snapshot.serializers import SnapshotSerializer
@ -31,10 +31,10 @@ class ListSnapshotsView(DashboardView, TemplateView):
return context return context
class UploadView(DashboardView, FormView): # class UploadView(DashboardView, FormView):
template_name = "upload.html" # template_name = "upload.html"
section = "snapshots" # section = "snapshots"
title = _("Upload Snapshot") # title = _("Upload Snapshot")
breadcrumb = "Snapshots / Upload" # breadcrumb = "Snapshots / Upload"
success_url = reverse_lazy('snashot:list') # success_url = reverse_lazy('snashot:list')
form_class = UploadForm # form_class = UploadForm

22
snapshot/xapian.py Normal file
View File

@ -0,0 +1,22 @@
import xapian
database = xapian.WritableDatabase("db", xapian.DB_CREATE_OR_OPEN)
indexer = xapian.TermGenerator()
stemmer = xapian.Stem("english")
indexer.set_stemmer(stemmer)
def search(qs, offset=0, limit=10):
query_string = str.join(' ', qs)
qp = xapian.QueryParser()
qp.set_stemmer(stemmer)
qp.set_database(database)
qp.set_stemming_strategy(xapian.QueryParser.STEM_SOME)
query = qp.parse_query(query_string)
enquire = xapian.Enquire(database)
enquire.set_query(query)
matches = enquire.get_mset(offset, limit)
return matches

View File

@ -5,3 +5,4 @@ STR_XSM_SIZE = 16
STR_SM_SIZE = 32 STR_SM_SIZE = 32
STR_SIZE = 64 STR_SIZE = 64
STR_BIG_SIZE = 128 STR_BIG_SIZE = 128
STR_EXTEND_SIZE = 256