add exports in front end
This commit is contained in:
parent
bfbd7c02b7
commit
179feaba44
|
@ -1,18 +1,24 @@
|
||||||
import flask
|
import csv
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
from flask import Blueprint, request, url_for, g, make_response
|
|
||||||
|
import flask
|
||||||
|
import flask_weasyprint
|
||||||
|
from flask import Blueprint, g, make_response, request, url_for
|
||||||
from flask.views import View
|
from flask.views import View
|
||||||
from flask_login import current_user, login_required
|
from flask_login import current_user, login_required
|
||||||
from werkzeug.exceptions import NotFound
|
from werkzeug.exceptions import NotFound
|
||||||
|
|
||||||
from ereuse_devicehub import messages
|
from ereuse_devicehub import messages
|
||||||
from ereuse_devicehub.inventory.forms import (AllocateForm, LotDeviceForm,
|
from ereuse_devicehub.inventory.forms import (
|
||||||
LotForm, NewActionForm,
|
AllocateForm, DataWipeForm, LotDeviceForm, LotForm, NewActionForm,
|
||||||
NewDeviceForm, TagDeviceForm,
|
NewDeviceForm, TagDeviceForm, TagForm, TagUnnamedForm, TradeDocumentForm,
|
||||||
TagForm, TagUnnamedForm,
|
TradeForm, UploadSnapshotForm)
|
||||||
UploadSnapshotForm, DataWipeForm,
|
from ereuse_devicehub.resources.action.models import Trade
|
||||||
TradeForm, TradeDocumentForm)
|
from ereuse_devicehub.resources.device.models import (
|
||||||
from ereuse_devicehub.resources.device.models import Device
|
Computer, DataStorage, Device)
|
||||||
|
from ereuse_devicehub.resources.documents.device_row import (
|
||||||
|
ActionRow, DeviceRow)
|
||||||
|
from ereuse_devicehub.resources.hash_reports import insert_hash
|
||||||
from ereuse_devicehub.resources.lot.models import Lot
|
from ereuse_devicehub.resources.lot.models import Lot
|
||||||
from ereuse_devicehub.resources.tag.model import Tag
|
from ereuse_devicehub.resources.tag.model import Tag
|
||||||
|
|
||||||
|
@ -30,8 +36,11 @@ class DeviceListMix(View):
|
||||||
filter_types = ['Desktop', 'Laptop', 'Server']
|
filter_types = ['Desktop', 'Laptop', 'Server']
|
||||||
lots = Lot.query.filter(Lot.owner_id == current_user.id)
|
lots = Lot.query.filter(Lot.owner_id == current_user.id)
|
||||||
lot = None
|
lot = None
|
||||||
tags = Tag.query.filter(Tag.owner_id == current_user.id).filter(
|
tags = (
|
||||||
Tag.device_id == None).order_by(Tag.created.desc())
|
Tag.query.filter(Tag.owner_id == current_user.id)
|
||||||
|
.filter_by(device_id=None)
|
||||||
|
.order_by(Tag.created.desc())
|
||||||
|
)
|
||||||
|
|
||||||
if lot_id:
|
if lot_id:
|
||||||
lot = lots.filter(Lot.id == lot_id).one()
|
lot = lots.filter(Lot.id == lot_id).one()
|
||||||
|
@ -46,10 +55,12 @@ class DeviceListMix(View):
|
||||||
user_from=g.user.email,
|
user_from=g.user.email,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
devices = Device.query.filter(
|
devices = (
|
||||||
Device.owner_id == current_user.id).filter(
|
Device.query.filter(Device.owner_id == current_user.id)
|
||||||
Device.type.in_(filter_types)).filter(Device.lots == None).order_by(
|
.filter(Device.type.in_(filter_types))
|
||||||
Device.updated.desc())
|
.filter_by(lots=None)
|
||||||
|
.order_by(Device.updated.desc())
|
||||||
|
)
|
||||||
form_new_action = NewActionForm()
|
form_new_action = NewActionForm()
|
||||||
form_new_allocate = AllocateForm()
|
form_new_allocate = AllocateForm()
|
||||||
form_new_datawipe = DataWipeForm()
|
form_new_datawipe = DataWipeForm()
|
||||||
|
@ -70,14 +81,13 @@ class DeviceListMix(View):
|
||||||
'form_new_trade': form_new_trade,
|
'form_new_trade': form_new_trade,
|
||||||
'lot': lot,
|
'lot': lot,
|
||||||
'tags': tags,
|
'tags': tags,
|
||||||
'list_devices': list_devices
|
'list_devices': list_devices,
|
||||||
}
|
}
|
||||||
|
|
||||||
return self.context
|
return self.context
|
||||||
|
|
||||||
|
|
||||||
class DeviceListView(DeviceListMix):
|
class DeviceListView(DeviceListMix):
|
||||||
|
|
||||||
def dispatch_request(self, lot_id=None):
|
def dispatch_request(self, lot_id=None):
|
||||||
self.get_context(lot_id)
|
self.get_context(lot_id)
|
||||||
return flask.render_template(self.template_name, **self.context)
|
return flask.render_template(self.template_name, **self.context)
|
||||||
|
@ -89,8 +99,11 @@ class DeviceDetailView(View):
|
||||||
|
|
||||||
def dispatch_request(self, id):
|
def dispatch_request(self, id):
|
||||||
lots = Lot.query.filter(Lot.owner_id == current_user.id)
|
lots = Lot.query.filter(Lot.owner_id == current_user.id)
|
||||||
device = Device.query.filter(
|
device = (
|
||||||
Device.owner_id == current_user.id).filter(Device.devicehub_id == id).one()
|
Device.query.filter(Device.owner_id == current_user.id)
|
||||||
|
.filter(Device.devicehub_id == id)
|
||||||
|
.one()
|
||||||
|
)
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
'device': device,
|
'device': device,
|
||||||
|
@ -142,7 +155,9 @@ class LotCreateView(View):
|
||||||
return flask.redirect(next_url)
|
return flask.redirect(next_url)
|
||||||
|
|
||||||
lots = Lot.query.filter(Lot.owner_id == current_user.id)
|
lots = Lot.query.filter(Lot.owner_id == current_user.id)
|
||||||
return flask.render_template(self.template_name, form=form, title=self.title, lots=lots)
|
return flask.render_template(
|
||||||
|
self.template_name, form=form, title=self.title, lots=lots
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class LotUpdateView(View):
|
class LotUpdateView(View):
|
||||||
|
@ -159,7 +174,9 @@ class LotUpdateView(View):
|
||||||
return flask.redirect(next_url)
|
return flask.redirect(next_url)
|
||||||
|
|
||||||
lots = Lot.query.filter(Lot.owner_id == current_user.id)
|
lots = Lot.query.filter(Lot.owner_id == current_user.id)
|
||||||
return flask.render_template(self.template_name, form=form, title=self.title, lots=lots)
|
return flask.render_template(
|
||||||
|
self.template_name, form=form, title=self.title, lots=lots
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class LotDeleteView(View):
|
class LotDeleteView(View):
|
||||||
|
@ -186,7 +203,9 @@ class UploadSnapshotView(View):
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
form.save()
|
form.save()
|
||||||
|
|
||||||
return flask.render_template(self.template_name, form=form, lots=lots, **context)
|
return flask.render_template(
|
||||||
|
self.template_name, form=form, lots=lots, **context
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class DeviceCreateView(View):
|
class DeviceCreateView(View):
|
||||||
|
@ -203,7 +222,9 @@ class DeviceCreateView(View):
|
||||||
next_url = url_for('inventory.devices.devicelist')
|
next_url = url_for('inventory.devices.devicelist')
|
||||||
return flask.redirect(next_url)
|
return flask.redirect(next_url)
|
||||||
|
|
||||||
return flask.render_template(self.template_name, form=form, lots=lots, **context)
|
return flask.render_template(
|
||||||
|
self.template_name, form=form, lots=lots, **context
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class TagListView(View):
|
class TagListView(View):
|
||||||
|
@ -259,8 +280,9 @@ class TagDetailView(View):
|
||||||
|
|
||||||
def dispatch_request(self, id):
|
def dispatch_request(self, id):
|
||||||
lots = Lot.query.filter(Lot.owner_id == current_user.id)
|
lots = Lot.query.filter(Lot.owner_id == current_user.id)
|
||||||
tag = Tag.query.filter(
|
tag = (
|
||||||
Tag.owner_id == current_user.id).filter(Tag.id == id).one()
|
Tag.query.filter(Tag.owner_id == current_user.id).filter(Tag.id == id).one()
|
||||||
|
)
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
'lots': lots,
|
'lots': lots,
|
||||||
|
@ -296,7 +318,9 @@ class TagUnlinkDeviceView(View):
|
||||||
next_url = url_for('inventory.devices.devicelist')
|
next_url = url_for('inventory.devices.devicelist')
|
||||||
return flask.redirect(next_url)
|
return flask.redirect(next_url)
|
||||||
|
|
||||||
return flask.render_template(self.template_name, form=form, referrer=request.referrer)
|
return flask.render_template(
|
||||||
|
self.template_name, form=form, referrer=request.referrer
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class NewActionView(View):
|
class NewActionView(View):
|
||||||
|
@ -308,8 +332,10 @@ class NewActionView(View):
|
||||||
self.form = self.form_class()
|
self.form = self.form_class()
|
||||||
|
|
||||||
if self.form.validate_on_submit():
|
if self.form.validate_on_submit():
|
||||||
instance = self.form.save()
|
self.form.save()
|
||||||
messages.success('Action "{}" created successfully!'.format(self.form.type.data))
|
messages.success(
|
||||||
|
'Action "{}" created successfully!'.format(self.form.type.data)
|
||||||
|
)
|
||||||
|
|
||||||
next_url = self.get_next_url()
|
next_url = self.get_next_url()
|
||||||
return flask.redirect(next_url)
|
return flask.redirect(next_url)
|
||||||
|
@ -331,8 +357,10 @@ class NewAllocateView(NewActionView, DeviceListMix):
|
||||||
self.form = self.form_class()
|
self.form = self.form_class()
|
||||||
|
|
||||||
if self.form.validate_on_submit():
|
if self.form.validate_on_submit():
|
||||||
instance = self.form.save()
|
self.form.save()
|
||||||
messages.success('Action "{}" created successfully!'.format(self.form.type.data))
|
messages.success(
|
||||||
|
'Action "{}" created successfully!'.format(self.form.type.data)
|
||||||
|
)
|
||||||
|
|
||||||
next_url = self.get_next_url()
|
next_url = self.get_next_url()
|
||||||
return flask.redirect(next_url)
|
return flask.redirect(next_url)
|
||||||
|
@ -351,8 +379,10 @@ class NewDataWipeView(NewActionView, DeviceListMix):
|
||||||
self.form = self.form_class()
|
self.form = self.form_class()
|
||||||
|
|
||||||
if self.form.validate_on_submit():
|
if self.form.validate_on_submit():
|
||||||
instance = self.form.save()
|
self.form.save()
|
||||||
messages.success('Action "{}" created successfully!'.format(self.form.type.data))
|
messages.success(
|
||||||
|
'Action "{}" created successfully!'.format(self.form.type.data)
|
||||||
|
)
|
||||||
|
|
||||||
next_url = self.get_next_url()
|
next_url = self.get_next_url()
|
||||||
return flask.redirect(next_url)
|
return flask.redirect(next_url)
|
||||||
|
@ -371,8 +401,10 @@ class NewTradeView(NewActionView, DeviceListMix):
|
||||||
self.form = self.form_class()
|
self.form = self.form_class()
|
||||||
|
|
||||||
if self.form.validate_on_submit():
|
if self.form.validate_on_submit():
|
||||||
instance = self.form.save()
|
self.form.save()
|
||||||
messages.success('Action "{}" created successfully!'.format(self.form.type.data))
|
messages.success(
|
||||||
|
'Action "{}" created successfully!'.format(self.form.type.data)
|
||||||
|
)
|
||||||
|
|
||||||
next_url = self.get_next_url()
|
next_url = self.get_next_url()
|
||||||
return flask.redirect(next_url)
|
return flask.redirect(next_url)
|
||||||
|
@ -399,68 +431,185 @@ class NewTradeDocumentView(View):
|
||||||
next_url = url_for('inventory.devices.lotdevicelist', lot_id=lot_id)
|
next_url = url_for('inventory.devices.lotdevicelist', lot_id=lot_id)
|
||||||
return flask.redirect(next_url)
|
return flask.redirect(next_url)
|
||||||
|
|
||||||
return flask.render_template(self.template_name, form=self.form, title=self.title)
|
return flask.render_template(
|
||||||
|
self.template_name, form=self.form, title=self.title
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ExportsView(View):
|
class ExportsView(View):
|
||||||
methods = ['GET']
|
methods = ['GET']
|
||||||
decorators = [login_required]
|
decorators = [login_required]
|
||||||
|
|
||||||
# def dispatch_request(self, export_id):
|
def dispatch_request(self, export_id):
|
||||||
def dispatch_request(self):
|
|
||||||
import pdb; pdb.trace()
|
|
||||||
export_id = 'metrics'
|
|
||||||
export_ids = {
|
export_ids = {
|
||||||
'metrics': self.metrics(),
|
'metrics': self.metrics,
|
||||||
'devices-list': self.metrics(),
|
'devices': self.devices_list,
|
||||||
'certificates': self.metrics()
|
'certificates': self.erasure,
|
||||||
|
'links': self.public_links,
|
||||||
}
|
}
|
||||||
|
|
||||||
if export_id not in export_ids:
|
if export_id not in export_ids:
|
||||||
return NotFound()
|
return NotFound()
|
||||||
return export_ids[export_id]()
|
return export_ids[export_id]()
|
||||||
|
|
||||||
|
def find_devices(self):
|
||||||
|
args = request.args.get('ids')
|
||||||
|
ids = args.split(',') if args else []
|
||||||
|
query = Device.query.filter(Device.owner == g.user)
|
||||||
|
return query.filter(Device.devicehub_id.in_(ids))
|
||||||
|
|
||||||
|
def response_csv(self, data, name):
|
||||||
|
bfile = data.getvalue().encode('utf-8')
|
||||||
|
# insert proof
|
||||||
|
insert_hash(bfile)
|
||||||
|
output = make_response(bfile)
|
||||||
|
output.headers['Content-Disposition'] = 'attachment; filename={}'.format(name)
|
||||||
|
output.headers['Content-type'] = 'text/csv'
|
||||||
|
return output
|
||||||
|
|
||||||
|
def devices_list(self):
|
||||||
|
"""Get device query and put information in csv format."""
|
||||||
|
data = StringIO()
|
||||||
|
cw = csv.writer(data, delimiter=';', lineterminator="\n", quotechar='"')
|
||||||
|
first = True
|
||||||
|
|
||||||
|
for device in self.find_devices():
|
||||||
|
d = DeviceRow(device, {})
|
||||||
|
if first:
|
||||||
|
cw.writerow(d.keys())
|
||||||
|
first = False
|
||||||
|
cw.writerow(d.values())
|
||||||
|
|
||||||
|
return self.response_csv(data, "export.csv")
|
||||||
|
|
||||||
def metrics(self):
|
def metrics(self):
|
||||||
"""Get device query and put information in csv format."""
|
"""Get device query and put information in csv format."""
|
||||||
data = StringIO()
|
data = StringIO()
|
||||||
# cw = csv.writer(data, delimiter=';', lineterminator="\n", quotechar='"')
|
cw = csv.writer(data, delimiter=';', lineterminator="\n", quotechar='"')
|
||||||
# first = True
|
first = True
|
||||||
# document_ids = self.get_documents_id()
|
devs_id = []
|
||||||
# for device in query:
|
# Get the allocate info
|
||||||
# d = DeviceRow(device, document_ids)
|
for device in self.find_devices():
|
||||||
# if first:
|
devs_id.append(device.id)
|
||||||
# cw.writerow(d.keys())
|
for allocate in device.get_metrics():
|
||||||
# first = False
|
d = ActionRow(allocate)
|
||||||
# cw.writerow(d.values())
|
if first:
|
||||||
bfile = data.getvalue().encode('utf-8')
|
cw.writerow(d.keys())
|
||||||
output = make_response(bfile)
|
first = False
|
||||||
# insert_hash(bfile)
|
cw.writerow(d.values())
|
||||||
output.headers['Content-Disposition'] = 'attachment; filename=export.csv'
|
|
||||||
output.headers['Content-type'] = 'text/csv'
|
# Get the trade info
|
||||||
return output
|
query_trade = Trade.query.filter(
|
||||||
|
Trade.devices.any(Device.id.in_(devs_id))
|
||||||
|
).all()
|
||||||
|
|
||||||
|
lot_id = request.args.get('lot')
|
||||||
|
if lot_id and not query_trade:
|
||||||
|
lot = Lot.query.filter_by(id=lot_id).one()
|
||||||
|
if hasattr(lot, "trade") and lot.trade:
|
||||||
|
if g.user in [lot.trade.user_from, lot.trade.user_to]:
|
||||||
|
query_trade = [lot.trade]
|
||||||
|
|
||||||
|
for trade in query_trade:
|
||||||
|
data_rows = trade.get_metrics()
|
||||||
|
for row in data_rows:
|
||||||
|
d = ActionRow(row)
|
||||||
|
if first:
|
||||||
|
cw.writerow(d.keys())
|
||||||
|
first = False
|
||||||
|
cw.writerow(d.values())
|
||||||
|
|
||||||
|
return self.response_csv(data, "actions_export.csv")
|
||||||
|
|
||||||
|
def public_links(self):
|
||||||
|
# get a csv with the publink links of this devices
|
||||||
|
data = StringIO()
|
||||||
|
cw = csv.writer(data, delimiter=';', lineterminator="\n", quotechar='"')
|
||||||
|
cw.writerow(['links'])
|
||||||
|
host_url = request.host_url
|
||||||
|
for dev in self.find_devices():
|
||||||
|
code = dev.devicehub_id
|
||||||
|
link = [f"{host_url}devices/{code}"]
|
||||||
|
cw.writerow(link)
|
||||||
|
|
||||||
|
return self.response_csv(data, "links.csv")
|
||||||
|
|
||||||
|
def erasure(self):
|
||||||
|
template = self.build_erasure_certificate()
|
||||||
|
res = flask_weasyprint.render_pdf(
|
||||||
|
flask_weasyprint.HTML(string=template),
|
||||||
|
download_filename='erasure-certificate.pdf',
|
||||||
|
)
|
||||||
|
insert_hash(res.data)
|
||||||
|
return res
|
||||||
|
|
||||||
|
def build_erasure_certificate(self):
|
||||||
|
erasures = []
|
||||||
|
for device in self.find_devices():
|
||||||
|
if isinstance(device, Computer):
|
||||||
|
for privacy in device.privacy:
|
||||||
|
erasures.append(privacy)
|
||||||
|
elif isinstance(device, DataStorage):
|
||||||
|
if device.privacy:
|
||||||
|
erasures.append(device.privacy)
|
||||||
|
|
||||||
|
params = {
|
||||||
|
'title': 'Erasure Certificate',
|
||||||
|
'erasures': tuple(erasures),
|
||||||
|
'url_pdf': '',
|
||||||
|
}
|
||||||
|
return flask.render_template('inventory/erasure.html', **params)
|
||||||
|
|
||||||
|
|
||||||
devices.add_url_rule('/action/add/', view_func=NewActionView.as_view('action_add'))
|
devices.add_url_rule('/action/add/', view_func=NewActionView.as_view('action_add'))
|
||||||
devices.add_url_rule('/action/trade/add/', view_func=NewTradeView.as_view('trade_add'))
|
devices.add_url_rule('/action/trade/add/', view_func=NewTradeView.as_view('trade_add'))
|
||||||
devices.add_url_rule('/action/allocate/add/', view_func=NewAllocateView.as_view('allocate_add'))
|
devices.add_url_rule(
|
||||||
devices.add_url_rule('/action/datawipe/add/', view_func=NewDataWipeView.as_view('datawipe_add'))
|
'/action/allocate/add/', view_func=NewAllocateView.as_view('allocate_add')
|
||||||
devices.add_url_rule('/lot/<string:lot_id>/trade-document/add/',
|
)
|
||||||
view_func=NewTradeDocumentView.as_view('trade_document_add'))
|
devices.add_url_rule(
|
||||||
|
'/action/datawipe/add/', view_func=NewDataWipeView.as_view('datawipe_add')
|
||||||
|
)
|
||||||
|
devices.add_url_rule(
|
||||||
|
'/lot/<string:lot_id>/trade-document/add/',
|
||||||
|
view_func=NewTradeDocumentView.as_view('trade_document_add'),
|
||||||
|
)
|
||||||
devices.add_url_rule('/device/', view_func=DeviceListView.as_view('devicelist'))
|
devices.add_url_rule('/device/', view_func=DeviceListView.as_view('devicelist'))
|
||||||
devices.add_url_rule('/device/<string:id>/', view_func=DeviceDetailView.as_view('device_details'))
|
devices.add_url_rule(
|
||||||
devices.add_url_rule('/lot/<string:lot_id>/device/', view_func=DeviceListView.as_view('lotdevicelist'))
|
'/device/<string:id>/', view_func=DeviceDetailView.as_view('device_details')
|
||||||
devices.add_url_rule('/lot/devices/add/', view_func=LotDeviceAddView.as_view('lot_devices_add'))
|
)
|
||||||
devices.add_url_rule('/lot/devices/del/', view_func=LotDeviceDeleteView.as_view('lot_devices_del'))
|
devices.add_url_rule(
|
||||||
|
'/lot/<string:lot_id>/device/', view_func=DeviceListView.as_view('lotdevicelist')
|
||||||
|
)
|
||||||
|
devices.add_url_rule(
|
||||||
|
'/lot/devices/add/', view_func=LotDeviceAddView.as_view('lot_devices_add')
|
||||||
|
)
|
||||||
|
devices.add_url_rule(
|
||||||
|
'/lot/devices/del/', view_func=LotDeviceDeleteView.as_view('lot_devices_del')
|
||||||
|
)
|
||||||
devices.add_url_rule('/lot/add/', view_func=LotCreateView.as_view('lot_add'))
|
devices.add_url_rule('/lot/add/', view_func=LotCreateView.as_view('lot_add'))
|
||||||
devices.add_url_rule('/lot/<string:id>/del/', view_func=LotDeleteView.as_view('lot_del'))
|
devices.add_url_rule(
|
||||||
|
'/lot/<string:id>/del/', view_func=LotDeleteView.as_view('lot_del')
|
||||||
|
)
|
||||||
devices.add_url_rule('/lot/<string:id>/', view_func=LotUpdateView.as_view('lot_edit'))
|
devices.add_url_rule('/lot/<string:id>/', view_func=LotUpdateView.as_view('lot_edit'))
|
||||||
devices.add_url_rule('/upload-snapshot/', view_func=UploadSnapshotView.as_view('upload_snapshot'))
|
devices.add_url_rule(
|
||||||
|
'/upload-snapshot/', view_func=UploadSnapshotView.as_view('upload_snapshot')
|
||||||
|
)
|
||||||
devices.add_url_rule('/device/add/', view_func=DeviceCreateView.as_view('device_add'))
|
devices.add_url_rule('/device/add/', view_func=DeviceCreateView.as_view('device_add'))
|
||||||
devices.add_url_rule('/tag/', view_func=TagListView.as_view('taglist'))
|
devices.add_url_rule('/tag/', view_func=TagListView.as_view('taglist'))
|
||||||
devices.add_url_rule('/tag/add/', view_func=TagAddView.as_view('tag_add'))
|
devices.add_url_rule('/tag/add/', view_func=TagAddView.as_view('tag_add'))
|
||||||
devices.add_url_rule('/tag/unnamed/add/', view_func=TagAddUnnamedView.as_view('tag_unnamed_add'))
|
devices.add_url_rule(
|
||||||
devices.add_url_rule('/tag/<string:id>/', view_func=TagDetailView.as_view('tag_details'))
|
'/tag/unnamed/add/', view_func=TagAddUnnamedView.as_view('tag_unnamed_add')
|
||||||
devices.add_url_rule('/tag/devices/add/', view_func=TagLinkDeviceView.as_view('tag_devices_add'))
|
)
|
||||||
devices.add_url_rule('/tag/devices/<int:id>/del/', view_func=TagUnlinkDeviceView.as_view('tag_devices_del'))
|
devices.add_url_rule(
|
||||||
# devices.add_url_rule('/export/<string:export_id>', view_func=ExportsView.as_view('export'))
|
'/tag/<string:id>/', view_func=TagDetailView.as_view('tag_details')
|
||||||
devices.add_url_rule('/export/', view_func=ExportsView.as_view('export'))
|
)
|
||||||
|
devices.add_url_rule(
|
||||||
|
'/tag/devices/add/', view_func=TagLinkDeviceView.as_view('tag_devices_add')
|
||||||
|
)
|
||||||
|
devices.add_url_rule(
|
||||||
|
'/tag/devices/<int:id>/del/',
|
||||||
|
view_func=TagUnlinkDeviceView.as_view('tag_devices_del'),
|
||||||
|
)
|
||||||
|
devices.add_url_rule(
|
||||||
|
'/export/<string:export_id>/', view_func=ExportsView.as_view('export')
|
||||||
|
)
|
||||||
|
|
|
@ -148,3 +148,12 @@ function get_device_list() {
|
||||||
description = $.map(list_devices, function(x) { return x }).join(", ");
|
description = $.map(list_devices, function(x) { return x }).join(", ");
|
||||||
$(".enumeration-devices").html(description);
|
$(".enumeration-devices").html(description);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function export_file(type_file) {
|
||||||
|
var devices = $(".deviceSelect").filter(':checked');
|
||||||
|
var devices_id = $.map(devices, function(x) { return $(x).attr('data-device-dhid')}).join(",");
|
||||||
|
if (devices_id){
|
||||||
|
var url = "/inventory/export/"+type_file+"/?ids="+devices_id;
|
||||||
|
window.location.href = url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -207,8 +207,27 @@
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu" aria-labelledby="btnExport">
|
<ul class="dropdown-menu" aria-labelledby="btnExport">
|
||||||
<li>
|
<li>
|
||||||
<a href="#" class="dropdown-item">
|
<a href="javascript:export_file('devices')" class="dropdown-item">
|
||||||
TODO: Not implemented
|
<i class="bi bi-file-spreadsheet"></i>
|
||||||
|
Devices Spreadsheet
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="javascript:export_file('metrics')" class="dropdown-item">
|
||||||
|
<i class="bi bi-file-spreadsheet"></i>
|
||||||
|
Metrics Spreadsheet
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="javascript:export_file('links')" class="dropdown-item">
|
||||||
|
<i class="bi bi-link-45deg"></i>
|
||||||
|
Public Links
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="javascript:export_file('certificates')" class="dropdown-item">
|
||||||
|
<i class="bi bi-eraser-fill"></i>
|
||||||
|
Erasure Certificate
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -352,9 +371,7 @@
|
||||||
{% include "inventory/actions.html" %}
|
{% include "inventory/actions.html" %}
|
||||||
{% include "inventory/allocate.html" %}
|
{% include "inventory/allocate.html" %}
|
||||||
{% include "inventory/data_wipe.html" %}
|
{% include "inventory/data_wipe.html" %}
|
||||||
{% if lot and lot.is_temporary %}
|
|
||||||
{% include "inventory/trade.html" %}
|
{% include "inventory/trade.html" %}
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<!-- CDN -->
|
<!-- CDN -->
|
||||||
<script src="https://cdn.jsdelivr.net/npm/simple-datatables@latest"></script>
|
<script src="https://cdn.jsdelivr.net/npm/simple-datatables@latest"></script>
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
{% extends "documents/layout.html" %}
|
||||||
|
{% block body %}
|
||||||
|
<div>
|
||||||
|
<h2>Summary</h2>
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>S/N Data Storage</th>
|
||||||
|
<th>Type of erasure</th>
|
||||||
|
<th>Result</th>
|
||||||
|
<th>Date</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for erasure in erasures %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
{{ erasure.device.serial_number.upper() }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ erasure.type }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ erasure.severity }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ erasure.date_str }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="page-break row">
|
||||||
|
<h2>Details</h2>
|
||||||
|
{% for erasure in erasures %}
|
||||||
|
<div class="col-md-6 no-page-break">
|
||||||
|
<h4>{{ erasure.device.__format__('t') }}</h4>
|
||||||
|
<dl>
|
||||||
|
<dt>Data storage:</dt>
|
||||||
|
<dd>{{ erasure.device.__format__('ts') }}</dd>
|
||||||
|
|
||||||
|
<dt>Computer where was erase:</dt>
|
||||||
|
<dd>Title: {{ erasure.parent.__format__('ts') }}</dd>
|
||||||
|
<dd>DevicehubID: {{ erasure.parent.devicehub_id }}</dd>
|
||||||
|
<dd>Hid: {{ erasure.parent.hid }}</dd>
|
||||||
|
<dd>Tags: {{ erasure.parent.tags }}</dd>
|
||||||
|
|
||||||
|
<dt>Computer where it resides:</dt>
|
||||||
|
<dd>Title: {{ erasure.device.parent.__format__('ts') }}</dd>
|
||||||
|
<dd>DevicehubID: {{ erasure.device.parent.devicehub_id }}</dd>
|
||||||
|
<dd>Hid: {{ erasure.device.parent.hid }}</dd>
|
||||||
|
<dd>Tags: {{ erasure.device.parent.tags }}</dd>
|
||||||
|
|
||||||
|
<dt>Erasure:</dt>
|
||||||
|
<dd>{{ erasure.__format__('ts') }}</dd>
|
||||||
|
{% if erasure.steps %}
|
||||||
|
<dt>Erasure steps:</dt>
|
||||||
|
<dd>
|
||||||
|
<ol>
|
||||||
|
{% for step in erasure.steps %}
|
||||||
|
<li>{{ step.__format__('') }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ol>
|
||||||
|
</dd>
|
||||||
|
{% endif %}
|
||||||
|
</dl>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<div class="no-page-break">
|
||||||
|
<h2>Glossary</h2>
|
||||||
|
<dl>
|
||||||
|
<dt>Erase Basic</dt>
|
||||||
|
<dd>
|
||||||
|
A software-based fast non-100%-secured way of erasing data storage,
|
||||||
|
using <a href="https://en.wikipedia.org/wiki/Shred_(Unix)">shred</a>.
|
||||||
|
</dd>
|
||||||
|
<dt>Erase Sectors</dt>
|
||||||
|
<dd>
|
||||||
|
A secured-way of erasing data storages, checking sector-by-sector
|
||||||
|
the erasure, using <a href="https://en.wikipedia.org/wiki/Badblocks">badblocks</a>.
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
</div>
|
||||||
|
<div class="no-print">
|
||||||
|
<a href="{{ url_pdf }}">Click here to download the PDF.</a>
|
||||||
|
</div>
|
||||||
|
<div class="print-only">
|
||||||
|
<a href="{{ url_for('Document.StampsView', _external=True) }}">Verify on-line the integrity of this document</a>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
|
@ -55,4 +55,8 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="modal fade" id="tradeLotModal" tabindex="-1" style="display: none;" aria-hidden="true"
|
||||||
|
data-show-action-form="None">
|
||||||
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
Reference in New Issue