Merge pull request #319 from eReuse/change/3659-weekly-report
add report command cli
This commit is contained in:
commit
5d2161c5e4
0
ereuse_devicehub/commands/__init__.py
Normal file
0
ereuse_devicehub/commands/__init__.py
Normal file
52
ereuse_devicehub/commands/reports.py
Normal file
52
ereuse_devicehub/commands/reports.py
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
import csv
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
# import click
|
||||||
|
|
||||||
|
|
||||||
|
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())
|
20
ereuse_devicehub/commands/users.py
Normal file
20
ereuse_devicehub/commands/users.py
Normal file
|
@ -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))
|
|
@ -15,6 +15,8 @@ from teal.teal import Teal
|
||||||
|
|
||||||
from ereuse_devicehub.auth import Auth
|
from ereuse_devicehub.auth import Auth
|
||||||
from ereuse_devicehub.client import Client, UserClient
|
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.config import DevicehubConfig
|
||||||
from ereuse_devicehub.db import db
|
from ereuse_devicehub.db import db
|
||||||
from ereuse_devicehub.dummy.dummy import Dummy
|
from ereuse_devicehub.dummy.dummy import Dummy
|
||||||
|
@ -27,6 +29,7 @@ from ereuse_devicehub.templating import Environment
|
||||||
class Devicehub(Teal):
|
class Devicehub(Teal):
|
||||||
test_client_class = Client
|
test_client_class = Client
|
||||||
Dummy = Dummy
|
Dummy = Dummy
|
||||||
|
Report = Report
|
||||||
jinja_environment = Environment
|
jinja_environment = Environment
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
|
@ -67,6 +70,8 @@ class Devicehub(Teal):
|
||||||
self.id = inventory
|
self.id = inventory
|
||||||
"""The Inventory ID of this instance. In Teal is the app.schema."""
|
"""The Inventory ID of this instance. In Teal is the app.schema."""
|
||||||
self.dummy = Dummy(self)
|
self.dummy = Dummy(self)
|
||||||
|
self.report = Report(self)
|
||||||
|
self.get_token = GetToken(self)
|
||||||
|
|
||||||
@self.cli.group(
|
@self.cli.group(
|
||||||
short_help='Inventory management.',
|
short_help='Inventory management.',
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import csv
|
import csv
|
||||||
import json
|
|
||||||
import enum
|
|
||||||
import uuid
|
|
||||||
import time
|
|
||||||
import datetime
|
import datetime
|
||||||
|
import enum
|
||||||
|
import json
|
||||||
|
import time
|
||||||
|
import uuid
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
from typing import Callable, Iterable, Tuple
|
from typing import Callable, Iterable, Tuple
|
||||||
|
@ -13,27 +13,31 @@ import flask
|
||||||
import flask_weasyprint
|
import flask_weasyprint
|
||||||
import teal.marshmallow
|
import teal.marshmallow
|
||||||
from boltons import urlutils
|
from boltons import urlutils
|
||||||
from flask import make_response, g, request
|
|
||||||
from flask import current_app as app
|
from flask import current_app as app
|
||||||
|
from flask import g, make_response, request
|
||||||
from flask.json import jsonify
|
from flask.json import jsonify
|
||||||
from teal.cache import cache
|
from teal.cache import cache
|
||||||
from teal.resource import Resource, View
|
from teal.resource import Resource, View
|
||||||
|
|
||||||
from ereuse_devicehub import auth
|
from ereuse_devicehub import auth
|
||||||
from ereuse_devicehub.db import db
|
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.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.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.device.views import DeviceView
|
||||||
from ereuse_devicehub.resources.documents.device_row import (DeviceRow, StockRow, ActionRow,
|
from ereuse_devicehub.resources.documents.device_row import (
|
||||||
InternalStatsRow)
|
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 import LotView
|
||||||
from ereuse_devicehub.resources.lot.models import Lot
|
from ereuse_devicehub.resources.lot.models import Lot
|
||||||
from ereuse_devicehub.resources.action.models import Trade
|
from ereuse_devicehub.resources.user.models import Session
|
||||||
from ereuse_devicehub.resources.device.models import Device
|
|
||||||
from ereuse_devicehub.resources.hash_reports import insert_hash, ReportHash, verify_hash
|
|
||||||
|
|
||||||
|
|
||||||
class Format(enum.Enum):
|
class Format(enum.Enum):
|
||||||
|
@ -469,11 +473,11 @@ class DocumentDef(Resource):
|
||||||
stamps_view = StampsView.as_view('StampsView', definition=self, auth=app.auth)
|
stamps_view = StampsView.as_view('StampsView', definition=self, auth=app.auth)
|
||||||
self.add_url_rule('/stamps/', defaults={}, view_func=stamps_view, methods={'GET', 'POST'})
|
self.add_url_rule('/stamps/', defaults={}, view_func=stamps_view, methods={'GET', 'POST'})
|
||||||
|
|
||||||
internalstats_view = InternalStatsView.as_view(
|
# internalstats_view = InternalStatsView.as_view(
|
||||||
'InternalStatsView', definition=self, auth=app.auth)
|
# 'InternalStatsView', definition=self, auth=app.auth)
|
||||||
internalstats_view = app.auth.requires_auth(internalstats_view)
|
# internalstats_view = app.auth.requires_auth(internalstats_view)
|
||||||
self.add_url_rule('/internalstats/', defaults=d, view_func=internalstats_view,
|
# self.add_url_rule('/internalstats/', defaults=d, view_func=internalstats_view,
|
||||||
methods=get)
|
# methods=get)
|
||||||
|
|
||||||
actions_view = ActionsDocumentView.as_view('ActionsDocumentView',
|
actions_view = ActionsDocumentView.as_view('ActionsDocumentView',
|
||||||
definition=self,
|
definition=self,
|
||||||
|
|
|
@ -41,7 +41,6 @@ def test_api_docs(client: Client):
|
||||||
'/documents/check/',
|
'/documents/check/',
|
||||||
'/documents/devices/',
|
'/documents/devices/',
|
||||||
'/documents/erasures/',
|
'/documents/erasures/',
|
||||||
'/documents/internalstats/',
|
|
||||||
'/documents/lots/',
|
'/documents/lots/',
|
||||||
'/inventory/search/',
|
'/inventory/search/',
|
||||||
'/documents/stamps/',
|
'/documents/stamps/',
|
||||||
|
|
|
@ -756,7 +756,6 @@ def test_verify_stamp_erasure_certificate(user: UserClient, client: Client):
|
||||||
assert "alert alert-info" in response
|
assert "alert alert-info" in response
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
|
||||||
def test_get_document_internal_stats(user: UserClient, user2: UserClient):
|
def test_get_document_internal_stats(user: UserClient, user2: UserClient):
|
||||||
"""Tests for get the internal stats."""
|
"""Tests for get the internal stats."""
|
||||||
|
|
||||||
|
|
Reference in a new issue