From 4f6663dc1237e994e9c8d16645e7ab2b8c0db209 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Mon, 27 Jun 2022 17:12:04 +0200 Subject: [PATCH 1/6] add sentry --- examples/app.py | 22 ++++++++++++++++++++++ requirements.txt | 2 ++ 2 files changed, 24 insertions(+) diff --git a/examples/app.py b/examples/app.py index 5a7e9fbb..690ff9f9 100644 --- a/examples/app.py +++ b/examples/app.py @@ -3,7 +3,11 @@ Example app with minimal configuration. Use this as a starting point. """ +import sentry_sdk +from decouple import config from flask_wtf.csrf import CSRFProtect +from sentry_sdk.integrations.flask import FlaskIntegration +from werkzeug.contrib.profiler import ProfilerMiddleware from ereuse_devicehub.api.views import api from ereuse_devicehub.config import DevicehubConfig @@ -13,6 +17,20 @@ from ereuse_devicehub.labels.views import labels from ereuse_devicehub.views import core from ereuse_devicehub.workbench.views import workbench +SENTRY_DSN = config('SENTRY_DSN', None) +if SENTRY_DSN: + sentry_sdk.init( + dsn=SENTRY_DSN, + integrations=[ + FlaskIntegration(), + ], + # Set traces_sample_rate to 1.0 to capture 100% + # of transactions for performance monitoring. + # We recommend adjusting this value in production. + traces_sample_rate=1.0, + ) + + app = Devicehub(inventory=DevicehubConfig.DB_SCHEMA) app.register_blueprint(core) app.register_blueprint(devices) @@ -26,3 +44,7 @@ app.register_blueprint(workbench) csrf = CSRFProtect(app) # csrf.protect(core) # csrf.protect(devices) +app.config["SQLALCHEMY_RECORD_QUERIES"] = True +app.config['PROFILE'] = True +app.wsgi_app = ProfilerMiddleware(app.wsgi_app, restrictions=[30]) +app.run(debug=True) diff --git a/requirements.txt b/requirements.txt index a72507d0..6f4bb6d9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -45,3 +45,5 @@ python-dotenv==0.14.0 pyjwt==2.4.0 pint==0.9 py-dmidecode==0.1.0 +sentry_sdk==1.6.0 +blinker==1.4 From a74e242e208ff6da4ac685227a0d510d33673993 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Fri, 22 Jul 2022 15:23:49 +0200 Subject: [PATCH 2/6] add report command cli --- ereuse_devicehub/commands/__init__.py | 0 ereuse_devicehub/commands/reports.py | 51 +++++++++++++++++++ ereuse_devicehub/devicehub.py | 3 ++ .../resources/documents/documents.py | 40 ++++++++------- 4 files changed, 76 insertions(+), 18 deletions(-) create mode 100644 ereuse_devicehub/commands/__init__.py create mode 100644 ereuse_devicehub/commands/reports.py diff --git a/ereuse_devicehub/commands/__init__.py b/ereuse_devicehub/commands/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ereuse_devicehub/commands/reports.py b/ereuse_devicehub/commands/reports.py new file mode 100644 index 00000000..cdc05211 --- /dev/null +++ b/ereuse_devicehub/commands/reports.py @@ -0,0 +1,51 @@ +import csv + +# import click +# import click_spinner +# import ereuse_utils.cli +from io import StringIO + +from ereuse_devicehub.resources.action import models as evs +from ereuse_devicehub.resources.documents.device_row import InternalStatsRow + + +class Report: + + def __init__(self, app) -> None: + super().__init__() + self.app = app + self.app.cli.command('report', short_help='Creates reports devices and users.')( + self.run + ) + + def run(self): + stats = InternalStatsView() + stats.print() + + +class InternalStatsView: + def print(self): + query = evs.Action.query.filter( + evs.Action.type.in_(('Snapshot', 'Live', 'Allocate', 'Deallocate'))) + return self.generate_post_csv(query) + + def generate_post_csv(self, query): + d = {} + for ac in query: + create = '{}-{}'.format(ac.created.year, ac.created.month) + user = ac.author.email + + if user not in d: + d[user] = {} + if create not in d[user]: + d[user][create] = [] + d[user][create].append(ac) + + data = StringIO() + cw = csv.writer(data, delimiter=';', lineterminator="\n", quotechar='"') + cw.writerow(InternalStatsRow('', "2000-1", []).keys()) + for user, createds in d.items(): + for create, actions in createds.items(): + cw.writerow(InternalStatsRow(user, create, actions).values()) + + return print(data.getvalue()) diff --git a/ereuse_devicehub/devicehub.py b/ereuse_devicehub/devicehub.py index 520ca132..182c064e 100644 --- a/ereuse_devicehub/devicehub.py +++ b/ereuse_devicehub/devicehub.py @@ -15,6 +15,7 @@ from teal.teal import Teal from ereuse_devicehub.auth import Auth from ereuse_devicehub.client import Client, UserClient +from ereuse_devicehub.commands.reports import Report from ereuse_devicehub.config import DevicehubConfig from ereuse_devicehub.db import db from ereuse_devicehub.dummy.dummy import Dummy @@ -27,6 +28,7 @@ from ereuse_devicehub.templating import Environment class Devicehub(Teal): test_client_class = Client Dummy = Dummy + Report = Report jinja_environment = Environment def __init__( @@ -67,6 +69,7 @@ class Devicehub(Teal): self.id = inventory """The Inventory ID of this instance. In Teal is the app.schema.""" self.dummy = Dummy(self) + self.report = Report(self) @self.cli.group( short_help='Inventory management.', diff --git a/ereuse_devicehub/resources/documents/documents.py b/ereuse_devicehub/resources/documents/documents.py index 1a1584e8..a6f4f95f 100644 --- a/ereuse_devicehub/resources/documents/documents.py +++ b/ereuse_devicehub/resources/documents/documents.py @@ -1,9 +1,9 @@ import csv -import json -import enum -import uuid -import time import datetime +import enum +import json +import time +import uuid from collections import OrderedDict from io import StringIO from typing import Callable, Iterable, Tuple @@ -13,27 +13,31 @@ import flask import flask_weasyprint import teal.marshmallow from boltons import urlutils -from flask import make_response, g, request from flask import current_app as app +from flask import g, make_response, request from flask.json import jsonify from teal.cache import cache from teal.resource import Resource, View from ereuse_devicehub import auth from ereuse_devicehub.db import db -from ereuse_devicehub.resources.enums import SessionType -from ereuse_devicehub.resources.user.models import Session from ereuse_devicehub.resources.action import models as evs -from ereuse_devicehub.resources.device import models as devs +from ereuse_devicehub.resources.action.models import Trade from ereuse_devicehub.resources.deliverynote.models import Deliverynote +from ereuse_devicehub.resources.device import models as devs +from ereuse_devicehub.resources.device.models import Device from ereuse_devicehub.resources.device.views import DeviceView -from ereuse_devicehub.resources.documents.device_row import (DeviceRow, StockRow, ActionRow, - InternalStatsRow) +from ereuse_devicehub.resources.documents.device_row import ( + ActionRow, + DeviceRow, + InternalStatsRow, + StockRow, +) +from ereuse_devicehub.resources.enums import SessionType +from ereuse_devicehub.resources.hash_reports import ReportHash, insert_hash, verify_hash from ereuse_devicehub.resources.lot import LotView from ereuse_devicehub.resources.lot.models import Lot -from ereuse_devicehub.resources.action.models import Trade -from ereuse_devicehub.resources.device.models import Device -from ereuse_devicehub.resources.hash_reports import insert_hash, ReportHash, verify_hash +from ereuse_devicehub.resources.user.models import Session class Format(enum.Enum): @@ -469,11 +473,11 @@ class DocumentDef(Resource): stamps_view = StampsView.as_view('StampsView', definition=self, auth=app.auth) self.add_url_rule('/stamps/', defaults={}, view_func=stamps_view, methods={'GET', 'POST'}) - internalstats_view = InternalStatsView.as_view( - 'InternalStatsView', definition=self, auth=app.auth) - internalstats_view = app.auth.requires_auth(internalstats_view) - self.add_url_rule('/internalstats/', defaults=d, view_func=internalstats_view, - methods=get) + # internalstats_view = InternalStatsView.as_view( + # 'InternalStatsView', definition=self, auth=app.auth) + # internalstats_view = app.auth.requires_auth(internalstats_view) + # self.add_url_rule('/internalstats/', defaults=d, view_func=internalstats_view, + # methods=get) actions_view = ActionsDocumentView.as_view('ActionsDocumentView', definition=self, From 429c9a1b157e43a927f92d98c0d68627638cfff3 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Fri, 22 Jul 2022 17:49:51 +0200 Subject: [PATCH 3/6] add command cli: get_token --- ereuse_devicehub/commands/reports.py | 3 ++- ereuse_devicehub/commands/users.py | 20 ++++++++++++++++++++ ereuse_devicehub/devicehub.py | 2 ++ 3 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 ereuse_devicehub/commands/users.py diff --git a/ereuse_devicehub/commands/reports.py b/ereuse_devicehub/commands/reports.py index cdc05211..8d020e7d 100644 --- a/ereuse_devicehub/commands/reports.py +++ b/ereuse_devicehub/commands/reports.py @@ -1,6 +1,5 @@ import csv -# import click # import click_spinner # import ereuse_utils.cli from io import StringIO @@ -8,6 +7,8 @@ from io import StringIO from ereuse_devicehub.resources.action import models as evs from ereuse_devicehub.resources.documents.device_row import InternalStatsRow +# import click + class Report: diff --git a/ereuse_devicehub/commands/users.py b/ereuse_devicehub/commands/users.py new file mode 100644 index 00000000..0537944f --- /dev/null +++ b/ereuse_devicehub/commands/users.py @@ -0,0 +1,20 @@ +import click + +from ereuse_devicehub import auth +from ereuse_devicehub.resources.user.models import User + + +class GetToken: + + def __init__(self, app) -> None: + super().__init__() + self.app = app + self.app.cli.command('get_token', short_help='show the user token.')( + self.run + ) + + @click.argument('email') + def run(self, email): + user = User.query.filter_by(email=email, active=True, phantom=False).one_or_none() + if user: + print(auth.Auth.encode(user.token)) diff --git a/ereuse_devicehub/devicehub.py b/ereuse_devicehub/devicehub.py index 182c064e..5fec2cbe 100644 --- a/ereuse_devicehub/devicehub.py +++ b/ereuse_devicehub/devicehub.py @@ -16,6 +16,7 @@ from teal.teal import Teal from ereuse_devicehub.auth import Auth from ereuse_devicehub.client import Client, UserClient from ereuse_devicehub.commands.reports import Report +from ereuse_devicehub.commands.users import GetToken from ereuse_devicehub.config import DevicehubConfig from ereuse_devicehub.db import db from ereuse_devicehub.dummy.dummy import Dummy @@ -70,6 +71,7 @@ class Devicehub(Teal): """The Inventory ID of this instance. In Teal is the app.schema.""" self.dummy = Dummy(self) self.report = Report(self) + self.get_token = GetToken(self) @self.cli.group( short_help='Inventory management.', From 21f2a9c49bccc7f7a6ed9879cdc10da73b5ba1e6 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Fri, 22 Jul 2022 17:53:09 +0200 Subject: [PATCH 4/6] fix tests --- tests/test_basic.py | 1 - tests/test_documents.py | 1 - 2 files changed, 2 deletions(-) diff --git a/tests/test_basic.py b/tests/test_basic.py index bb9196a2..18d48bfc 100644 --- a/tests/test_basic.py +++ b/tests/test_basic.py @@ -41,7 +41,6 @@ def test_api_docs(client: Client): '/documents/check/', '/documents/devices/', '/documents/erasures/', - '/documents/internalstats/', '/documents/lots/', '/inventory/search/', '/documents/stamps/', diff --git a/tests/test_documents.py b/tests/test_documents.py index 4365af5c..fc36ecfa 100644 --- a/tests/test_documents.py +++ b/tests/test_documents.py @@ -756,7 +756,6 @@ def test_verify_stamp_erasure_certificate(user: UserClient, client: Client): assert "alert alert-info" in response -@pytest.mark.mvp def test_get_document_internal_stats(user: UserClient, user2: UserClient): """Tests for get the internal stats.""" From 31bd4d775b3487e4137d9c25672c9a52c2ca4d89 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Mon, 25 Jul 2022 17:37:00 +0200 Subject: [PATCH 5/6] fix fields number for print label --- ereuse_devicehub/static/js/print.pdf.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ereuse_devicehub/static/js/print.pdf.js b/ereuse_devicehub/static/js/print.pdf.js index b17f70ee..e0109d33 100644 --- a/ereuse_devicehub/static/js/print.pdf.js +++ b/ereuse_devicehub/static/js/print.pdf.js @@ -234,9 +234,9 @@ function printpdf() { if ($("#qrCheck").prop('checked')) { var h = hspace + border - img_side/2; var w = border*2 + img_side; - pdf.text(tag, w, h); + pdf.text(String(tag), w, h); } else { - pdf.text(tag, border, hspace); + pdf.text(String(tag), border, hspace); } hspace += line; }; @@ -244,26 +244,26 @@ function printpdf() { var sn = $(y).data('sid'); pdf.setFontSize(12); if (sn) { - pdf.text(sn, border, hspace); + pdf.text(String(sn), border, hspace); hspace += line; } }; if ($("#serialNumberCheck").prop('checked')) { var sn = $(y).data('serial-number'); pdf.setFontSize(12); - pdf.text(sn, border, hspace); + pdf.text(String(sn), border, hspace); hspace += line; }; if ($("#manufacturerCheck").prop('checked')) { var sn = $(y).data('manufacturer'); pdf.setFontSize(12); - pdf.text(sn, border, hspace); + pdf.text(String(sn), border, hspace); hspace += line; }; if ($("#modelCheck").prop('checked')) { var sn = $(y).data('model'); pdf.setFontSize(8); - pdf.text(sn, border, hspace); + pdf.text(String(sn), border, hspace); hspace += line; }; }); From ac9708c77967946821b1b2cd1835707d287fc8d7 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Mon, 25 Jul 2022 17:38:08 +0200 Subject: [PATCH 6/6] fix unlink tags --- ereuse_devicehub/static/js/main_inventory.build.js | 4 ++-- ereuse_devicehub/static/js/main_inventory.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ereuse_devicehub/static/js/main_inventory.build.js b/ereuse_devicehub/static/js/main_inventory.build.js index 1e1b21fd..7737a44c 100644 --- a/ereuse_devicehub/static/js/main_inventory.build.js +++ b/ereuse_devicehub/static/js/main_inventory.build.js @@ -216,7 +216,7 @@ function removeLot() { function removeTag() { const devices = TableController.getSelectedDevices(); - const devices_id = devices.map(dev => dev.data); + const devices_id = devices.map(dev => $(dev).attr('data')); if (devices_id.length == 1) { const url = "/inventory/tag/devices/".concat(devices_id[0], "/del/"); @@ -228,7 +228,7 @@ function removeTag() { function addTag() { const devices = TableController.getSelectedDevices(); - const devices_id = devices.map(dev => dev.data); + const devices_id = devices.map(dev => $(dev).attr('data')); if (devices_id.length == 1) { $("#addingTagModal .pol").hide(); diff --git a/ereuse_devicehub/static/js/main_inventory.js b/ereuse_devicehub/static/js/main_inventory.js index 9c9b8d0a..d80d6c66 100644 --- a/ereuse_devicehub/static/js/main_inventory.js +++ b/ereuse_devicehub/static/js/main_inventory.js @@ -207,7 +207,7 @@ function removeLot() { function removeTag() { const devices = TableController.getSelectedDevices(); - const devices_id = devices.map(dev => dev.data); + const devices_id = devices.map(dev => $(dev).attr("data")); if (devices_id.length == 1) { const url = `/inventory/tag/devices/${devices_id[0]}/del/`; window.location.href = url; @@ -218,7 +218,7 @@ function removeTag() { function addTag() { const devices = TableController.getSelectedDevices(); - const devices_id = devices.map(dev => dev.data); + const devices_id = devices.map(dev => $(dev).attr("data")); if (devices_id.length == 1) { $("#addingTagModal .pol").hide(); $("#addingTagModal .btn-primary").show();