Compare commits

..

1646 Commits

Author SHA1 Message Date
pedro c4dff2afb6 devicehub entrypoint: put one worker 2024-04-03 17:59:33 +02:00
pedro a0b14461b3 docker: bugfix devicehub entrypoint
entrypoint was being put inside the working directory, which is
preserved

that made entrypoint "persistent", avoiding future updates

solution is to put it in the root (/), which is not preserved
2024-04-03 13:13:32 +02:00
pedro b607eedf5f adapt entrypoint to idhub trustchain pilot 2024-04-03 13:01:40 +02:00
Cayo Puigdefabregas 8b4f4b2c6e fix host 2024-04-02 22:03:50 +02:00
Cayo Puigdefabregas 2a7a10178c fix https 2024-04-02 13:24:55 +02:00
Cayo Puigdefabregas 2283f20ab2 fix access to table with schema and without 2024-03-27 17:32:57 +01:00
Cayo Puigdefabregas a4c7b2a744 add new flow for get credentials from wallet 2024-03-26 18:51:46 +01:00
Cayo Puigdefabregas da8d43f9f6 fix new dlt_keys structure 2024-03-26 18:25:06 +01:00
Cayo Puigdefabregas f0710e88ec first step 2024-03-26 17:52:58 +01:00
Cayo Puigdefabregas 55839a26ea fix did 2024-02-22 17:49:44 +01:00
Cayo Puigdefabregas 39f0300a28 fix register_user_dlt when there are more than one user 2024-02-22 11:57:05 +01:00
Cayo Puigdefabregas e5dbb09025 fix roles 2024-02-21 16:19:39 +01:00
Cayo Puigdefabregas c948b0bca5 update readme 2024-02-20 15:59:20 +01:00
Cayo Puigdefabregas cd440b9931 fix get role in register_user_dlt 2024-02-16 20:59:21 +01:00
Cayo Puigdefabregas 44b1a245b6 fix get role in register_user_dlt 2024-02-16 20:34:36 +01:00
Cayo Puigdefabregas f9ec594a0e update READMES 2024-02-16 20:18:17 +01:00
pedro 397e4978e2 docker refactor
- use latest tag
- use launcher (which builds and deploys the docker compose)
- small fixes
- updated README
2024-02-16 11:02:18 +01:00
Cayo Puigdefabregas 77dd11ea23 uncomment create user demo un initdatas 2024-02-16 10:51:56 +01:00
Cayo Puigdefabregas 2c039c0a12 comment create user demo un initdatas 2024-02-16 10:48:49 +01:00
Cayo Puigdefabregas 4d416f426c fix lot trade 2024-02-09 22:41:56 +01:00
Cayo Puigdefabregas 74fe50b6fb add action Recycled with dlt proof 2024-02-09 20:45:17 +01:00
Cayo Puigdefabregas 9fb2b1c94a add snapthot and dpp to action EWaste 2024-02-08 18:40:02 +01:00
Cayo Puigdefabregas 708dad64aa fix readme and env.example 2024-02-08 12:41:54 +01:00
Cayo Puigdefabregas b680a3574d add user_devicehub example 2024-02-08 12:36:03 +01:00
Cayo Puigdefabregas b6e9be306b fix READMES 2024-02-08 12:34:55 +01:00
Cayo Puigdefabregas 95700e7ba4 comment set rols for users 2024-02-05 14:54:00 +01:00
Cayo Puigdefabregas 5c02b424c1 fix version of ereuseapitest 2024-02-05 12:40:18 +01:00
Cayo Puigdefabregas 51e54450d8 fix get_manuals 2024-01-30 21:54:34 +01:00
Cayo Puigdefabregas 9100f315f9 fix config 2024-01-30 20:33:09 +01:00
Cayo Puigdefabregas 8b0d1f4b7d add env vars 2024-01-30 18:32:32 +01:00
Cayo Puigdefabregas 46bfef2585 remove engine_options 2024-01-30 18:29:45 +01:00
Cayo Puigdefabregas 660fe41b62 fix change max connections 2024-01-30 12:04:17 +01:00
Cayo Puigdefabregas e687cef4a3 fix docker 2024-01-29 19:46:53 +01:00
Cayo Puigdefabregas af338cfa4c fix 2024-01-29 18:53:06 +01:00
Cayo Puigdefabregas 72c8fac29e fix new api for iota 2024-01-29 18:49:02 +01:00
Cayo Puigdefabregas ca273285fe Merge branch 'new_dpp' into oidc4vp-new 2024-01-29 17:49:35 +01:00
Cayo Puigdefabregas 0197ddb4d1 fix new dict of dlt_secrets 2024-01-24 14:47:42 +01:00
Cayo Puigdefabregas 87e3c3e917 fix 2024-01-23 18:38:34 +01:00
Cayo Puigdefabregas 5aaa88971a not create user in docker init 2024-01-23 18:14:46 +01:00
Cayo Puigdefabregas 16ae2c08da add new register user in dlt 2024-01-23 18:11:40 +01:00
Cayo Puigdefabregas 6a75423532 add new register user in dlt 2024-01-23 18:11:40 +01:00
Cayo Puigdefabregas c9238e8e6a get ABAC_URL from config in user model 2024-01-23 18:11:40 +01:00
Cayo Puigdefabregas 53289b0dfc add ABAC_URL in config 2024-01-23 18:11:40 +01:00
pedro 14e37ef8c4 docker: IMPORT_SNAPSHOTS: change default to no 2024-01-23 12:56:26 +01:00
Cayo Puigdefabregas 1a5384e302 change url of iota explorer 2024-01-10 18:39:33 +01:00
Cayo Puigdefabregas d2b4de7c41 fix loop 2023-12-14 12:53:48 +01:00
Cayo Puigdefabregas fcc4b34424 fix check credentials in loop 2023-12-14 12:48:46 +01:00
Cayo Puigdefabregas 69d1873da4 fix now vcredential is a list 2023-12-14 10:19:39 +01:00
Cayo Puigdefabregas a33613b21d fix & in the url 2023-12-14 09:51:52 +01:00
Cayo Puigdefabregas 9721344244 fix presentation_definition_uri 2023-12-14 09:39:46 +01:00
Cayo Puigdefabregas 2806e7ab18 fix filter 2023-12-13 19:07:29 +01:00
Cayo Puigdefabregas 37fb688f77 fix login_required 2023-12-13 18:56:00 +01:00
Cayo Puigdefabregas 6c7395c26f fix primarykey 2023-12-13 18:49:52 +01:00
Cayo Puigdefabregas 18600af272 fix next_url 2023-12-13 10:39:00 +01:00
Cayo Puigdefabregas 278377090a flow for connect to wallet 2023-12-12 20:40:11 +01:00
Cayo Puigdefabregas fc7d7b4549 get roles from credential 2023-12-11 21:30:56 +01:00
Cayo Puigdefabregas 543aad813d try conenct to api iota for validation 2023-12-08 20:54:44 +01:00
Cayo Puigdefabregas 950cc59cae new endpoint 2023-12-06 14:03:49 +01:00
Cayo Puigdefabregas ada42f291a add abac datas in session 2023-11-06 16:48:03 +01:00
Cayo Puigdefabregas ab4ec523c3 add Iota did and attributes 2023-11-06 13:23:47 +01:00
pedro 20ee5ae411 docker: remove unneeded env var 2023-10-24 09:14:18 +02:00
pedro 57eb978dc4 docker-compose: upgrade images 2023-10-24 08:54:08 +02:00
pedro c6ec665865 env.example: new DEPLOYMENT var 2023-10-24 08:49:55 +02:00
pedro 5a0990f22a docker: new features regarding persistence
- added db persistence
- bugfix init_flagfile, as now its volume is persisted, it really does
  the configuration step when needed
- also added production deployment for the non dpp deployment
2023-10-24 08:43:27 +02:00
Cayo Puigdefabregas 0ad35de5d6 add new changes of ereuseapitest 2023-10-23 19:43:10 +02:00
Cayo Puigdefabregas aa966b5b93 change name of algorithm 2023-10-20 12:29:49 +02:00
Cayo Puigdefabregas bc3d3abcd7 add endpoint for check the proofs 2023-10-03 14:37:49 +02:00
pedro 9ca92f4c56 dc.yml: update docker images 2023-10-01 11:38:32 +02:00
Cayo Puigdefabregas 15d6851043 explain the new vars 2023-09-29 14:29:00 +02:00
pedro bcb4c69677 add optional dpp_module and snapshots
- dpp_module becomes optional
  - docker compose for simple devicehub and with the dpp module
  - changed logic in entrypoint so different parts are configured or
  - not depending on the new DPP_MODULE env var
- optional snapshots
  - new default directory for SNAPSHOTS_PATH
  - new env var IMPORT_SNAPSHOTS to optionally import the snapshots or not
- new Make file targets:
  - dc_up_devicehub: docker compose for simple devicehub
  - dc_up_devicehub_dpp: docker compose for devicehub with DPP_module
2023-09-29 10:51:48 +02:00
pedro b594022194 make API_RESOLVER more resilient (normalize urls) 2023-09-29 10:46:01 +02:00
pedro c226138ff2 bugfix dockerfile build: add app.py from example 2023-09-29 10:46:01 +02:00
Cayo Puigdefabregas 6c3831d103 fix readme 2023-09-29 10:05:35 +02:00
Cayo Puigdefabregas a7f5de96a5 fix text README 2023-09-29 10:03:42 +02:00
Cayo Puigdefabregas 594fe1483f changes readme 2023-09-28 18:31:18 +02:00
Cayo Puigdefabregas ece944ea3f change README 2023-09-28 17:57:56 +02:00
Cayo Puigdefabregas ac3d318fc9 change the examples files 2023-09-28 16:40:36 +02:00
Cayo Puigdefabregas 0181bd34ae changes on README.md 2023-09-28 16:37:02 +02:00
Cayo Puigdefabregas 5fa6f46acc clean example app.py 2023-09-28 13:15:46 +02:00
Cayo Puigdefabregas 4ba7bcc956 fix link in readme 2023-09-28 08:49:32 +02:00
cayop fde966ec13
Merge pull request #463 from eReuse/dpp_docker
add dockerization of devicehub dpp
2023-09-28 08:38:51 +02:00
Cayo Puigdefabregas cb0c7f1cb6 fix env example 2023-09-28 08:37:41 +02:00
Cayo Puigdefabregas 68c342ee18 fix readme 2023-09-28 08:27:05 +02:00
Cayo Puigdefabregas b614fad41f fix readme 2023-09-28 08:26:10 +02:00
Cayo Puigdefabregas 7e088eefc8 new readme 2023-09-28 08:24:03 +02:00
Cayo Puigdefabregas 82bf535915 new readme 2023-09-28 08:18:24 +02:00
Cayo Puigdefabregas 843324bd17 fix strip slash in domain 2023-09-28 08:17:47 +02:00
Cayo Puigdefabregas 740007b804 fix env.example 2023-09-27 08:03:09 +02:00
Cayo Puigdefabregas c8ab0a959e add Manufacturer DPP in templates 2023-09-26 17:32:42 +02:00
pedro dce2873158 update env.example: we need real reachable URLs
specially for the OIDC demo
2023-09-21 22:12:03 +02:00
pedro 2dc40e95fe docker-compose: update images 2023-09-21 21:40:29 +02:00
pedro 5a965e245e docker-compose: use unique users for each instance 2023-09-21 21:40:16 +02:00
pedro 6a58dcc68f refactor Makefile
- use ereuse project (to avoid confusion between devicehub project and
devicehub image)
- facilitate the docker image URL on the make docker_build
2023-09-21 21:37:37 +02:00
pedro 2c4b0006cc bugfix oidc client not working
the file gets created, but you need to wait some time to get data into it
2023-09-21 21:33:11 +02:00
pedro 7a85ebd8f8 client_id_config is not a global env var
then, move it to downcase to avoid confusion
2023-09-21 20:57:00 +02:00
pedro 9dec42bd05 docker-compose: update devicehub image 2023-09-21 19:07:14 +02:00
pedro 37069ff561 bugfix docker compose devicehub client id 2023-09-21 18:44:43 +02:00
pedro b423a53cfe automate OIDC setup for devicehub server & client 2023-09-21 18:44:43 +02:00
pedro 260ac90f86 reorder env vars in entrypoint for coherence 2023-09-21 18:44:43 +02:00
pedro f37800dcd3 docker: publish new image and put it in d-compose 2023-09-21 18:44:43 +02:00
pedro 907bf2dba0 add basic dockerization to devicehub dpp 2023-09-21 18:44:43 +02:00
Cayo Puigdefabregas 0b70f42daa fix json doble quotes 2023-09-21 18:40:21 +02:00
Cayo Puigdefabregas 8a7a9476fe fix command add contract oidc 2023-09-21 13:19:30 +02:00
Cayo Puigdefabregas 5069c793cf change result as json 2023-09-20 16:33:20 +02:00
Cayo Puigdefabregas 0f26bf63c6 add contract oidc command 2023-09-20 15:54:22 +02:00
Cayo Puigdefabregas bf3474e3db update README 2023-09-19 09:05:59 +02:00
Cayo Puigdefabregas 274c99db43 add context to json for only chassis 2023-09-18 16:35:30 +02:00
Cayo Puigdefabregas 2f250402e3 add context to json 2023-09-18 16:20:55 +02:00
Cayo Puigdefabregas 3f86242bfb add context to json 2023-09-18 16:05:10 +02:00
Cayo Puigdefabregas 5de416796e fix proof action 2023-09-18 11:41:58 +02:00
Cayo Puigdefabregas 0fb4fa5ba6 refactor 2023-08-22 10:41:48 +02:00
Cayo Puigdefabregas 33fc69013f fix reset password 2023-08-16 10:45:54 +02:00
Cayo Puigdefabregas d5f8b1ec75 render datas energy star in operator role 2023-08-10 16:44:20 +02:00
Cayo Puigdefabregas 5aee8f3f8f get energy star datas from manuals api 2023-08-10 16:43:45 +02:00
Cayo Puigdefabregas 9c2f22c77a remove pdbs 2023-08-10 16:43:03 +02:00
Cayo Puigdefabregas db706503fc fix printing messages 2023-08-03 17:32:50 +02:00
Cayo Puigdefabregas 11f3b7730a more info about the chekers for every step 2023-08-03 16:36:51 +02:00
Cayo Puigdefabregas 7857a85e8f add ignore files 2023-07-28 10:32:35 +02:00
Cayo Puigdefabregas ac02246ddc add check install 2023-07-28 10:15:05 +02:00
Cayo Puigdefabregas 33efa7ab75 fix remove files 2023-07-25 15:54:24 +02:00
Cayo Puigdefabregas 74789d66d1 add pip install 2023-07-25 13:18:01 +02:00
Cayo Puigdefabregas 1a107bb2db create snapshot_files directory 2023-07-25 13:04:01 +02:00
Cayo Puigdefabregas 0d2dd2fcb1 add input in snapshot command for select user 2023-07-25 09:49:29 +02:00
Cayo Puigdefabregas 7f449aa95c add new call to proofs 2023-07-24 19:23:26 +02:00
Cayo Puigdefabregas 4f2cfe5c47 remove files 2023-07-24 12:33:04 +02:00
Cayo Puigdefabregas 1b4159d58b fix format 2023-07-24 09:29:46 +02:00
Cayo Puigdefabregas 13d36f5650 upload snapshot from web client 2023-07-21 18:02:22 +02:00
Cayo Puigdefabregas 9ff20740dd get user from .env config 2023-07-21 17:21:08 +02:00
Cayo Puigdefabregas 0b0d9edaad add command upload snapshot 2023-07-21 17:20:15 +02:00
cayop 77f39ef78c
Update Definition-dpp.md
fix documentation
2023-07-19 11:34:58 +02:00
cayop 947deb45af
Update Definition-dpp.md 2023-07-19 11:32:48 +02:00
Cayo Puigdefabregas 7c91314d4a Document define what is a Dpp 2023-07-19 11:23:41 +02:00
Cayo Puigdefabregas 56b36ab244 add laer datas in operator template 2023-07-17 17:13:55 +02:00
Cayo Puigdefabregas 79cb5279e9 Merge branch 'dpp' into join-to-manuals 2023-07-13 17:18:35 +02:00
Cayo Puigdefabregas fdb4d90ab4 add chid of components 2023-07-11 16:39:04 +02:00
Cayo Puigdefabregas b5ae2b0629 add manuals in templates: 2023-07-07 16:57:36 +02:00
Cayo Puigdefabregas 748516edaf example of repair manuals 2023-07-06 17:49:54 +02:00
Cayo Puigdefabregas 5e3af04a8c Merge branch 'dpp' into join-to-manuals 2023-07-06 16:35:50 +02:00
Cayo Puigdefabregas 472d742db2 allow verify dpp 2023-07-06 12:54:18 +02:00
Cayo Puigdefabregas 36c61d49ff get manuals first step 2023-07-06 11:39:37 +02:00
Cayo Puigdefabregas 2f9a2edb44 make calls to manuals resouce 2023-07-05 11:54:58 +02:00
Cayo Puigdefabregas 8762705cb5 fix nonce 2023-06-23 14:29:08 +02:00
Cayo Puigdefabregas 0438cbb509 fix 2023-06-23 11:59:45 +02:00
Cayo Puigdefabregas e451668ff9 fix templates 2023-06-23 10:22:46 +02:00
Cayo Puigdefabregas 945c0d42f9 fix, phid_dpp instead of json_wb 2023-06-21 12:48:36 +02:00
Cayo Puigdefabregas 94ddc76e17 fix sequence in database 2023-06-21 12:47:41 +02:00
Cayo Puigdefabregas 453fa52963 role instead of rol 2023-06-21 12:32:44 +02:00
Cayo Puigdefabregas 73fa8a6d28 role instead of rol 2023-06-21 12:27:10 +02:00
Cayo Puigdefabregas a68784c94c env migrations 2023-06-16 18:20:11 +02:00
Cayo Puigdefabregas 311ca3ca51 mv did as a module and migrates files to dpp 2023-06-16 18:05:52 +02:00
Cayo Puigdefabregas 1f78c184b5 Merge branch 'testing' into dpp 2023-06-16 13:12:38 +02:00
Cayo Puigdefabregas 99f4c71ee1 fix test 2023-06-16 13:04:37 +02:00
Cayo Puigdefabregas a6684999a8 add dpp and oidc modules 2023-06-16 12:39:03 +02:00
Cayo Puigdefabregas 8f333e04ae Merge branch 'testing' into dpp 2023-06-16 11:55:41 +02:00
Cayo Puigdefabregas 57caf52c02 fix initial id 2023-06-16 11:55:21 +02:00
Cayo Puigdefabregas 52da9c99ba commands 2023-06-16 09:31:16 +02:00
Cayo Puigdefabregas 7ddcb8ead0 resolve conflict 2023-06-15 18:32:49 +02:00
Cayo Puigdefabregas 523ca3e892 add some modules commands 2023-06-15 18:30:55 +02:00
cayop c1d03e9525
Merge pull request #459 from eReuse/bugfix/init_deploy
Bugfix/init deploy
2023-06-15 18:29:16 +02:00
Cayo Puigdefabregas 5f1c7c8b4a add command adduser 2023-06-15 17:56:34 +02:00
Cayo Puigdefabregas fad008b25d command initdatas 2023-06-15 16:41:47 +02:00
Cayo Puigdefabregas 17c88ef4b1 get rols 2023-06-15 10:43:43 +02:00
Cayo Puigdefabregas 3c23c8ce09 add rols to user 2023-06-14 16:06:10 +02:00
Cayo Puigdefabregas 47e918dc07 Merge branch 'testing' into dpp 2023-06-14 10:45:42 +02:00
Cayo Puigdefabregas ffaff20025 update changelog 2023-06-14 10:43:52 +02:00
cayop e0f986f4fe
Merge pull request #458 from eReuse/bugfix/erasure-placeholders
not datawipe for placeholders computers
2023-06-14 10:43:18 +02:00
Cayo Puigdefabregas 7638a6dab4 not datawipe for placeholders computers 2023-06-14 10:17:01 +02:00
Cayo Puigdefabregas c27040296d up version 2023-06-13 17:14:39 +02:00
cayop 56e04cf7c5
Merge pull request #457 from eReuse/bugfix/4431-certificate
change format erase datawipe
2023-06-13 17:14:49 +02:00
Cayo Puigdefabregas 1bdf0c8baa change format erase datawipe 2023-06-13 16:48:52 +02:00
Cayo Puigdefabregas 80486136bd Merge branch 'testing' into dpp 2023-06-13 12:32:08 +02:00
cayop 48604e1a8f
Merge pull request #456 from eReuse/bugfix/4418-datastorage-placeholder
fix bug
2023-06-13 11:47:57 +02:00
Cayo Puigdefabregas 314e944208 fix bug 2023-06-13 11:07:24 +02:00
cayop 7c032a2d27
Merge pull request #455 from eReuse/bugfix/4326-datawipe
Bugfix/4326 datawipe
2023-06-13 09:29:50 +02:00
Cayo Puigdefabregas dc07b4973b add datastorage to csv 2023-06-13 08:53:17 +02:00
Cayo Puigdefabregas 57882ca2c5 add placeholder datastorage 2023-06-12 18:47:55 +02:00
Cayo Puigdefabregas 6aa643c197 mobile datawipe in csv report and pdf certificate 2023-06-12 17:38:32 +02:00
Cayo Puigdefabregas 2543f7f761 add datastorage placeholders 2023-06-09 18:17:06 +02:00
Cayo Puigdefabregas 850398f7ed add id federated to actions 2023-06-08 19:04:55 +02:00
Cayo Puigdefabregas f7a60647b9 resolve conflict 2023-06-08 11:44:08 +02:00
cayop a38c990412
Merge pull request #454 from eReuse/bugfix/4350-edit-imei
Bugfix/4350 edit imei
2023-06-07 16:26:18 +02:00
Cayo Puigdefabregas 4390f681f5 fix tests 2023-06-07 15:52:41 +02:00
Cayo Puigdefabregas bb6365c519 fix tests smartphons 2023-06-07 13:36:08 +02:00
Cayo Puigdefabregas 2ef6e6cb49 remove validate of imei 2023-06-07 12:50:21 +02:00
Cayo Puigdefabregas 2c171d8e26 remove validation of imei 2023-06-07 12:28:00 +02:00
Cayo Puigdefabregas 4d5761ac02 fix config get 2023-06-06 17:42:15 +02:00
Cayo Puigdefabregas 66e162db4d add services in register a new device 2023-06-06 16:47:47 +02:00
Cayo Puigdefabregas 79c2ecbd81 add ID_FEDERATED 2023-06-05 17:11:28 +02:00
Cayo Puigdefabregas b29086e46d fix 2023-06-05 16:03:35 +02:00
Cayo Puigdefabregas 9119143a63 fix 2023-06-05 16:00:10 +02:00
Cayo Puigdefabregas 9671333635 fix layout and drop rols for public page of device 2023-06-02 18:24:07 +02:00
Cayo Puigdefabregas e3b8543a12 fix rols 2023-06-02 18:05:03 +02:00
Cayo Puigdefabregas 49d19ec38e add dpp 2023-06-02 11:42:38 +02:00
Cayo Puigdefabregas 312f8a01bf add details for user validated 2023-06-02 11:00:05 +02:00
Cayo Puigdefabregas c82db8caa0 up target-version 2023-06-02 09:54:43 +02:00
Cayo Puigdefabregas 4db71b2af4 add rols to session 2023-06-02 09:54:14 +02:00
Cayo Puigdefabregas 4a6c82ef55 isort 2023-05-31 18:29:00 +02:00
Cayo Puigdefabregas df6b09d051 new did endpoint 2023-05-31 16:30:49 +02:00
cayop aab3addc20
Merge pull request #453 from eReuse/changes/4377-setup-page
fix pdf
2023-05-31 11:19:02 +02:00
Cayo Puigdefabregas 5ceeba3af7 fix pdf 2023-05-31 10:54:11 +02:00
Cayo Puigdefabregas f423d5ea34 fix wb templates 2023-05-31 09:41:14 +02:00
Cayo Puigdefabregas 15b25d8aeb fix wb templates 2023-05-31 09:32:59 +02:00
Cayo Puigdefabregas 2c2cd19688 fix template 2023-05-31 09:17:01 +02:00
Cayo Puigdefabregas 851fc123e1 up version of wb 2023-05-31 09:14:06 +02:00
cayop 1ffad380b3
Merge pull request #452 from eReuse/changes/4377-setup-page
new wbSettings templates
2023-05-31 09:10:36 +02:00
Cayo Puigdefabregas 1f913eebaa add version 14.4 2023-05-30 22:37:30 +02:00
Cayo Puigdefabregas ccbf2f98a7 new wbSettings templates 2023-05-30 22:29:01 +02:00
Cayo Puigdefabregas efacba6aab Merge branch 'testing' into new-trublo 2023-05-30 16:34:12 +02:00
cayop e4017cf5cc
Merge pull request #451 from eReuse/bugfix/4381
Bugfix/4381
2023-05-30 13:10:32 +02:00
Cayo Puigdefabregas 35ffb8239f fix pdf 2023-05-30 12:49:37 +02:00
Cayo Puigdefabregas a95d643755 fix eraseDataWipe in csv 2023-05-30 11:49:42 +02:00
Cayo Puigdefabregas 80f7d102e1 Merge branch 'testing' into bugfix/4381 2023-05-30 10:17:42 +02:00
Cayo Puigdefabregas 5af553b6a3 Merge branch 'master' into testing 2023-05-30 10:16:55 +02:00
Cayo Puigdefabregas 8c69585800 fix a bug of seting hid in components 2023-05-30 10:13:55 +02:00
Cayo Puigdefabregas 085c5151bc fix 2023-05-30 09:45:19 +02:00
Cayo Puigdefabregas 7990f4518b redirect in logout 2023-05-29 13:48:43 +02:00
cayop a42dfe5469
Merge pull request #450 from eReuse/feature/4357-add-datawipe-csv
Feature/4357 add datawipe csv
2023-05-29 09:25:46 +02:00
Cayo Puigdefabregas a3b71ec996 add test for EraseDataWipe 2023-05-26 17:35:53 +02:00
Cayo Puigdefabregas 2e2b346daa fix test 2023-05-26 17:16:20 +02:00
Cayo Puigdefabregas 631bfa2774 change certificate pdf 2023-05-26 17:11:47 +02:00
Cayo Puigdefabregas 5eea698695 revert upgrade datawipe 2023-05-25 16:20:26 +02:00
Cayo Puigdefabregas b571b26433 upgrade datawipe to erasedatawipe 2023-05-25 10:57:40 +02:00
Cayo Puigdefabregas 46860660e0 fix modules calls 2023-05-24 12:26:52 +02:00
Cayo Puigdefabregas 838d9180ad fix teal import inm did resource 2023-05-24 10:27:31 +02:00
Cayo Puigdefabregas 48be3bae64 fix teal import inm did resource 2023-05-24 10:25:04 +02:00
Cayo Puigdefabregas 4e610f0903 resolve conflict 2023-05-23 15:28:13 +02:00
Cayo Puigdefabregas 39b04f3709 new datawipe 2023-05-23 13:45:32 +02:00
Cayo Puigdefabregas b5a77ace2f add logout 2023-05-19 18:17:22 +02:00
Cayo Puigdefabregas 7b2bfd095c adapt client oidc 2023-05-19 17:05:02 +02:00
Cayo Puigdefabregas 7a128e6e7f add link to oidc in user profile 2023-05-16 10:05:50 +02:00
Cayo Puigdefabregas 3cf87f7f95 add vars and get_user_id in model user 2023-05-12 12:05:41 +02:00
Cayo Puigdefabregas ebdb6949c9 Merge branch 'master' into testing 2023-05-10 17:01:59 +02:00
Cayo Puigdefabregas 8e54f34519 fix set_hid 2023-05-07 19:43:30 +02:00
cayop 31629b3f16
Merge pull request #449 from eReuse/changes/changes-filter-devices
hide submit in filter of list of devices
2023-05-04 17:25:06 +02:00
Cayo Puigdefabregas 906dceed56 fix 2023-05-04 17:04:08 +02:00
Cayo Puigdefabregas acc5f6ed78 fix devices lot shared 2023-05-04 16:14:43 +02:00
Cayo Puigdefabregas 02752ee2b8 hide submit in filter of list of devices 2023-05-04 12:58:32 +02:00
cayop b8593bd63f
Merge pull request #448 from eReuse/feature/4343-share-lot
Feature/4343 share lot
2023-05-04 10:59:29 +02:00
Cayo Puigdefabregas e845709027 fix test export lots 2023-05-04 10:35:20 +02:00
Cayo Puigdefabregas 7b9c33ca4f fix base template 2023-05-04 10:27:40 +02:00
Cayo Puigdefabregas 9cafc4f72b shared and customer details in exports lots 2023-05-04 10:23:56 +02:00
cayop 8ba853b14a
Merge pull request #447 from eReuse/feature/4343-share-lot
Feature/4343 share lot
2023-04-28 15:10:29 +02:00
Cayo Puigdefabregas 4e5dbe8cd1 fix tests 2023-04-28 14:45:22 +02:00
Cayo Puigdefabregas c9f996dd8e fix schema in sql query 2023-04-28 12:54:30 +02:00
Cayo Puigdefabregas d3b624fbd1 drop pdb 2023-04-28 12:11:09 +02:00
Cayo Puigdefabregas 0547e4cf32 allow get device for export when is a share lot 2023-04-28 12:10:25 +02:00
Cayo Puigdefabregas e365c366f4 share lot structure 2023-04-26 18:25:03 +02:00
Cayo Puigdefabregas e649d65b5d add validations in public page of device 2023-04-26 12:24:38 +02:00
cayop 9da841fc1f
Merge pull request #446 from eReuse/changes/4217-add-columns-export-devices
Bugfix/4217 fix id supplier column in export devices
2023-04-21 17:17:42 +02:00
Cayo Puigdefabregas 0e3aa1ce04 fix tests 2023-04-21 16:20:30 +02:00
Cayo Puigdefabregas 075dc8d5b0 fix tests 2023-04-21 13:03:12 +02:00
Cayo Puigdefabregas 750d3e7db6 fix id supplier in export devices 2023-04-21 12:47:53 +02:00
cayop a47e99ce0b
Merge pull request #439 from eReuse/without-teal
Without teal
2023-04-20 18:25:04 +02:00
Cayo Puigdefabregas 8f5835fa4f fix test selenium 2023-04-20 18:07:12 +02:00
Cayo Puigdefabregas f9ed33d46d Merge branch 'testing' into without-teal 2023-04-20 17:59:17 +02:00
Cayo Puigdefabregas 119b4938c0 upgrade version 2023-04-20 10:52:19 +02:00
Cayo Puigdefabregas e224f22b85 Merge branch 'testing' into without-teal 2023-04-20 09:18:17 +02:00
Cayo Puigdefabregas 1a7c2f3a01 fix required in form 2023-04-19 16:17:29 +02:00
Cayo Puigdefabregas ce7693dd9b fix import teal in migration 2023-04-19 11:30:12 +02:00
Cayo Puigdefabregas dcae036271 Merge branch 'testing' into without-teal 2023-04-19 11:26:53 +02:00
cayop 6dce475256
Merge pull request #445 from eReuse/feature/4319-add-columns-list-documents-device
fix FileField
2023-04-19 11:19:37 +02:00
Cayo Puigdefabregas 0ce12bbfba fix it 2023-04-18 18:15:44 +02:00
cayop 9e7a1ec5bd
Merge pull request #444 from eReuse/feature/4319-add-columns-list-documents-device
Feature/4319 add columns list documents device
2023-04-18 11:44:39 +02:00
Cayo Puigdefabregas 6692233a22 fix 2023-04-18 11:08:43 +02:00
Cayo Puigdefabregas b6b8c6a1f9 add new columns 2023-04-18 10:10:43 +02:00
Cayo Puigdefabregas ae5992f4c0 Merge branch 'testing' into without-teal 2023-04-17 11:51:44 +02:00
cayop 2e0173b7dc
Merge pull request #443 from eReuse/feature/4109-documents-in-device
Feature/4109 documents in device
2023-04-17 11:41:12 +02:00
Cayo Puigdefabregas cd4d1bb095 add select field 2023-04-04 17:23:50 +02:00
Cayo Puigdefabregas 2f27095c84 documents in devices 2023-04-04 16:56:27 +02:00
Cayo Puigdefabregas 645bdf3750 new device document 2023-03-31 18:06:22 +02:00
Cayo Puigdefabregas 3a08347276 Merge branch 'without-teal' of github.com:eReuse/devicehub-teal into without-teal 2023-03-30 12:49:15 +02:00
cayop 4059dc3a7a
Merge pull request #442 from eReuse/feature/4126-edit-documents
Feature/4126 edit documents
2023-03-29 14:11:06 +02:00
Cayo Puigdefabregas 509a445480 add edit document form 2023-03-29 13:40:27 +02:00
Cayo Puigdefabregas ca0b31059f Merge branch 'feature/4125-remove-documents' into feature/4126-edit-documents 2023-03-29 13:38:30 +02:00
Cayo Puigdefabregas 7d228a61f9 change name of link trade-document 2023-03-29 13:38:25 +02:00
cayop 8f8883242e
Merge pull request #441 from eReuse/feature/4125-remove-documents
allow remove a document
2023-03-29 11:32:04 +02:00
Cayo Puigdefabregas 8b69962374 fix test 2023-03-29 10:46:07 +02:00
Cayo Puigdefabregas d1c332e891 add edit document in template 2023-03-29 10:43:30 +02:00
Cayo Puigdefabregas 1515302d98 allow remove a document 2023-03-28 17:09:47 +02:00
cayop 290c20d46e
Merge pull request #440 from eReuse/feature/4174-report-devices
add lots in export devices
2023-03-27 17:35:22 +02:00
Cayo Puigdefabregas 4b9f1c02b9 fix render test 2023-03-27 17:17:13 +02:00
Cayo Puigdefabregas 745b9966df add lots in export devices 2023-03-27 16:34:25 +02:00
Cayo Puigdefabregas f3926e3b92 fix import in tests 2023-03-27 11:13:58 +02:00
Cayo Puigdefabregas 309b266fe9 fix import in tests 2023-03-27 11:07:30 +02:00
Cayo Puigdefabregas e6c07851d4 fix lint checks 2023-03-27 10:55:26 +02:00
Cayo Puigdefabregas e6f91db4e4 correct versions of dependencies 2023-03-27 10:22:08 +02:00
Cayo Puigdefabregas 83f1e4c18f add ereuse_utils as module 2023-03-21 17:31:43 +01:00
Cayo Puigdefabregas 01ef359bd4 add teal as module 2023-03-21 12:08:13 +01:00
Cayo Puigdefabregas e624ab7a7a Merge branch 'testing' of github.com:eReuse/devicehub-teal into testing 2023-03-20 18:08:48 +01:00
Cayo Puigdefabregas 2ff6f40228 fix links 2023-03-20 18:08:37 +01:00
cayop 91d13808a7
Merge pull request #437 from eReuse/bugfix/4283-replace-erasure-sanitization
Bugfix/4283 replace erasure sanitization
2023-03-20 18:01:51 +01:00
Cayo Puigdefabregas 6a14727f31 fix names of titles 2023-03-20 17:34:20 +01:00
Cayo Puigdefabregas a7aae591aa fix names of titles 2023-03-20 17:32:58 +01:00
Cayo Puigdefabregas ad52bad3f6 up version to 2.5.1 2023-03-17 11:35:35 +01:00
Cayo Puigdefabregas ad1e5e06d9 proofs in details 2023-03-16 10:35:37 +01:00
Cayo Puigdefabregas 7dc7ca2026 Merge branch 'testing' into new-trublo 2023-03-15 17:57:16 +01:00
cayop 494a14c7f0
Merge pull request #436 from eReuse/bugfix/doc-erasure-fix-hid
fix hide hid of erasure certificate
2023-03-15 17:50:39 +01:00
Cayo Puigdefabregas c94801deab Merge branch 'master' into bugfix/doc-erasure-fix-hid 2023-03-15 17:23:46 +01:00
Cayo Puigdefabregas a27dc0914c fix hide hid of erasure certificate 2023-03-15 17:19:31 +01:00
Cayo Puigdefabregas e559ea30da add proof in document 2023-03-15 16:40:29 +01:00
Cayo Puigdefabregas 174928872f resolve conflict 2023-03-15 15:49:35 +01:00
Cayo Puigdefabregas ddcd1697e6 fix template 2023-03-14 17:52:49 +01:00
Cayo Puigdefabregas 6fa5a25a4a Merge branch 'testing' 2023-03-14 17:16:24 +01:00
Cayo Puigdefabregas d1abc8075f fix 2023-03-14 12:50:57 +01:00
cayop 56c970e810
Merge pull request #434 from eReuse/bugfix/4281
Bugfix/4281
2023-03-13 18:25:47 +01:00
Cayo Puigdefabregas e7833c1727 fix test 2023-03-13 17:59:08 +01:00
Cayo Puigdefabregas 21d251e6c0 add reopen transfer 2023-03-13 17:52:00 +01:00
Cayo Puigdefabregas b140dc5f89 fix without logo 2023-03-13 17:04:57 +01:00
cayop d97eb08cce
Merge pull request #433 from eReuse/bugfix/4280-pdf
fix with last lot incoming
2023-03-13 12:48:26 +01:00
Cayo Puigdefabregas d0688cc751 fix with last lot incoming 2023-03-13 12:24:57 +01:00
cayop 25794f2fb4
Merge pull request #432 from eReuse/bugfix/4279-pdf
Bugfix/4279 pdf
2023-03-10 22:14:03 +01:00
Cayo Puigdefabregas 498d2ec92f fix test 2023-03-10 21:56:17 +01:00
Cayo Puigdefabregas cf5150b7c9 fix lots 2023-03-10 21:15:00 +01:00
Cayo Puigdefabregas ba02351f59 fix lots 2023-03-10 20:13:54 +01:00
Cayo Puigdefabregas 1c82fcfa30 add customer details for default if there are more than one incoming lot 2023-03-10 18:34:09 +01:00
Cayo Puigdefabregas 20ccb385d8 add lots in list of erasures actions 2023-03-09 18:38:54 +01:00
Cayo Puigdefabregas 6d722bb19f feedback when there are one error in sanitization form 2023-03-09 18:07:16 +01:00
Cayo Puigdefabregas 93d6502a66 fix server report n_computers 2023-03-09 13:09:05 +01:00
Cayo Puigdefabregas 6b0110adda fix server report 2023-03-09 12:40:46 +01:00
Cayo Puigdefabregas de24cae235 add placeholder 2023-03-09 10:43:35 +01:00
cayop e6de54873e
Merge pull request #431 from eReuse/bugfix/4277-testing-erasure
Bugfix/4277 testing erasure
2023-03-08 18:08:12 +01:00
Cayo Puigdefabregas 40a151df5a fix order of devices 2023-03-08 17:22:26 +01:00
Cayo Puigdefabregas 54372ad2f9 put comment as placeholder in field of logo 2023-03-08 12:43:37 +01:00
Cayo Puigdefabregas eb945ae348 fix ortigraphy 2023-03-08 12:34:52 +01:00
Cayo Puigdefabregas ab6f89c3d2 fix sanitization_entity in view 2023-03-08 10:58:28 +01:00
Cayo Puigdefabregas eed1075771 save with commit for default 2023-03-07 16:41:24 +01:00
Cayo Puigdefabregas 7534df083c fix definition of model SanitizationEntity 2023-03-07 16:40:45 +01:00
Cayo Puigdefabregas 0ff2bcae92 use populate_obj 2023-03-07 16:39:52 +01:00
Cayo Puigdefabregas 8f58bcb24e fix type 2023-03-07 10:20:25 +01:00
Cayo Puigdefabregas 327e5f20cb merge testing 2023-03-03 17:45:41 +01:00
Cayo Puigdefabregas 1e62af56a6 fix parent 2023-03-03 16:00:54 +01:00
Cayo Puigdefabregas 2da17d06c0 fix dpp template in new version 2023-03-03 12:11:11 +01:00
Cayo Puigdefabregas 5bfd69f785 fix customer name in pdf 2023-03-03 10:11:18 +01:00
Cayo Puigdefabregas c8fb5db63c add dpp in device details 2023-03-02 10:35:37 +01:00
Cayo Puigdefabregas b6b5e5d29d fix fields string 2023-03-01 18:06:41 +01:00
Cayo Puigdefabregas 12b196fd8e fix register dpp 2023-03-01 12:49:30 +01:00
cayop ea2d446595
Merge pull request #430 from eReuse/features/4251-delete-certificate
Features/4251 delete certificate
2023-02-28 17:46:42 +01:00
Cayo Puigdefabregas be271d59ea fix test render 2023-02-28 17:25:42 +01:00
Cayo Puigdefabregas 6b9965f57e drop pdbs 2023-02-28 17:25:20 +01:00
Cayo Puigdefabregas 7f6acf2db8 drop simple-datatables from local 2023-02-28 16:56:00 +01:00
Cayo Puigdefabregas e900f5f298 erasure on server 2023-02-28 16:43:28 +01:00
Cayo Puigdefabregas 69cb07d55a Merge branch 'testing' into features/4251-delete-certificate 2023-02-27 10:08:47 +01:00
Cayo Puigdefabregas fb413671fc fix size of ram and data storage 2023-02-25 11:29:41 +01:00
Cayo Puigdefabregas 26ed0f3577 details device 2023-02-24 17:01:38 +01:00
Cayo Puigdefabregas c9d23d5e6a benchamark to False in wbSettings template 2023-02-23 17:14:21 +01:00
Cayo Puigdefabregas 5f9abe83d6 change version of usody iso to 14.2.0 2023-02-23 17:13:16 +01:00
Cayo Puigdefabregas 26f8d191fb . 2023-02-23 17:07:00 +01:00
nad c24460009e update wb iso to 14.2.0 2023-02-23 12:52:57 +01:00
nad 5bdcf4da7f disable WB_BENCHMARK in wb settings 2023-02-23 12:52:27 +01:00
Cayo Puigdefabregas ef8825568f add proof 2023-02-20 19:16:43 +01:00
Cayo Puigdefabregas 599f15d5ae fixed proof register 2023-02-20 11:37:19 +01:00
Cayo Puigdefabregas 1907f2508a fix proof 2023-02-17 17:26:38 +01:00
Cayo Puigdefabregas 80013bcc90 . 2023-02-17 10:45:55 +01:00
Cayo Puigdefabregas 680a7b89e2 change base of template 2023-02-15 18:30:45 +01:00
Cayo Puigdefabregas 12d64aefdc save customer datas in transfers 2023-02-14 20:03:33 +01:00
Cayo Puigdefabregas 8207ca9ab2 save datas and initialized form 2023-02-14 12:15:21 +01:00
Cayo Puigdefabregas 8cd7777fc6 add model, form and template of sanitization entity 2023-02-13 20:35:31 +01:00
cayop c58dc367e6
Merge pull request #428 from eReuse/bugfix/2476-onlyhardrive
only sync DataStorages
2023-02-13 12:15:12 +01:00
Cayo Puigdefabregas ead6f3af78 fix tests 2023-02-13 11:57:12 +01:00
Cayo Puigdefabregas 77c8e2181f only sync DataStorages 2023-02-10 20:09:22 +01:00
Cayo Puigdefabregas 8efccf4f58 fix migrations order 2023-02-09 11:48:50 +01:00
Cayo Puigdefabregas 6b54521d50 fix versions 2023-02-08 12:54:38 +01:00
Cayo Puigdefabregas 184a9877bc fix footer 2023-02-02 11:02:36 +01:00
Cayo Puigdefabregas 2553a9cdd0 fix footer 2023-02-02 10:58:37 +01:00
Cayo Puigdefabregas 4055365bc9 fix dummy 2023-02-02 10:58:09 +01:00
cayop 6fc6402397
Merge pull request #427 from eReuse/new-legal-pages
Updated links to Terms & Conditions and Privacy Policy now hosted in …
2023-02-02 10:34:19 +01:00
Stephan Fortelny bed2c534b5 Updated links to Terms & Conditions and Privacy Policy now hosted in English on usody.com 2023-02-02 08:01:53 +01:00
Cayo Puigdefabregas 799c003a09 fix 2023-02-01 17:29:43 +01:00
Cayo Puigdefabregas 7a8cbe11a6 fix 2023-02-01 17:25:39 +01:00
cayop bea63148b2
Merge pull request #426 from eReuse/feature/2078-public-page
add new version of public page
2023-02-01 17:16:12 +01:00
Cayo Puigdefabregas 7dc3ac9530 fix test 2023-02-01 16:35:27 +01:00
Cayo Puigdefabregas 6b5db31922 add new version of public page 2023-02-01 13:28:31 +01:00
cayop cbf2d607a1
Merge pull request #425 from eReuse/feature/4245
Feature/4245
2023-01-31 13:12:35 +01:00
Cayo Puigdefabregas 00c07161e0 add link to price 2023-01-31 12:38:47 +01:00
Nadeu 38b77c111a
Update 14.1.0 iso 2023-01-27 12:04:54 +01:00
cayop c961573c91
Merge pull request #424 from eReuse/bugfix/4219-testing
Bugfix/4219 testing
2023-01-26 12:15:00 +01:00
Cayo Puigdefabregas 6c9334fa76 fix test 2 2023-01-26 11:35:08 +01:00
Cayo Puigdefabregas de9b525737 . 2023-01-26 10:46:34 +01:00
Cayo Puigdefabregas 32dc4445e4 fix some things of interaction with the api and register dpps 2023-01-25 13:20:43 +01:00
Cayo Puigdefabregas e7e595f2c2 add json_wb in snapshot 2023-01-23 19:44:36 +01:00
Cayo Puigdefabregas 45a787aa39 . 2023-01-23 11:52:38 +01:00
Cayo Puigdefabregas 574ab36da4 add registar issuer passport 2023-01-20 18:58:25 +01:00
Cayo Puigdefabregas fbe8600cc1 resolve conflicts 2023-01-19 13:42:01 +01:00
Cayo Puigdefabregas 9053c89f47 add chid_dpp and phid_dpp in models 2023-01-19 13:33:32 +01:00
Cayo Puigdefabregas 8ed1e2296d Merge branch 'testing' into new-trublo 2023-01-19 12:26:29 +01:00
Cayo Puigdefabregas 8dd926de80 add dpp 2023-01-19 12:26:25 +01:00
Nadeu 253371376d
Update HWMD iso to 2022.12.2-beta 2023-01-19 11:27:53 +01:00
Nadeu 850278c297
Update HWMD iso to 2022.12.2-beta 2023-01-19 10:27:01 +01:00
Cayo Puigdefabregas faa7c1d605 . 2023-01-18 18:56:04 +01:00
cayop 149bc1c6f6
Merge pull request #423 from eReuse/changes/4025-new-hid
Changes/4025 new hid
2023-01-18 17:49:41 +01:00
Cayo Puigdefabregas 9db949cef2 add correct descriptions in the pop ups 2023-01-18 12:38:08 +01:00
Cayo Puigdefabregas c26d2d69b9 fix filter active TRue 2023-01-17 13:18:18 +01:00
Cayo Puigdefabregas f8d418b4a9 add pop up 2023-01-17 13:07:01 +01:00
Cayo Puigdefabregas a572ef0507 add pop up 2023-01-17 13:00:34 +01:00
Cayo Puigdefabregas 6fc802e159 fix test reliable 2023-01-16 15:26:58 +01:00
Cayo Puigdefabregas 520f1726be reliable device 2023-01-13 17:42:42 +01:00
Cayo Puigdefabregas 5e7d95ba31 Merge branch 'testing' into changes/4025-new-hid 2023-01-11 22:14:32 +01:00
cayop 12aa5e917d
Merge pull request #422 from eReuse/bugfix/simple-datatables
Bugfix/simple datatables
2023-01-11 18:53:10 +01:00
Lint Action 00310a3228 Fix code style issues with ESLint 2023-01-11 17:34:54 +00:00
Cayo Puigdefabregas 7789d972eb fix simple-datatables librarie 2023-01-11 18:32:02 +01:00
Cayo Puigdefabregas 23f4a0e412 fix simple-datatables librarie 2023-01-11 18:31:11 +01:00
Cayo Puigdefabregas ac4e87d2b3 Merge branch 'testing' into changes/4025-new-hid 2023-01-11 17:18:52 +01:00
Cayo Puigdefabregas bc12258db0 create device 2023-01-11 17:17:50 +01:00
Cayo Puigdefabregas 5a0692216a Merge branch 'bugfix/4206-donalo-incoming' 2023-01-11 10:49:36 +01:00
cayop b77c81c16a
Merge pull request #421 from eReuse/bugfix/4206-donalo-incoming
Bugfix/4206 donalo incoming
2023-01-11 10:49:20 +01:00
Cayo Puigdefabregas a265af8864 fix remove placeholder from trade 2023-01-11 10:18:22 +01:00
Cayo Puigdefabregas 9603ac1f43 . 2023-01-11 09:38:39 +01:00
cayop 3606f9dee6
Merge pull request #420 from eReuse/bugfix/4206-donalo-incoming
Bugfix/4206 donalo incoming
2023-01-10 16:59:09 +01:00
Cayo Puigdefabregas f929283f4f fix trades in temporary list 2023-01-10 14:11:42 +01:00
Cayo Puigdefabregas 350aad19c4 get all lots not only temporary 2023-01-10 14:10:49 +01:00
Cayo Puigdefabregas 9c2bc7d7fa put the correct link in the snapshot to warning message 2023-01-10 10:49:32 +01:00
Cayo Puigdefabregas 50856671ed reliable and unreliable device. Active and deactive devices and snapshots 2022-12-23 18:33:49 +01:00
Nadeu 8a8feb3165
Update iso 2022.12.1-beta 2022-12-23 13:53:22 +01:00
Cayo Puigdefabregas 14ce3892ac add new filter in actions for show only active snapshots 2022-12-22 18:39:59 +01:00
Cayo Puigdefabregas bf5c3d6abc add snapshot.active in model and migration file 2022-12-22 18:04:34 +01:00
Cayo Puigdefabregas 62de2126c7 base of form for update type of updated 2022-12-22 12:01:31 +01:00
Cayo Puigdefabregas 5d88d4e516 remove script 2022-12-20 13:37:17 +01:00
Cayo Puigdefabregas 205e111e9d fix tests rate 2022-12-20 11:39:31 +01:00
Cayo Puigdefabregas 2bb6b13e07 fix 2022-12-20 11:06:41 +01:00
Cayo Puigdefabregas 31b62a2d81 check if is active module hid 2022-12-20 10:17:42 +01:00
Cayo Puigdefabregas 84e937026e fix tests 2022-12-19 20:03:34 +01:00
Cayo Puigdefabregas b3b4e8cd2b Merge branch 'testing' into changes/4025-new-hid 2022-12-15 16:17:09 +01:00
cayop 14b61cbaeb
Merge pull request #419 from eReuse/feature/3999-setings
Feature/3999 fix setings_version and template
2022-12-15 10:53:22 +01:00
Cayo Puigdefabregas 1924d7fe71 wb settins 2022-12-15 10:20:17 +01:00
Cayo Puigdefabregas 0f7c9504b0 fix settings_version 2022-12-15 10:18:22 +01:00
Cayo Puigdefabregas 30474fa7e6 Merge branch 'testing' into feature/3999-setings 2022-12-14 17:47:38 +01:00
Cayo Puigdefabregas 83d62b4cb4 Merge branch 'master' into testing 2022-12-14 17:41:55 +01:00
Cayo Puigdefabregas 63c7b29233 https instead of http 2022-12-14 17:41:35 +01:00
Cayo Puigdefabregas c066d8a2af fix tests 2022-12-14 16:57:59 +01:00
Cayo Puigdefabregas 2cc677a555 fix sync 2022-12-14 11:42:11 +01:00
Cayo Puigdefabregas fc36218124 fix set_chid 2022-12-13 20:41:15 +01:00
Cayo Puigdefabregas a0c1cce69a fix template snapshots logs 2022-12-13 20:40:53 +01:00
Cayo Puigdefabregas 1b11162522 clean sync class 2022-12-13 20:40:28 +01:00
Cayo Puigdefabregas da1feef746 fix migration 2022-12-13 14:29:52 +01:00
Cayo Puigdefabregas 27910f2c20 clean 2022-12-13 14:25:44 +01:00
Cayo Puigdefabregas 756925d657 migrations and get_from_db 2022-12-13 14:02:38 +01:00
Cayo Puigdefabregas 254a32d989 test settings version 2022-12-12 14:20:18 +01:00
Cayo Puigdefabregas 9736ee323a test settings version 2022-12-12 14:20:07 +01:00
Cayo Puigdefabregas fac6380bcf . 2022-12-12 14:10:17 +01:00
Cayo Puigdefabregas 4debac4fbe fix dummy 2022-12-12 10:36:33 +01:00
Cayo Puigdefabregas 5e8cf78751 put the forze of validation in the schemas 2022-12-05 19:17:54 +01:00
Cayo Puigdefabregas d6bee33601 fix new hid in build 2022-12-05 17:33:22 +01:00
Cayo Puigdefabregas 4b13995b4f . 2022-12-05 12:40:26 +01:00
Cayo Puigdefabregas 534adbba75 Merge branch 'master' into testing 2022-12-05 10:35:49 +01:00
cayop 01a3a97c2b
Merge pull request #416 from eReuse/bugfix/4131-link-dhid
fix bug
2022-12-05 10:28:35 +01:00
Cayo Puigdefabregas 9a39f3ae9d fix bug 2022-12-05 10:05:12 +01:00
Cayo Puigdefabregas e3f01f4795 fix 2022-12-05 09:58:12 +01:00
Cayo Puigdefabregas 94a586f00b filter correct values 2022-12-02 10:08:03 +01:00
Cayo Puigdefabregas 39f19f676b Merge branch 'testing' into changes/4025-new-hid 2022-12-01 15:59:52 +01:00
Cayo Puigdefabregas 8c979d7741 fix user register 2022-12-01 13:03:24 +01:00
Cayo Puigdefabregas a0e63b2ae9 Merge branch 'testing' into new-trublo 2022-12-01 10:20:39 +01:00
cayop 046a902005
Merge pull request #414 from eReuse/feature/3999-setings
Feature/3999 setings
2022-11-30 17:12:19 +01:00
Cayo Puigdefabregas a2626a0b58 add settings version to version column in snapshots log 2022-11-30 16:46:10 +01:00
Cayo Puigdefabregas 7c6290bd89 add settings version to snapshots model 2022-11-30 16:25:11 +01:00
Cayo Puigdefabregas 4fa6f9f343 Merge branch 'testing' into feature/3999-setings 2022-11-30 16:13:33 +01:00
Cayo Puigdefabregas 341a7b2034 fix bug privacity 2022-11-30 15:26:16 +01:00
Cayo Puigdefabregas fe9c2c1c2d fix bug privacity 2022-11-30 15:19:59 +01:00
cayop f1042b627b
Merge pull request #415 from eReuse/bugfix/4128-prefix-lot-search
put prefix in lots in result of search
2022-11-30 15:04:32 +01:00
Cayo Puigdefabregas 7bc4a7d387 CHANGELOG.md 2022-11-30 13:31:37 +01:00
Cayo Puigdefabregas e36f813d92 put prefix in lots in result of search 2022-11-30 13:28:17 +01:00
Cayo Puigdefabregas 7be17ead58 release 2.5.0 2022-11-30 13:10:49 +01:00
Cayo Puigdefabregas 0a6f9e3bf4 add settings_version to schema 2022-11-30 12:54:11 +01:00
Cayo Puigdefabregas 18281c95e5 remove system_uuid 2022-11-30 12:10:00 +01:00
Cayo Puigdefabregas 3f5ae9fefd change settings template 2022-11-30 11:55:32 +01:00
Cayo Puigdefabregas 785f72692a change settings template 2022-11-30 11:53:19 +01:00
cayop f49ba1f7ba
Merge pull request #413 from eReuse/bugfix/4124-documents-in-lot
fix orther without id
2022-11-30 11:27:27 +01:00
Cayo Puigdefabregas 9fbdaf5834 add test 2022-11-30 10:59:56 +01:00
Cayo Puigdefabregas b1ad7b151d fix orther without id 2022-11-30 10:23:51 +01:00
cayop 0233a2ba6b
Merge pull request #412 from eReuse/bugfix/4122-snapshots-log-type-upload
Bugfix/4122 snapshots log type upload
2022-11-29 18:35:27 +01:00
cayop 4dff032fe6
Merge pull request #411 from eReuse/feature/4094-add-new-fields
Feature/4094 add new fields
2022-11-29 18:11:55 +01:00
Cayo Puigdefabregas d2a4c0ef83 Merge branch 'testing' into bugfix/4122-snapshots-log-type-upload 2022-11-29 18:10:36 +01:00
Cayo Puigdefabregas 4be07130c2 fixed 2022-11-29 18:09:53 +01:00
Cayo Puigdefabregas 040421172f fix definition of others 2022-11-29 17:46:41 +01:00
Cayo Puigdefabregas c392270676 add others device 2022-11-29 16:49:23 +01:00
Cayo Puigdefabregas b84f379468 Merge branch 'testing' into feature/4094-add-new-fields 2022-11-29 10:09:10 +01:00
cayop b98be622e1
Merge pull request #410 from eReuse/feature/4107-search
add advanced search as top search
2022-11-28 18:34:51 +01:00
Cayo Puigdefabregas 9ee24c3e82 put simple table as cdn 2022-11-28 17:09:32 +01:00
Cayo Puigdefabregas 07f947b1ad fix search 2022-11-28 17:00:30 +01:00
Cayo Puigdefabregas 79fbe323a2 try fix 2022-11-28 16:39:43 +01:00
Cayo Puigdefabregas b39388bef0 fix 2022-11-28 15:24:31 +01:00
Cayo Puigdefabregas 994cd3c6ca Merge branch 'feature/4107-search' of github.com:eReuse/devicehub-teal into feature/4107-search 2022-11-28 15:10:29 +01:00
Cayo Puigdefabregas 9da321a925 fix 2022-11-28 15:10:12 +01:00
Lint Action 368d82c007 Fix code style issues with ESLint 2022-11-28 14:05:48 +00:00
Cayo Puigdefabregas 0b6cfb210d add advanced search as top search 2022-11-28 15:00:45 +01:00
cayop 6eb820b69d
Merge pull request #409 from eReuse/feature/4106-pagination
Feature/4106 pagination
2022-11-28 13:39:15 +01:00
Cayo Puigdefabregas 3757873b02 fix bug Title tag in erasure list 2022-11-28 13:12:14 +01:00
Cayo Puigdefabregas f9d679547f pagination in placeholder logs 2022-11-28 12:30:02 +01:00
Cayo Puigdefabregas 5e2dd3344b add pagination to snapshots logs 2022-11-28 11:58:42 +01:00
Cayo Puigdefabregas abc773fe6e add pagination in all list of devices 2022-11-25 18:56:56 +01:00
Cayo Puigdefabregas 789eb1b526 add register devices 2022-11-25 13:27:14 +01:00
Cayo Puigdefabregas e7cf069a33 add api_token 2022-11-24 18:00:16 +01:00
Cayo Puigdefabregas 88b13961fe add permitons to new users 2022-11-24 17:54:25 +01:00
Cayo Puigdefabregas 3a952324c2 change value per_page 2022-11-24 14:02:56 +01:00
cayop 4ae9eeb4c7
Merge pull request #408 from eReuse/feature/3988-real-pagination
Feature/3988 real pagination
2022-11-24 13:55:42 +01:00
Cayo Puigdefabregas eee61dca8e fix test 2022-11-24 13:19:11 +01:00
Cayo Puigdefabregas a544549a81 clean 2022-11-24 12:21:42 +01:00
Cayo Puigdefabregas 0f033c8d83 clean 2022-11-24 11:59:18 +01:00
Cayo Puigdefabregas d7500a2596 add pagination to all devices view 2022-11-24 11:50:56 +01:00
Cayo Puigdefabregas 925ce473e6 put the correct links 2022-11-23 19:22:49 +01:00
Cayo Puigdefabregas ade9fbd018 add raw query 2022-11-23 19:22:26 +01:00
Cayo Puigdefabregas 1efc650bea add simpledatatables 2022-11-23 16:13:30 +01:00
Cayo Puigdefabregas a9504b0b71 first step for pagination 2022-11-23 13:36:34 +01:00
Cayo Puigdefabregas 9d8fb6b04a add dlt keys to the model 2022-11-22 19:12:11 +01:00
Cayo Puigdefabregas ac535cc9b5 add new fields in the filters 2022-11-22 15:44:44 +01:00
cayop 1ab6606cf0
Merge pull request #407 from eReuse/feature/4092-erasure-tabs
Feature/4092 erasure tabs
2022-11-22 12:29:42 +01:00
Cayo Puigdefabregas 796f49f6cf show correctly the ids in the templates 2022-11-22 12:00:17 +01:00
Cayo Puigdefabregas 7bf879bbcf add my_partner for get the partner of one device 2022-11-22 11:59:31 +01:00
Cayo Puigdefabregas 67cf797c6c fixing name hardDrive in filter 2022-11-22 11:58:56 +01:00
cayop 5d8c26ade6
Merge pull request #406 from eReuse/feature/4092-erasure-tabs
Feature/4092 erasure tabs
2022-11-21 17:57:38 +01:00
Cayo Puigdefabregas 2d67c9afd2 version 2022-11-21 17:37:51 +01:00
Cayo Puigdefabregas 15d9c86104 add test orphans disks 2022-11-21 17:34:19 +01:00
Cayo Puigdefabregas 0e85b81857 fix test 2022-11-21 15:35:37 +01:00
Cayo Puigdefabregas 6fd87ac8e8 fix label dhid 2022-11-21 15:34:00 +01:00
Cayo Puigdefabregas fb430f2138 add lot to list erasure 2022-11-21 15:14:02 +01:00
Cayo Puigdefabregas 35dd08c9c8 fixing add hdd to lot 2022-11-21 15:13:36 +01:00
Cayo Puigdefabregas a09e087b0e add tab for Hard drives without device 2022-11-21 13:24:56 +01:00
Cayo Puigdefabregas d1eed13b0a tabs 2022-11-18 18:46:10 +01:00
Cayo Puigdefabregas 905716f74b fix live view 2022-11-18 10:20:57 +01:00
Cayo Puigdefabregas c263dc0ae0 changelog 2022-11-18 10:18:54 +01:00
Cayo Puigdefabregas 9b08c083ce set hid to components 2022-11-16 17:40:59 +01:00
Cayo Puigdefabregas f0ffe27671 fix device set_hid 2022-11-16 17:40:35 +01:00
Cayo Puigdefabregas 81b28b2663 add script 2022-11-16 13:48:19 +01:00
Cayo Puigdefabregas d030ed9b23 set_old_hid 2022-11-16 13:47:50 +01:00
Cayo Puigdefabregas 236fcac0b8 add new hid in devices 2022-11-16 11:51:31 +01:00
Cayo Puigdefabregas 0ae12e71a6 Merge branch 'master' into testing 2022-11-14 10:23:32 +01:00
cayop 4bf27706db
Merge pull request #404 from eReuse/bugfix/4074-table-row
fixing table.rows()
2022-11-14 10:24:46 +01:00
Cayo Puigdefabregas 17df239599 fixing table.rows() 2022-11-14 10:00:33 +01:00
cayop 3809ae76e1
Merge pull request #403 from eReuse/bugfix/4073-obada
change delimiter
2022-11-11 18:58:36 +01:00
Cayo Puigdefabregas efa9693f16 fixing obada test 2022-11-11 18:34:41 +01:00
Cayo Puigdefabregas b99be1a144 change delimiter 2022-11-11 18:26:15 +01:00
cayop 6addddd974
Merge pull request #402 from eReuse/feature/add-reset-password-link
add reset password link in login page
2022-11-11 18:03:06 +01:00
Cayo Puigdefabregas 79dff1d361 add reset password link in login page 2022-11-11 17:42:29 +01:00
cayop cf5a7651a0
Merge pull request #401 from eReuse/bugfix/4042-new-var-in-environment
fix db_host
2022-11-08 18:59:33 +01:00
Cayo Puigdefabregas 25f2287e98 fix db_host 2022-11-08 18:35:47 +01:00
cayop fe33f2d7e7
Merge pull request #400 from eReuse/bugfix/4046-drop-register-user
remove user_registration
2022-11-08 18:12:56 +01:00
Cayo Puigdefabregas 2c01183604 fix test_basic 2022-11-08 17:52:14 +01:00
Cayo Puigdefabregas 1b7d37b50a drop register in tests 2022-11-08 17:37:10 +01:00
Cayo Puigdefabregas 4df33e8808 remove user_registration 2022-11-08 13:32:29 +01:00
cayop 48de1d5f47
Merge pull request #399 from eReuse/bugfix/4042-new-var-in-environment
put api_host in config
2022-11-07 17:34:19 +01:00
Cayo Puigdefabregas 79877d09a1 put api_host in config 2022-11-07 17:08:03 +01:00
cayop 3d658a9051
Merge pull request #398 from eReuse/bugfix/4028-placeholder-in-new-components
Bugfix/4028 placeholder in new components
2022-11-07 11:57:03 +01:00
Cayo Puigdefabregas 41eb390e39 Merge branch 'master' into testing 2022-11-07 11:56:16 +01:00
Cayo Puigdefabregas d8541d917c fix orohans storage with parents 2022-11-07 11:25:01 +01:00
cayop 375a2de5c1
Merge pull request #397 from eReuse/feature/4023-obada
add obada standard
2022-11-04 15:27:34 +01:00
Cayo Puigdefabregas b2205c56f9 add obada standard 2022-11-04 10:37:56 +01:00
cayop c784fb7499
Merge pull request #396 from eReuse/changes/3853-report
Changes/3853 report
2022-11-03 23:56:57 +01:00
Cayo Puigdefabregas 09a0a30386 fixing bug 2022-11-03 18:19:56 +01:00
Cayo Puigdefabregas c14f40fccb add test 2022-11-03 17:49:18 +01:00
Cayo Puigdefabregas 74d10e1951 add test 2022-11-03 17:49:01 +01:00
Cayo Puigdefabregas 6ee62eb415 test 2022-11-03 13:28:49 +01:00
Cayo Puigdefabregas 6c7ae1bb75 remove report of devicehub commands 2022-11-02 19:44:39 +01:00
Cayo Puigdefabregas eae036d7c0 remove internal stats of actual devicehub 2022-11-02 12:00:39 +01:00
Cayo Puigdefabregas 1cb0634bf1 add ignore files 2022-11-02 09:57:50 +01:00
cayop 3a7a8d6e1d
Merge pull request #395 from eReuse/changes/3943-wb-response
change response
2022-10-28 16:41:24 +02:00
Cayo Puigdefabregas 04a3ec99de change response 2022-10-28 14:08:51 +02:00
cayop 2252fe93cd
Merge pull request #393 from eReuse/features/3969-improvements-login
Features/3969 improvements login
2022-10-28 10:40:44 +02:00
Cayo Puigdefabregas 67cfac6adc fix tests 2022-10-28 10:08:11 +02:00
Cayo Puigdefabregas 4bbec903ef refactor in a module register 2022-10-27 20:10:08 +02:00
Cayo Puigdefabregas 7041bfcf76 change email text 2022-10-27 18:22:54 +02:00
Cayo Puigdefabregas 045b7b4f95 fix test login 2022-10-27 10:43:08 +02:00
Cayo Puigdefabregas 61f2507ead new login style 2022-10-26 18:04:16 +02:00
cayop eb1649f506
Merge pull request #391 from eReuse/feature/3959-dhid-in-erasure
add dhid as column in erasure section
2022-10-26 12:08:07 +02:00
Cayo Puigdefabregas 44985d07a1 add dhid as column in erasure section 2022-10-26 11:26:09 +02:00
cayop 0aa4696fe0
Merge pull request #390 from eReuse/bugfix/edit-placeholder
fix image in edit device
2022-10-26 10:03:56 +02:00
Cayo Puigdefabregas 563e2ec652 Merge branch 'master' into testing 2022-10-26 10:03:07 +02:00
Cayo Puigdefabregas 7c4a3bd770 tests 2022-10-26 09:43:01 +02:00
Cayo Puigdefabregas e30990cc1b fix render image None 2022-10-26 09:33:28 +02:00
Cayo Puigdefabregas 2a8da254d9 fix image in edit device 2022-10-25 17:54:58 +02:00
Cayo Puigdefabregas 9a157eaaee Merge branch 'master' into testing 2022-10-25 16:49:32 +02:00
cayop dfdbf8f1f7
Merge pull request #389 from eReuse/bugfix/3960-datastorage-details
Bugfix/3960 datastorage details
2022-10-25 16:40:53 +02:00
Cayo Puigdefabregas 694663c412 add script for rebuild disks without placeholder 2022-10-25 15:09:03 +02:00
Cayo Puigdefabregas 9d7869929c fix disks without placeholder 2022-10-25 11:10:39 +02:00
Cayo Puigdefabregas 4c2f37dfec resolve conflict 2022-10-24 18:33:40 +02:00
cayop 95ac4e794b
Merge pull request #388 from eReuse/bugfix/3962-system-uuid
2 computers with diferents motherboard with the same system-uuid
2022-10-24 18:27:46 +02:00
Cayo Puigdefabregas 4fa4a4c553 fix text error 2022-10-24 17:58:25 +02:00
Cayo Puigdefabregas b73526768b 2 computers with diferents motherboard with the same system-uuid 2022-10-24 17:46:57 +02:00
cayop 9d3b54c593
Merge pull request #387 from eReuse/changes/3861-setup
add template for Enhanced Secure Erasure
2022-10-21 18:53:01 +02:00
Cayo Puigdefabregas aba6548d9c add point 2022-10-21 18:23:33 +02:00
Cayo Puigdefabregas a5bf59c561 add template for Enhanced Secure Erasure 2022-10-21 17:43:21 +02:00
cayop 13605abbaf
Merge pull request #386 from eReuse/feature/3729-user-registration
Feature/3729 user registration
2022-10-20 18:03:09 +02:00
Cayo Puigdefabregas 72b139a2bc fix requirements 2022-10-20 17:41:06 +02:00
Cayo Puigdefabregas da7f03aa53 fix flask_mail 2022-10-20 17:31:33 +02:00
Cayo Puigdefabregas 61bd4e0642 add tests 2022-10-20 15:59:17 +02:00
Cayo Puigdefabregas 469ce1c6e0 pass emails to templates 2022-10-20 12:51:20 +02:00
Cayo Puigdefabregas c93c143cc8 add token to user registration and admin email 2022-10-19 18:55:34 +02:00
Cayo Puigdefabregas 9e86f0e3ae send email 2022-10-19 13:35:53 +02:00
Cayo Puigdefabregas c2d81b1b29 Merge branch 'testing' into feature/3729-user-registration 2022-10-18 17:15:28 +02:00
Cayo Puigdefabregas c8a4b16667 CHANGELOG.md and change version 2022-10-18 17:01:38 +02:00
cayop f33499cb23
Merge pull request #385 from eReuse/bugfix/3957-unbinding
fix components placeholder in unbinding
2022-10-18 16:32:28 +02:00
Cayo Puigdefabregas 2a32ba47b8 fix components placeholder in unbinding 2022-10-18 13:48:03 +02:00
cayop 177fbe1109
Merge pull request #384 from eReuse/feature/3830-redirect-to-twin
add tests and redirect from abstract device to twin page
2022-10-18 11:45:39 +02:00
Cayo Puigdefabregas 106ab2f650 add tests and redirect from abstract device to twin page 2022-10-18 11:18:50 +02:00
Cayo Puigdefabregas fc86181311 change snapshot id for snapshot uuid 2022-10-18 09:49:54 +02:00
Cayo Puigdefabregas 5d5ed0c552 add version of isos 2022-10-17 19:01:53 +02:00
cayop 00e40cbdeb
Merge pull request #383 from eReuse/changes/3861-setup
Changes/3861 setup
2022-10-17 18:48:14 +02:00
Cayo Puigdefabregas fb46f48461 fix text settings setup 2022-10-17 18:25:12 +02:00
Cayo Puigdefabregas fc297ee5f8 add is_server_erase in snapshot action 2022-10-17 18:07:16 +02:00
Cayo Puigdefabregas fee98f9d30 second version of layout for settings 2022-10-17 11:35:14 +02:00
Cayo Puigdefabregas 2e31af4dfa Merge branch 'testing' into changes/3861-setup 2022-10-17 09:36:53 +02:00
cayop fa990fe050
Merge pull request #382 from eReuse/features/3858-storage-management
fix template device list
2022-10-14 17:02:34 +02:00
Cayo Puigdefabregas c9a3dbf6c6 fix template device list 2022-10-14 16:39:38 +02:00
cayop 99dfe40984
Merge pull request #381 from eReuse/features/3858-storage-management
Features/3858 storage management
2022-10-14 16:05:15 +02:00
Cayo Puigdefabregas a54942a8a8 add kangaroo form 2022-10-14 15:47:54 +02:00
Cayo Puigdefabregas ce09de4133 add tests 2022-10-14 15:33:43 +02:00
Cayo Puigdefabregas 6b173de5a8 setup kangaroo server 2022-10-13 18:21:44 +02:00
cayop 14a4e2f868
Merge pull request #380 from eReuse/bugfix/3833-print-label
fix layout print label
2022-10-11 18:23:09 +02:00
Cayo Puigdefabregas 5819154c5a fix layout print label 2022-10-11 18:04:25 +02:00
Cayo Puigdefabregas c8c542189a drop comments 2022-10-11 16:01:35 +02:00
Cayo Puigdefabregas b77d7abaa4 layout settings 2022-10-11 16:00:38 +02:00
Cayo Puigdefabregas b66871e9c2 first step for layout new settings 2022-10-10 17:44:20 +02:00
cayop 3914e72463
Merge pull request #379 from eReuse/changes/3925-datatime-representation
change representation data times
2022-10-10 13:50:31 +02:00
Cayo Puigdefabregas 9e41555a2f change representation data times 2022-10-10 13:24:31 +02:00
cayop 5d5a52376b
Merge pull request #378 from eReuse/feature/3854-new-button-transfer
Feature/3854 new button transfer
2022-10-10 13:10:38 +02:00
Cayo Puigdefabregas 0a657a3b45 fix tests transfer 2022-10-10 11:10:39 +02:00
Cayo Puigdefabregas 50882ee56a 3924 redirect cancel to reffered 2022-10-10 09:08:12 +02:00
cayop 1d48515008
Merge pull request #377 from eReuse/features/3842-prefix-lots-in-device-list
add prefix to lots name in the list of devices
2022-10-06 19:13:22 +02:00
Cayo Puigdefabregas 7775208b28 add prefix to lots name in the list of devices 2022-10-06 18:47:32 +02:00
cayop fbf70aac89
Merge pull request #376 from eReuse/feature/3854-new-button-transfer
add new buttons for transfer
2022-10-06 18:25:18 +02:00
Cayo Puigdefabregas 9c45665241 fix test 2022-10-06 17:16:53 +02:00
Cayo Puigdefabregas abe3c44213 add new buttons for transfer 2022-10-06 16:56:12 +02:00
cayop b7d2c88664
Merge pull request #375 from eReuse/changes/3840-name-column
change type for type upload
2022-10-06 16:08:25 +02:00
Cayo Puigdefabregas 4b1f92573a change type for type upload 2022-10-06 16:06:14 +02:00
cayop ff2b1d3be0
Merge pull request #374 from eReuse/changes/3883-identifiers-link
move links identifier and data storage to top
2022-10-06 15:56:17 +02:00
Cayo Puigdefabregas 1cd929e06b move links identifier and data storage to top 2022-10-06 15:32:09 +02:00
cayop 72ce086625
Merge pull request #373 from eReuse/changes/3881-details-lots
Enhancement - UX Lots
2022-10-06 15:19:24 +02:00
Cayo Puigdefabregas cc105fd330 changes button documents in a transfer 2022-10-06 14:41:40 +02:00
Cayo Puigdefabregas 792cc1915f move buttons transfer, remove direction transfer 2022-10-06 14:29:40 +02:00
cayop c0d129e713
Merge pull request #372 from eReuse/changes/3880-drop-logo
remove logo
2022-10-06 09:17:15 +02:00
Cayo Puigdefabregas 3d4b74f0ca drop logo 2022-10-06 08:35:00 +02:00
Cayo Puigdefabregas 795d4a20fb up version 2022-10-05 15:05:20 +02:00
Cayo Puigdefabregas 4f1e6c28eb up version to 2.4.1 2022-10-05 14:49:09 +02:00
cayop 6bb43575b6
Merge pull request #371 from eReuse/changes/3888-phid
Changes/3888 phid
2022-10-05 14:23:24 +02:00
Cayo Puigdefabregas c97ef94101 fix tests 2022-10-05 13:45:06 +02:00
Cayo Puigdefabregas 74dde2e626 fix form new device 2022-10-05 13:44:29 +02:00
Cayo Puigdefabregas 722ee1a261 fix phid definition 2022-10-05 12:22:40 +02:00
Cayo Puigdefabregas 77d10661b3 drop phid from UploadPlaceholderForm and drop update placeholder form this form 2022-10-05 09:49:15 +02:00
Cayo Puigdefabregas 926f65e291 id internal in device details 2022-10-05 09:19:16 +02:00
Cayo Puigdefabregas 120646289c id internal when create a new placeholder, wbform 2022-10-05 09:18:42 +02:00
Cayo Puigdefabregas 02f394d81e add id_internal in placeholder model 2022-10-05 09:17:27 +02:00
Cayo Puigdefabregas 45ae96ce33 add id_internal and update phid incremental per user 2022-10-05 09:16:16 +02:00
Cayo Puigdefabregas a9d6ac22f9 mail sender 2022-09-30 19:05:10 +02:00
Cayo Puigdefabregas 9184edf9b1 add mail configs 2022-09-30 19:04:37 +02:00
Cayo Puigdefabregas 6357a15f01 fix migrations 2022-09-30 17:54:26 +02:00
cayop 42d89def9a
Merge pull request #370 from eReuse/bugfix/3859-print-labels
Bugfix/3859 print labels
2022-09-29 17:56:29 +02:00
Cayo Puigdefabregas 6726d439bf fix test render print label 2022-09-29 17:24:00 +02:00
Cayo Puigdefabregas f42ccba706 change contrib for middleware in ProfilerMiddleware 2022-09-29 16:58:30 +02:00
Cayo Puigdefabregas df2dd396ee Merge branch 'testing' into bugfix/3859-print-labels 2022-09-29 13:40:11 +02:00
Santiago L 29f716ab76
Merge pull request #365 from eReuse/dependencies/pip-tools
Manage dependencies using pip-tools
2022-09-29 13:18:27 +02:00
Cayo Puigdefabregas e61a1d88bd unique identifier instead of tags in print label 2022-09-29 12:30:25 +02:00
Santiago L 81fa78f6bb Add pip-compile pre-commit hook 2022-09-29 12:22:22 +02:00
Cayo Puigdefabregas 74166019b2 rebuild view for label details 2022-09-29 12:20:06 +02:00
Santiago L 8fecf9e37b Group workbench dependencies 2022-09-29 12:11:10 +02:00
Santiago L 7245708807 Fix flake8 & reformat using black 2022-09-29 12:11:10 +02:00
Santiago L 332c1088c0 Fix can't compare offset-naive and offset-aware datetimes 2022-09-29 12:11:10 +02:00
Santiago L 7bae66e041 Fix E711, E713 2022-09-29 12:11:10 +02:00
Santiago L c232320d62 Fix flake8: E713, E501 2022-09-29 12:11:10 +02:00
Santiago L 5b99286994 E712 comparison to True should be 'if cond is True:' or 'if cond:' 2022-09-29 12:11:10 +02:00
Santiago L bf423ab515 Fix flake F841 variable assigned never used 2022-09-29 12:11:10 +02:00
Santiago L 814f36d4ee Drop "message" parameter of pytest.raises
Deprecated since version 4.1
https://docs.pytest.org/en/4.6.x/deprecations.html#raises-message-deprecated
2022-09-29 12:11:10 +02:00
Santiago L d9ba3889c0 Revert teal version to 0.2.0a38
There are code not compatible with newer libraries
2022-09-29 12:11:10 +02:00
Santiago L bcec57e752 Fix apispec dependencies 2022-09-29 12:11:10 +02:00
Santiago L 8a49e63592 Run selenium only on reviews 2022-09-29 12:11:10 +02:00
Santiago L fe5d5408fe . 2022-09-29 12:11:10 +02:00
Santiago L d0c91d5d24 Drop apispec-webframeworks requirement 2022-09-29 12:11:10 +02:00
Santiago L cffa950fec Bump to teal 0.2.0a41 which fixes marshmallow version 2022-09-29 12:11:10 +02:00
Santiago L abb675d9d3 Lock 2022-09-29 12:11:10 +02:00
Santiago L 51c42ad94f Lock marshmallow version 2022-09-29 12:11:10 +02:00
Santiago L a85e7c90e1 Manage dependencies using pip-tools
Add instructions to CONTRIBUTING.md & create requirements.in
2022-09-29 12:11:10 +02:00
Santiago L df73cd5657 Fix build-js pre-commit hook
Only run when main_inventory is run & discard parameters
passed by pre-commit which breaks babel command
2022-09-29 12:04:05 +02:00
Cayo Puigdefabregas d36008934a details in register 2022-09-28 17:51:31 +02:00
cayop 7335c04f8e
Merge pull request #369 from eReuse/bugfix/test_data_storage
Bugfix/test data storage
2022-09-28 12:30:10 +02:00
Cayo Puigdefabregas 60992a13da change 100 for None 2022-09-28 11:55:31 +02:00
Cayo Puigdefabregas ab06bd5f44 fix remain_lifetime_percentage 2022-09-28 11:10:34 +02:00
Cayo Puigdefabregas 76c5100fa3 return to copy base 2022-09-28 10:48:41 +02:00
cayop 2aa8f95817
Merge pull request #368 from eReuse/bugfix/migrations-monitors
add migrations for monitors and mobiles
2022-09-27 15:04:48 +02:00
Cayo Puigdefabregas 121012c1f8 add migrations for monitors and mobiles 2022-09-27 13:02:27 +02:00
Cayo Puigdefabregas b2918852b6 add migrations for monitors and mobiles 2022-09-27 12:51:31 +02:00
cayop 187abd550d
Merge pull request #364 from eReuse/bugfix/3843-after-action-go-to
after do action from all device go to all device view
2022-09-27 10:25:40 +02:00
Cayo Puigdefabregas 59d8355728 fix tests 2022-09-27 10:05:49 +02:00
Cayo Puigdefabregas 5614eb36f8 Merge branch 'testing' into bugfix/3843-after-action-go-to 2022-09-27 09:44:45 +02:00
cayop 8627a7dd5f
Merge pull request #367 from eReuse/bugfix/3848-phid-erasure-host
get the phid of the computer from where created
2022-09-26 17:42:00 +02:00
Cayo Puigdefabregas a0c938c044 get the phid of the computer from where created 2022-09-26 17:22:01 +02:00
Cayo Puigdefabregas e589cedb49 fix it 2022-09-26 11:42:50 +02:00
Cayo Puigdefabregas 194fe366fd fix bug 3841 2022-09-26 08:14:04 +02:00
Cayo Puigdefabregas 5f745ad04a change version 2022-09-23 13:29:36 +02:00
Cayo Puigdefabregas bbe285516a CHANGELOG 2022-09-23 13:05:31 +02:00
cayop 2ecec6590a
Merge pull request #363 from eReuse/bugfix/3831-bug-documents
fix bug and test
2022-09-23 12:20:05 +02:00
Cayo Puigdefabregas c5619518f5 fix bug and test 2022-09-23 11:54:19 +02:00
cayop 83b790c97f
Merge pull request #362 from eReuse/feature/3790-snapshot-columns
add new columns to list of snapshots
2022-09-23 11:04:07 +02:00
Cayo Puigdefabregas 0db1d2ed0e fix test 2022-09-23 10:27:29 +02:00
Cayo Puigdefabregas 3b7d396670 no fix now bug 3831 2022-09-23 09:58:14 +02:00
Cayo Puigdefabregas baa48bf5cd add new columns to list of snapshots 2022-09-22 19:14:11 +02:00
cayop 9e82164662
Merge pull request #361 from eReuse/changes/3788-message-phid-error
changes messages for device add form
2022-09-22 13:46:00 +02:00
Cayo Puigdefabregas d8e33e680d changes messages for device add form 2022-09-22 13:16:14 +02:00
cayop 9ac3781f82
Merge pull request #360 from eReuse/bugfix/3819-snapshot-in-lot
add placeholder device in lot instead of snapshot device
2022-09-22 12:35:41 +02:00
Cayo Puigdefabregas 45a21eb210 add placeholder device in lot instead of snapshot device 2022-09-22 12:08:37 +02:00
cayop 4c3851cbbd
Merge pull request #359 from eReuse/bugfix/3821-dhid_bk
fix dhid_bk
2022-09-22 10:49:34 +02:00
Cayo Puigdefabregas 0f6364f075 fix dhid_bk 2022-09-22 10:15:37 +02:00
cayop 553f85776a
Merge pull request #358 from eReuse/changes/3791-changes-export-device
Changes/3791 changes export device
2022-09-21 16:10:59 +02:00
Cayo Puigdefabregas 324aceb04e fixing tests csv exports 2022-09-21 15:47:17 +02:00
cayop f898e0c669
Merge pull request #357 from eReuse/changes/3787-new-actions
change New Actions for Actions
2022-09-21 13:11:50 +02:00
Cayo Puigdefabregas a9947fd93f changes order of columns in export devices 2022-09-21 13:04:57 +02:00
Cayo Puigdefabregas 1292ddbd26 change New Actions for Actions 2022-09-21 12:29:16 +02:00
cayop 06e1aac5a5
Merge pull request #356 from eReuse/feature/3809-new-export-hdds
Feature/3809 new export hdds
2022-09-21 12:22:46 +02:00
Cayo Puigdefabregas ad9b9e4e83 add test exports actions erasure 2022-09-21 12:04:34 +02:00
Cayo Puigdefabregas 47736c8679 add new export actions erasure 2022-09-21 11:35:31 +02:00
Cayo Puigdefabregas b006ec1973 new export actions erasure 2022-09-21 09:42:31 +02:00
cayop 73881f4f25
Merge pull request #355 from eReuse/changes/3786-changes-link-templates
changes links
2022-09-20 18:15:44 +02:00
Cayo Puigdefabregas fed030dd65 changes links 2022-09-20 17:57:37 +02:00
cayop 26a803d1ab
Merge pull request #353 from eReuse/bugfix/2656-update-in-list
get the last update of one device
2022-09-20 17:52:17 +02:00
cayop a7994547b7
Merge pull request #354 from eReuse/bugfix/2656-certificates
fix titles of table
2022-09-20 17:37:50 +02:00
Cayo Puigdefabregas 5642d3880e fix titles of table 2022-09-20 17:36:09 +02:00
Cayo Puigdefabregas c3aa1edd5a get the last update of one device 2022-09-20 17:25:09 +02:00
cayop b1736f68af
Merge pull request #352 from eReuse/bugfix/2656-certificates
fix exports certificate for placeholders
2022-09-20 16:41:00 +02:00
Cayo Puigdefabregas 6d8365564e fix exports certificate for placeholders 2022-09-20 16:02:25 +02:00
cayop d245ca21a6
Merge pull request #351 from eReuse/bugfix/2656-certificates
fix phid
2022-09-20 13:33:13 +02:00
Cayo Puigdefabregas 4d3ab6a70c fix phid 2022-09-20 13:31:21 +02:00
cayop 6542309218
Merge pull request #350 from eReuse/bugfix/2656-certificates
Bugfix/2656 certificates
2022-09-20 13:22:39 +02:00
Cayo Puigdefabregas 60e783258e fix basic test 2022-09-20 13:05:23 +02:00
Cayo Puigdefabregas 31c903230a fix uuid of snapshot 2022-09-20 12:43:04 +02:00
Cayo Puigdefabregas e02644f75c add test for erasure list view 2022-09-20 12:20:30 +02:00
Cayo Puigdefabregas ff765f38f8 add view for list of hdd eraseds 2022-09-20 10:27:02 +02:00
cayop da6ca7bb7e
Merge pull request #349 from eReuse/feature/3785-add-columns-to-inform
add new colums in report
2022-09-19 14:28:18 +02:00
Cayo Puigdefabregas 1ec0f83d28 add erasure total counts 2022-09-19 14:04:30 +02:00
Cayo Puigdefabregas b118edb0a9 erasure only one time for row and disk 2022-09-19 12:10:34 +02:00
Cayo Puigdefabregas b597fdd372 add new colums in report 2022-09-19 11:58:56 +02:00
cayop f100eb2ecb
Merge pull request #348 from eReuse/changes/button-new-device
change buttons new device
2022-09-16 08:30:27 +02:00
Cayo Puigdefabregas f60236e7b7 fix 2022-09-15 17:33:00 +02:00
Cayo Puigdefabregas c50403d95e change buttons new device 2022-09-15 17:11:06 +02:00
cayop c9809061c6
Merge pull request #347 from eReuse/changes/3775-change-names-real-abstract
modify abstract for snapshot and real for placeholder
2022-09-15 12:19:37 +02:00
Cayo Puigdefabregas a1febe8b3f modify abstract for snapshot and real for placeholder 2022-09-15 11:51:27 +02:00
cayop d6ed1240a0
Merge pull request #346 from eReuse/changes/3752-Abstract-for-Fixed
change editable for real
2022-09-14 19:08:58 +02:00
Cayo Puigdefabregas 726627d69a change editable for real 2022-09-14 18:45:40 +02:00
cayop c45e0c969f
Merge pull request #345 from eReuse/changes/3742-remove-generation
remove generation concept in form create device
2022-09-14 18:36:40 +02:00
Cayo Puigdefabregas cf0cd9faa0 remove generation concept in form create device 2022-09-14 18:09:44 +02:00
cayop 07c641f4b9
Merge pull request #344 from eReuse/bugfix/3772-excel-name
add Ods File as description in Placeholders Log
2022-09-14 16:51:58 +02:00
Cayo Puigdefabregas cb48cc9f65 Merge branch 'testing' into bugfix/3772-excel-name 2022-09-14 16:30:56 +02:00
Cayo Puigdefabregas 0ed523ca5c add Ods File as description in Placeholders Log 2022-09-14 15:43:34 +02:00
cayop 2b9d5ce7ed
Merge pull request #343 from eReuse/bugfix/3773-upload-placeholders
forze Phid to be string
2022-09-14 15:35:30 +02:00
Cayo Puigdefabregas 708c2cbdfa forze Phid to be string 2022-09-14 14:58:54 +02:00
cayop d08b93d3fd
Merge pull request #342 from eReuse/changes/3776-new-twin-for-binding
change binding for new twin
2022-09-14 13:38:35 +02:00
Cayo Puigdefabregas 5c644d9a9a change binding for new twin 2022-09-14 13:13:03 +02:00
cayop 44c22898c2
Merge pull request #341 from eReuse/changes/3743-parth-number
Changes/3743 parth number
2022-09-14 12:46:22 +02:00
Cayo Puigdefabregas b39b61bede add part number in device details 2022-09-13 20:03:10 +02:00
Cayo Puigdefabregas 3040676f49 fix tests 2022-09-13 19:53:44 +02:00
Cayo Puigdefabregas d215008927 add part number 2022-09-13 18:15:50 +02:00
Cayo Puigdefabregas d9d0dc533a change message when create a new real device 2022-09-13 13:17:05 +02:00
cayop ce3bab659d
Merge pull request #340 from eReuse/changes/3746-messages-upload-placeholder
update the message of upload placeholders
2022-09-12 18:00:57 +02:00
Cayo Puigdefabregas 9969e6594d update the message of upload placeholders 2022-09-12 17:38:29 +02:00
cayop 56c35b2d54
Merge pull request #339 from eReuse/changes/3745-upload-placeholder
change visual description of upload placeholders
2022-09-12 13:53:02 +02:00
Cayo Puigdefabregas ce666692b3 change visual description of upload placeholders 2022-09-12 13:15:18 +02:00
cayop 22804b4409
Merge pull request #338 from eReuse/bugfix/3741-serialnumber
fix name
2022-09-12 11:55:04 +02:00
Cayo Puigdefabregas 2528775296 change parth for part in device details 2022-09-12 11:37:34 +02:00
Cayo Puigdefabregas 6079e34627 fix name 2022-09-12 11:32:15 +02:00
cayop 39b68fae87
Merge pull request #337 from eReuse/bugfix/3749-csv-placeholders
fix upload csv placeholders
2022-09-12 11:22:08 +02:00
Cayo Puigdefabregas f3b03a1d46 fix upload csv placeholders 2022-09-12 10:55:49 +02:00
cayop 560c9004ef
Merge pull request #336 from eReuse/bugfix/3728-filter-unassigned
change only_unassigned for one specific url
2022-09-09 14:07:06 +02:00
Cayo Puigdefabregas 3f4ad1d57a fix basic test 2022-09-09 13:44:51 +02:00
Cayo Puigdefabregas fcff7e8d02 change only_unassigned for one specific url 2022-09-09 11:48:23 +02:00
cayop 2edd9fbe6c
Merge pull request #335 from eReuse/bugfix/3748-upload-placeholders
fixing bigs of excel with phid with nan
2022-09-08 14:27:50 +02:00
Cayo Puigdefabregas ec844a7376 fixing bigs of excel with phid with nan 2022-09-08 14:04:49 +02:00
cayop 04297d5437
Merge pull request #334 from eReuse/feature/3757-backup-dhid-phid-abstract
Feature/3757 backup dhid phid abstract
2022-09-07 18:04:35 +02:00
Cayo Puigdefabregas 5913733404 fix tests 2022-09-07 16:23:31 +02:00
Cayo Puigdefabregas c421bdad94 resolve conflict 2022-09-07 14:10:11 +02:00
Cayo Puigdefabregas e7a772dee7 drop S of SHA512SUMS in Template settings workbench 2022-09-07 14:04:54 +02:00
Cayo Puigdefabregas f19046b2ef add backups for the abstract phid and dhid 2022-09-07 14:04:09 +02:00
Nadeu 9cad30fff2
Merge pull request #333 from eReuse/update-workbench-iso
Update wb iso from 2022.5.2-beta to 2022.8.0-beta
2022-09-07 13:42:05 +02:00
Nadeu 015978b327
Update wb iso 2022 to 2022.8.0-beta 2022-09-07 13:33:43 +02:00
Cayo Puigdefabregas aee34e4989 drop / of url 2022-09-07 11:14:13 +02:00
cayop 45323cd932
Merge pull request #332 from eReuse/feature/3683-wb-page2
add external mirror for download the workbench isos
2022-09-07 10:59:29 +02:00
Cayo Puigdefabregas e598f8aabe resolve conflict 2022-09-07 10:35:50 +02:00
Cayo Puigdefabregas 04f8b630ac fix url in test_print_labels 2022-09-07 10:26:00 +02:00
Cayo Puigdefabregas 261456514d add external mirror for download the workbench isos 2022-09-07 09:45:34 +02:00
cayop ae653f0987
Merge pull request #329 from eReuse/feature/3702-update-binding
Feature/3702 update binding
2022-09-02 17:01:18 +02:00
Cayo Puigdefabregas 74c8a48d6e get erasure datas form abstract device and drop parent details 2022-09-02 16:40:35 +02:00
Cayo Puigdefabregas 74a8472aa1 fix 11 test 2022-09-02 12:42:26 +02:00
Cayo Puigdefabregas 9bde9edc63 fix test actions 2022-09-01 11:10:37 +02:00
Cayo Puigdefabregas 60f7ee8354 use dhid for get the devicehub_id of the real parth of a device 2022-08-31 17:27:17 +02:00
Cayo Puigdefabregas a222b37ecc fixing tests 2022-08-31 17:25:38 +02:00
Cayo Puigdefabregas d2975ba313 values of dimension optional in a new devices 2022-08-31 12:43:59 +02:00
Cayo Puigdefabregas eefcaeb6a0 split new device in a parth real and other abstract 2022-08-31 11:04:59 +02:00
Cayo Puigdefabregas c0653e51ce redirect public link from abstract to real device 2022-08-31 10:55:49 +02:00
Cayo Puigdefabregas 4935a1bd75 add phid in advanced search 2022-08-30 15:12:14 +02:00
Cayo Puigdefabregas 4dfbb4a0dc js unique identifiers fix 2022-08-30 13:17:58 +02:00
Cayo Puigdefabregas bdf04061dc mv unique identifiers buttons to device details 2022-08-30 13:10:35 +02:00
Cayo Puigdefabregas b5a738c44a fix test print label in test_render 2022-08-29 17:22:29 +02:00
Cayo Puigdefabregas 43f1d4e209 add template binding search 2022-08-29 16:38:07 +02:00
Cayo Puigdefabregas 30f511a03a add both device in a public page when is a twin device 2022-08-29 16:36:57 +02:00
Cayo Puigdefabregas 05d1f9698c add both device in a public page when is a twin device 2022-08-29 16:36:42 +02:00
Cayo Puigdefabregas 36dfba584d status colors and messages 2022-08-29 12:56:10 +02:00
Cayo Puigdefabregas d3f87d553b fix actions and tags colums 2022-08-29 12:55:53 +02:00
Cayo Puigdefabregas df37c46636 messages and colors in binding details 2022-08-29 12:50:01 +02:00
Cayo Puigdefabregas c8ff7a74f1 messages succesfull 2022-08-29 12:49:15 +02:00
Cayo Puigdefabregas 2f74a7526a declare real and abstract details in the head 2022-08-29 11:38:16 +02:00
Cayo Puigdefabregas 59509bf2d4 messages succesfull 2022-08-29 11:37:39 +02:00
Cayo Puigdefabregas 3900d5b878 Merge branch 'testing' into feature/3702-update-binding 2022-08-29 09:29:02 +02:00
Cayo Puigdefabregas 4564caa0ea Merge branch 'master' into testing 2022-08-29 09:28:29 +02:00
Cayo Puigdefabregas 2224fb890f fix qr link 2022-08-22 12:29:08 +02:00
Cayo Puigdefabregas d5de313384 fix binding search 2022-08-12 16:29:51 +02:00
Cayo Puigdefabregas ee754f6c64 Merge branch 'testing' into feature/3702-update-binding 2022-08-12 16:12:00 +02:00
Cayo Puigdefabregas b387572555 change USOdy by Usody in base templates 2022-08-12 16:09:47 +02:00
Cayo Puigdefabregas 7b0ceb0b5a change text help of wb settings template 2022-08-12 16:08:59 +02:00
Cayo Puigdefabregas ae4ea03b49 add new view for search phid 2022-08-12 15:59:15 +02:00
cayop d6d9fa0d3f
Merge pull request #331 from eReuse/feature/3683-wb-page
update template settings wb
2022-08-12 13:59:20 +02:00
Cayo Puigdefabregas 995baa75bb update template settings wb 2022-08-12 13:37:15 +02:00
Cayo Puigdefabregas 1e5254d7d3 buttons binding/unbinding 2022-08-12 12:28:48 +02:00
cayop eec5c7143c
Merge pull request #330 from eReuse/feature/3683-wb-page
Feature/3683 wb page
2022-08-12 10:55:30 +02:00
Cayo Puigdefabregas dcd229f12b fix not exist iso dir 2022-08-12 10:23:06 +02:00
Cayo Puigdefabregas 29d69cd285 fix tests 2022-08-12 09:58:19 +02:00
Cayo Puigdefabregas cf6965f2e6 modify template wb 2022-08-11 18:10:46 +02:00
Cayo Puigdefabregas 803c02ef35 add help to the template 2022-08-11 18:04:30 +02:00
Cayo Puigdefabregas 62b235a455 to do binding from real device 2022-08-11 17:30:00 +02:00
Cayo Puigdefabregas 138dc66b9a modify details page and binding/unbinding page 2022-08-11 14:50:47 +02:00
Cayo Puigdefabregas 57ba86eb39 add actions in placeholder model 2022-08-11 10:21:45 +02:00
Cayo Puigdefabregas 6bcaa94a3d template for erase wb 14 2022-08-11 10:01:20 +02:00
Cayo Puigdefabregas 7ed2368f02 unic template for device details 2022-08-11 09:51:17 +02:00
Cayo Puigdefabregas f55abc4a7b put the old dhid in the new placeholder device 2022-08-10 18:05:18 +02:00
Cayo Puigdefabregas f3766e49a8 drop pdbs 2022-08-10 10:49:29 +02:00
cayop 1988260c05
Merge pull request #328 from eReuse/feature/exports-placeholder
Feature/exports placeholder
2022-08-10 10:48:23 +02:00
Cayo Puigdefabregas 134a1cc313 fix csv files with placeholder datas 2022-08-10 10:23:57 +02:00
Cayo Puigdefabregas 6687898784 add placeholder datas 2022-08-09 17:52:18 +02:00
Cayo Puigdefabregas c55dbc3c8c create a Base device row 2022-08-09 17:13:29 +02:00
Cayo Puigdefabregas f63192c833 create a Base device row 2022-08-09 17:09:58 +02:00
Cayo Puigdefabregas 1098d3eb51 drop import ActionDevice 2022-08-09 13:25:42 +02:00
Cayo Puigdefabregas 43667dd9f2 fix twin 2022-08-09 13:22:56 +02:00
Cayo Puigdefabregas 5a970b0e9b fix tests binding unbinding 2022-08-09 13:19:58 +02:00
Cayo Puigdefabregas 10879e6143 fix unbinding 2022-08-09 13:19:16 +02:00
Cayo Puigdefabregas 967319f50c fix binding confirm 2022-08-09 12:17:18 +02:00
cayop 00f03cb082
Merge pull request #327 from eReuse/feature/3598-binding
Feature/3598 binding
2022-08-09 11:41:26 +02:00
Cayo Puigdefabregas 74f17def71 add components to placeholder migration 2022-08-09 11:38:30 +02:00
Cayo Puigdefabregas 8c4f7eb10e add components placeholder and simplify binding process 2022-08-09 10:49:56 +02:00
Cayo Puigdefabregas 9782ab68d6 join actions and tags 2022-08-08 18:09:25 +02:00
Cayo Puigdefabregas 9800b48aa3 show dhi of placeholder in shapshot_log list 2022-08-05 16:52:56 +02:00
Cayo Puigdefabregas 1996e8fa7a new concept of status abstract of a device 2022-08-05 16:42:07 +02:00
Cayo Puigdefabregas ded8a23075 allow edit only phid on abstrac devices 2022-08-05 16:17:19 +02:00
Cayo Puigdefabregas 5d81db5b8c fix phid form upload 2022-08-05 15:50:03 +02:00
Cayo Puigdefabregas 8c1ea5786e add v14 iso for download erease settings 2022-08-05 11:07:54 +02:00
Cayo Puigdefabregas 43da3f0a4f resolve conflict 2022-08-04 18:25:02 +02:00
Cayo Puigdefabregas 6f87005f18 Merge branch 'master' into testing 2022-08-04 15:30:25 +02:00
cayop 95c3803752
Merge pull request #326 from eReuse/feature/hello-wb-settings
new hello settings
2022-08-04 15:24:41 +02:00
Cayo Puigdefabregas 497d522ce8 new hello settings 2022-08-04 14:38:43 +02:00
Cayo Puigdefabregas a3a8f377f0 new settins page 2022-08-04 14:09:59 +02:00
cayop 5593425c60
Merge pull request #325 from eReuse/feature/3598-binding
fix migration only devices without placeholders
2022-08-03 18:42:55 +02:00
Cayo Puigdefabregas d03850b278 fix migration only devices without placeholders 2022-08-03 18:41:58 +02:00
cayop d8afbb72cc
Merge pull request #324 from eReuse/feature/3598-binding
Feature/3598 binding
2022-08-03 17:30:57 +02:00
Cayo Puigdefabregas 1b5debc77f fix battery migration 2022-08-03 17:29:13 +02:00
Cayo Puigdefabregas dcc445a42e fix battery migration 2022-08-03 17:28:59 +02:00
cayop ae847b8ee2
Merge pull request #316 from eReuse/feature/3598-binding
Feature/3598 binding
2022-08-03 16:25:00 +02:00
Cayo Puigdefabregas 08d7012bd9 CHANGELOG.md 2022-08-03 16:03:09 +02:00
Cayo Puigdefabregas beb687b967 add binding and unbinding tests 2022-08-03 16:00:25 +02:00
Cayo Puigdefabregas 23ef1e2bae fix test basic 2022-08-02 18:01:28 +02:00
Cayo Puigdefabregas 829266a808 fix excess of line 2022-08-02 17:44:36 +02:00
Cayo Puigdefabregas 83519219c7 switch order of migration 2022-08-02 16:31:27 +02:00
Cayo Puigdefabregas 080fc039ec drop cascade own 2022-08-02 13:14:02 +02:00
Cayo Puigdefabregas 72b34b3330 resolve conflict 2022-08-02 12:58:26 +02:00
Cayo Puigdefabregas 9c2d52a7f7 fix cascade delete in placeholder 2022-08-02 12:41:31 +02:00
Cayo Puigdefabregas 8728707bf7 fix csv files 2022-08-01 20:54:26 +02:00
Cayo Puigdefabregas bee420c1e7 fix tests quotes files 2022-08-01 20:40:42 +02:00
Cayo Puigdefabregas bc339a1cd9 fix test metrics 2022-08-01 20:06:47 +02:00
Cayo Puigdefabregas b75fd6873f fix render 2022-08-01 19:38:21 +02:00
Cayo Puigdefabregas e8b06d8e16 fix render 2022-08-01 19:38:09 +02:00
Cayo Puigdefabregas 5ba879d4b5 other type of quotes 2022-08-01 19:17:21 +02:00
Cayo Puigdefabregas bfc568cd2e fix test bugs 2022-08-01 17:42:28 +02:00
Cayo Puigdefabregas 2a9b6864be resolve conflict 2022-08-01 17:23:27 +02:00
Cayo Puigdefabregas c6bbaa0460 add quotation for results of csv 2022-08-01 16:13:55 +02:00
Cayo Puigdefabregas 063d20695f add quotation for results of csv 2022-07-29 18:30:58 +02:00
Cayo Puigdefabregas 7e4deea7fe add unbinding 2022-07-29 17:02:27 +02:00
Cayo Puigdefabregas c98de60680 Merge branch 'testing' into feature/3598-binding 2022-07-29 10:05:49 +02:00
cayop 0c52598820
Merge pull request #322 from eReuse/drop-imei-form
commit validation imei for mobiles
2022-07-28 18:56:56 +02:00
Cayo Puigdefabregas 637308ee8f drop required of imei and meid 2022-07-28 18:34:34 +02:00
Cayo Puigdefabregas b0beff5b1d commit validation imei for mobiles 2022-07-28 18:12:49 +02:00
Cayo Puigdefabregas 497e29a2da add manual binding 2022-07-28 17:48:14 +02:00
Cayo Puigdefabregas d008bb2921 resolve conflicts 2022-07-25 18:16:09 +02:00
Cayo Puigdefabregas d5588bc871 Merge branch 'bugfix/3666-label' into testing 2022-07-25 18:13:52 +02:00
cayop eea6d5c7e7
Merge pull request #321 from eReuse/bugfix/3666-label
Bugfix/3666 label
2022-07-25 18:06:07 +02:00
Cayo Puigdefabregas ac9708c779 fix unlink tags 2022-07-25 17:38:08 +02:00
Cayo Puigdefabregas 31bd4d775b fix fields number for print label 2022-07-25 17:37:00 +02:00
Cayo Puigdefabregas 8bec1fbd29 Merge branch 'change/3659-weekly-report' into testing 2022-07-25 16:03:08 +02:00
cayop 5d2161c5e4
Merge pull request #319 from eReuse/change/3659-weekly-report
add report command cli
2022-07-25 16:02:57 +02:00
Cayo Puigdefabregas 21f2a9c49b fix tests 2022-07-22 17:53:09 +02:00
Cayo Puigdefabregas 429c9a1b15 add command cli: get_token 2022-07-22 17:49:51 +02:00
Cayo Puigdefabregas a74e242e20 add report command cli 2022-07-22 15:23:49 +02:00
Cayo Puigdefabregas ee49b4a2dd fix test print labels 2022-07-21 16:51:02 +02:00
Cayo Puigdefabregas 21dcb6c26d Merge branch 'testing' into feature/3598-binding 2022-07-21 16:46:22 +02:00
Cayo Puigdefabregas 9f0edf5bd8 CHANGELOG.md 2022-07-21 16:46:01 +02:00
cayop 7ff9673bde
Merge pull request #318 from eReuse/bugfix/remove-tag
fix get id from js
2022-07-21 16:49:18 +02:00
Lint Action 0d2edef437 Fix code style issues with ESLint 2022-07-21 14:49:02 +00:00
Cayo Puigdefabregas a7e1daca79 fix get id from js 2022-07-21 16:30:35 +02:00
Cayo Puigdefabregas 60e46fae7b drop check in dummy 2022-07-21 14:01:20 +02:00
Cayo Puigdefabregas d0bfb9644d add phid and tags in labels 2022-07-21 13:56:09 +02:00
Cayo Puigdefabregas 71efe63ca9 fix migration 2022-07-20 17:29:29 +02:00
Cayo Puigdefabregas 5d9928bd70 fixed tests 2022-07-20 14:58:32 +02:00
Cayo Puigdefabregas 7db53a5779 fix delete device 2022-07-20 12:39:21 +02:00
Cayo Puigdefabregas 924d9941bc resolve conflict 2022-07-20 12:28:08 +02:00
cayop fa7bb86974
Merge pull request #317 from eReuse/bugfix/3613-export-placeholder
Bugfix/3613 export placeholder
2022-07-20 12:17:34 +02:00
Cayo Puigdefabregas b0dca83a3a CHANGELOG.md 2022-07-20 12:11:37 +02:00
Cayo Puigdefabregas 61db45959b CHANGELOG.md 2022-07-20 12:08:55 +02:00
Cayo Puigdefabregas c93f1360f8 fix export_devices 2022-07-20 11:52:36 +02:00
Cayo Puigdefabregas 5d573e2305 Deactivate 'Devices Lots Spreadsheet' in unassigned list 2022-07-20 11:31:54 +02:00
Cayo Puigdefabregas 02404c4277 fix export placeholders 2022-07-20 11:19:45 +02:00
Cayo Puigdefabregas 2aafe9efcc remove add tag automaticaly 2022-07-20 10:33:44 +02:00
Cayo Puigdefabregas a2b9d1c96d drop filter only by wb device 2022-07-20 10:03:46 +02:00
Cayo Puigdefabregas e2870f2b3e fix 2b90b41a556a_create_placeholders by null enviroment 2022-07-19 19:02:21 +02:00
Cayo Puigdefabregas 1167b3cb1e fix tests 2022-07-19 18:40:27 +02:00
Cayo Puigdefabregas 055abc8a42 drop scripts placeholder migrations 2022-07-19 12:42:45 +02:00
Cayo Puigdefabregas 3a3b403433 add and remove placeholders for snaposhot devices 2022-07-19 12:42:11 +02:00
Cayo Puigdefabregas aed23450df fix tests 2022-07-19 12:27:10 +02:00
Cayo Puigdefabregas d7b9d01165 fix test devices 2022-07-18 17:57:23 +02:00
Cayo Puigdefabregas 31abdf55e2 show only devices wb via api 2022-07-18 17:56:54 +02:00
Cayo Puigdefabregas a6c84ae588 fix dummy 2022-07-18 16:56:57 +02:00
Cayo Puigdefabregas e3a7684865 sync only wb devices 2022-07-18 16:56:35 +02:00
Cayo Puigdefabregas 3c1c38ca18 script downgrade placeholders 2022-07-18 15:09:11 +02:00
Cayo Puigdefabregas 376021470c allow device_details without placeholder 2022-07-18 12:56:33 +02:00
Cayo Puigdefabregas b039e491dc Merge branch 'testing' into feature/3598-binding 2022-07-18 11:54:11 +02:00
Cayo Puigdefabregas d51a3d3b56 Merge branch 'testing' of github.com:eReuse/devicehub-teal into testing 2022-07-18 11:53:18 +02:00
Cayo Puigdefabregas 5b2a4626c6 changelog 2022-07-18 11:53:07 +02:00
cayop f9fcc9697e
Merge pull request #315 from eReuse/bugfix/314-DeviceCreate
Bugfix/314 device create
2022-07-18 11:47:02 +02:00
Cayo Puigdefabregas 3a6032c17d add test for new placeholder from a lot adding from form 2022-07-18 11:28:02 +02:00
Cayo Puigdefabregas 26b322ba70 fix bug 2022-07-18 10:56:36 +02:00
Cayo Puigdefabregas 83ea86705d test for add new placeholder in a lot 2022-07-18 10:56:05 +02:00
Cayo Puigdefabregas 6a6c0e5182 show a error message creating placeholder device 2022-07-18 10:07:37 +02:00
Cayo Puigdefabregas eda61f7808 fix transfer action 2022-07-16 17:16:21 +02:00
Cayo Puigdefabregas 9e42ccafc0 change device for placeholders in lots 2022-07-15 18:07:39 +02:00
Cayo Puigdefabregas 74260c6a00 change devices of lots 2022-07-15 17:43:51 +02:00
Cayo Puigdefabregas ccc9abb835 create placeholder for the actual device 2022-07-15 16:49:04 +02:00
Cayo Puigdefabregas 2b5ff4cb2f add placeholder details in detail of device 2022-07-15 16:47:39 +02:00
Cayo Puigdefabregas 03fbfcb73b add device placeholder only in the list of devices 2022-07-15 16:47:00 +02:00
Cayo Puigdefabregas 1fa6e7512c fix tag automatic only for placeholder 2022-07-15 13:11:04 +02:00
Santiago L b915a561b8
Merge pull request #313 from eReuse/dependabot/pip/numpy-1.22.0
Bump numpy from 1.21.6 to 1.22.0 & reorder dependencies.
2022-07-15 12:17:26 +02:00
Santiago L b2f8fe3ed5 Reorder imports because sentry is an optional dep 2022-07-15 12:10:10 +02:00
Santiago L 5aa6f16ae0 Move selenium to requirements-dev.txt
and update actions to install dependencies from this file.
2022-07-15 12:03:06 +02:00
Santiago L 09412f9ee6 Move sentry & blinker to requirements-prod.txt
Use a separate file to requirements of production environment
2022-07-15 11:59:06 +02:00
Santiago L 05c6b9f47b Add comment to pandas dependencies 2022-07-15 11:58:27 +02:00
Cayo Puigdefabregas 2c6f831068 add a placeholder when arrive a snapshot 2022-07-13 11:23:18 +02:00
Cayo Puigdefabregas 98ebb0d902 Merge branch 'testing' into feature/3598-binding 2022-07-12 14:02:16 +02:00
Cayo Puigdefabregas 2d7e1fdffd fix script 2022-07-12 13:59:56 +02:00
dependabot[bot] dc083f9c16
Bump numpy from 1.21.6 to 1.22.0
Bumps [numpy](https://github.com/numpy/numpy) from 1.21.6 to 1.22.0.
- [Release notes](https://github.com/numpy/numpy/releases)
- [Changelog](https://github.com/numpy/numpy/blob/main/doc/RELEASE_WALKTHROUGH.rst)
- [Commits](https://github.com/numpy/numpy/compare/v1.21.6...v1.22.0)

---
updated-dependencies:
- dependency-name: numpy
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-12 11:49:52 +00:00
cayop 676b36811d
Merge pull request #312 from eReuse/feature/3518-define-placeholder
Feature/3518 define placeholder
2022-07-12 13:49:16 +02:00
Cayo Puigdefabregas 49ee618a6a Merge branch 'feature/3518-define-placeholder' into feature/3598-binding 2022-07-12 13:38:54 +02:00
Cayo Puigdefabregas 958a5f1815 fix unused 2022-07-12 13:31:38 +02:00
Cayo Puigdefabregas fb31ce69bc fix models 2022-07-12 13:23:24 +02:00
Cayo Puigdefabregas 0253eda736 fix test 2022-07-12 13:17:13 +02:00
Cayo Puigdefabregas 963f42b248 change debug in app 2022-07-12 11:39:27 +02:00
Cayo Puigdefabregas 9936a89171 Merge branch 'feature/3518-define-placeholder' of github.com:eReuse/devicehub-teal into feature/3518-define-placeholder 2022-07-12 11:25:58 +02:00
Cayo Puigdefabregas e3ca632177 add components as placeholder 2022-07-12 11:23:55 +02:00
Santiago L 6350bcd6a4 Merge branch 'testing' 2022-07-12 10:15:50 +02:00
Santiago L e6accae694 Release version 2.3.0 2022-07-12 10:11:30 +02:00
Santiago L 2491ab9137 Cosmetics and fix typos 2022-07-12 10:11:30 +02:00
Cayo Puigdefabregas 8f4d3e7063 modify changelog 2022-07-12 10:11:30 +02:00
Cayo Puigdefabregas 15a56a59ee fix flak8 2022-07-12 10:11:30 +02:00
Cayo Puigdefabregas a303b935a8 move extract_uuid to script folder 2022-07-12 10:11:30 +02:00
Cayo Puigdefabregas a21018a2d2 add binding relation 2022-07-11 15:36:45 +02:00
Santiago L 785833c1b7
Merge pull request #310 from eReuse/ci/house-keeping
Run Selenium as an independent workflow
2022-07-11 13:57:33 +02:00
Santiago L 214fbb6e37 Bump to Python 3.9 on actions
It's the version used on testing & production servers
2022-07-11 13:53:27 +02:00
Santiago L d6a2dc0a14 Bump actions versions 2022-07-11 13:46:52 +02:00
Santiago L f359aa6cfa Run Selenium as an independent workflow 2022-07-11 13:42:25 +02:00
Cayo Puigdefabregas 99238d69d8 resolve conflict 2022-07-11 09:35:03 +02:00
Cayo Puigdefabregas f60fdfe7a1 add selenium test 2022-07-10 07:21:11 +02:00
cayop 41d0b56369
Merge pull request #281 from eReuse/feature/3096-testing_selenium
Feature/3096 testing selenium
2022-07-10 07:18:49 +02:00
Cayo Puigdefabregas d028cd3c79 fix test selenium 2022-07-08 18:55:50 +02:00
Cayo Puigdefabregas cfb8706598 fix test selenium 2022-07-08 18:55:32 +02:00
Cayo Puigdefabregas b7aaa20879 resolve conclict 2022-07-08 17:33:58 +02:00
Cayo Puigdefabregas acc8015b92 changelog 2022-07-08 12:46:46 +02:00
cayop 02de86bd55
Merge pull request #309 from eReuse/bugfix/3553-export
fixed
2022-07-08 12:46:28 +02:00
Cayo Puigdefabregas fa45080a44 fixed 2022-07-08 12:21:07 +02:00
Cayo Puigdefabregas da56126653 fixing schema 2022-07-07 17:43:46 +02:00
Cayo Puigdefabregas c9cd68b817 resolve conflict 2022-07-07 16:33:43 +02:00
Cayo Puigdefabregas 1eed2f5773 remove schema of placeholder 2022-07-07 16:32:00 +02:00
Cayo Puigdefabregas 4507a3206c add secuence and remove schema for placeholder_log 2022-07-07 16:18:51 +02:00
Cayo Puigdefabregas 2e3bc8137f add tests placeholder logs 2022-07-07 15:49:21 +02:00
Cayo Puigdefabregas c914705e29 add test files 2022-07-07 13:10:37 +02:00
Cayo Puigdefabregas d4824a4333 add placeholder log in form 2022-07-07 13:10:05 +02:00
Cayo Puigdefabregas d93f040453 add placeholder log models 2022-07-06 18:37:27 +02:00
Cayo Puigdefabregas 3af2645706 fix format of file 2022-07-05 18:36:27 +02:00
Cayo Puigdefabregas e8b957c697 call one time all lots reset 2022-07-05 18:18:29 +02:00
Cayo Puigdefabregas 3a06ade79f call one time all lots 2022-07-05 18:10:17 +02:00
Cayo Puigdefabregas bc8944a498 add manual edit placeholder 2022-07-05 18:09:47 +02:00
Cayo Puigdefabregas 71518ca2a5 add upload form placeholder 2022-07-04 11:26:24 +02:00
Cayo Puigdefabregas b22ea880dd fix add amount placeholder 2022-06-29 18:07:57 +02:00
Cayo Puigdefabregas 3dae7e3a58 ux menu 2022-06-29 17:31:54 +02:00
Cayo Puigdefabregas a4aced0238 add test crerate with amount laptops 2022-06-29 13:46:19 +02:00
Cayo Puigdefabregas 3e2ed58b07 add number of devices to be created 2022-06-29 13:40:00 +02:00
Cayo Puigdefabregas ce2694f229 add test over placeholders 2022-06-29 11:51:39 +02:00
Cayo Puigdefabregas 01e1d6e0b7 add computers as placeholders 2022-06-29 11:51:03 +02:00
Cayo Puigdefabregas 16daba1fa5 add placeholder in sync function 2022-06-28 17:40:00 +02:00
Cayo Puigdefabregas c6e5d71e15 add placeholder in form 2022-06-28 17:39:08 +02:00
Cayo Puigdefabregas d2924dfafe add fields in template 2022-06-28 17:38:31 +02:00
Cayo Puigdefabregas 12d55c2d24 add models 2022-06-28 17:38:05 +02:00
Cayo Puigdefabregas 4f6663dc12 add sentry 2022-06-27 17:12:04 +02:00
Cayo Puigdefabregas 5c5d1c1a64 change changelog 2022-06-27 12:35:52 +02:00
cayop 9e7e10208b
Merge pull request #308 from eReuse/feature/3535-sentry
add sentry to app
2022-06-27 12:26:08 +02:00
Cayo Puigdefabregas c3ee749fe4 add sentry to app 2022-06-27 11:42:16 +02:00
Cayo Puigdefabregas 35ccb33f34 Merge branch 'testing' into feature/3518-define-placeholder 2022-06-27 09:46:32 +02:00
cayop 97d0dd1411
Merge pull request #307 from eReuse/feature/3530-download-snapshots
Feature/3530 download snapshots
2022-06-24 15:50:27 +02:00
Cayo Puigdefabregas 5435d21828 add test for download snapshot 2022-06-24 15:23:24 +02:00
Cayo Puigdefabregas 9829ebe7c7 add download snapshots 2022-06-24 15:05:38 +02:00
cayop 746df7e528
Merge pull request #306 from eReuse/feature/3439-wb-iso
fixing path
2022-06-24 12:43:36 +02:00
Cayo Puigdefabregas 72c19501fa fixing path 2022-06-24 12:39:46 +02:00
Cayo Puigdefabregas 6594cebaf6 changelog 2022-06-24 12:05:12 +02:00
cayop 035ccc7315
Merge pull request #305 from eReuse/feature/3439-wb-iso
Feature/3439 wb iso
2022-06-24 12:03:49 +02:00
cayop ac883d514c
Merge pull request #302 from eReuse/changes/hdi
Changes/hid
2022-06-24 12:03:01 +02:00
Cayo Puigdefabregas 2760348cc0 add iso dir 2022-06-24 11:45:26 +02:00
Cayo Puigdefabregas 1f85abc1e2 resolve conflicts 2022-06-24 11:32:14 +02:00
Cayo Puigdefabregas 18e051596c fixing system uuid as non physical property 2022-06-24 11:27:42 +02:00
Cayo Puigdefabregas 93545ad01b fix test_physical_properties 2022-06-24 09:59:24 +02:00
Santiago L cd3439b3ac Release version 2.2.0 2022-06-24 07:22:01 +02:00
Cayo Puigdefabregas 7cb5c76562 add download iso 2022-06-23 18:08:56 +02:00
Cayo Puigdefabregas 6e3c032d97 3500 change name of anchor 2022-06-23 18:08:16 +02:00
Cayo Puigdefabregas 8bcbf21abe resolve conflicts 2022-06-23 17:08:07 +02:00
Cayo Puigdefabregas be7cbf02c0 remove system uuid of public page 2022-06-23 17:06:40 +02:00
cayop bd9d659c39
Merge pull request #304 from eReuse/bugfix/3523
change link of export devices lots
2022-06-23 16:28:38 +02:00
Cayo Puigdefabregas 7ca91cbb35 changelog 2022-06-23 16:09:58 +02:00
Cayo Puigdefabregas e55c1d4cab change link of export devices lots 2022-06-23 15:52:23 +02:00
Cayo Puigdefabregas 2605d938e5 add placeholder model 2022-06-23 15:51:01 +02:00
Cayo Puigdefabregas eb8dec5173 changelog 2022-06-22 14:57:57 +02:00
Cayo Puigdefabregas 436e796234 changelog 2022-06-22 09:45:02 +02:00
cayop 97653058c6
Merge pull request #303 from eReuse/features/transfer-3493-3492-3510
Features/transfer 3493 3492 3510
2022-06-22 09:40:56 +02:00
Cayo Puigdefabregas 02ab084dc1 changelog 2022-06-22 09:13:53 +02:00
Cayo Puigdefabregas bc446e7dbf run babel 2022-06-22 09:03:12 +02:00
Cayo Puigdefabregas b47cc84859 run babel 2022-06-21 18:27:55 +02:00
Cayo Puigdefabregas 1168842cea Merge branch 'features/transfer-3493-3492-3510' of github.com:eReuse/devicehub-teal into features/transfer-3493-3492-3510 2022-06-21 18:16:10 +02:00
Cayo Puigdefabregas b00e602150 add files for test 2022-06-21 18:15:44 +02:00
Lint Action db53905cf1 Fix code style issues with ESLint 2022-06-21 15:53:23 +00:00
Cayo Puigdefabregas fc50604011 add sections in menu of lots 2022-06-21 17:51:33 +02:00
Cayo Puigdefabregas cf4e1df527 add field type of transfer instead of change the name 2022-06-21 17:50:27 +02:00
Cayo Puigdefabregas 7d40f5b537 add transfer in name of lot 2022-06-21 16:40:21 +02:00
Cayo Puigdefabregas 97edb260b7 drop pdbs 2022-06-21 08:12:08 +02:00
Cayo Puigdefabregas 2a3b7a0900 add Transfers to lot dropdown 2022-06-21 08:11:42 +02:00
Cayo Puigdefabregas 985039adcd add export lots tests 2022-06-20 14:37:26 +02:00
Cayo Puigdefabregas 3ecf4c4a89 add dropdown menu in reports lots 2022-06-20 14:36:34 +02:00
Cayo Puigdefabregas c6c443899a add temporary lots too in reports 2022-06-20 14:35:57 +02:00
Cayo Puigdefabregas 8e11aff88b add export devices lots 2022-06-20 10:51:32 +02:00
Cayo Puigdefabregas 49062d9944 add export devices lots 2022-06-20 10:40:00 +02:00
Cayo Puigdefabregas e332cd2d43 add link to devices lot export 2022-06-20 10:36:24 +02:00
Cayo Puigdefabregas 740178f57b add link for report lots 2022-06-20 09:24:48 +02:00
Cayo Puigdefabregas ec47bfaec6 export lots 2022-06-17 14:14:32 +02:00
Cayo Puigdefabregas cdf180cf38 drop metrics of devices list 2022-06-17 12:16:01 +02:00
Cayo Puigdefabregas 6bb5e8e6d6 fix test physical_properties 2022-06-17 11:35:40 +02:00
Cayo Puigdefabregas 3afdf3ea0b return to the original state of dummy 2022-06-17 11:25:24 +02:00
Cayo Puigdefabregas 559e926626 fix commit in db 2022-06-17 11:24:52 +02:00
Cayo Puigdefabregas 5262d407b8 modify changelog 2022-06-17 09:53:16 +02:00
Cayo Puigdefabregas f4987b7cd6 add system_uuid4.json 2022-06-17 09:41:59 +02:00
Cayo Puigdefabregas e4919c78b1 add test for check smbios 2.5 version 2022-06-17 09:34:03 +02:00
Cayo Puigdefabregas 5c2c4653a1 extract system uuid of old snapshots 2022-06-16 17:59:53 +02:00
Cayo Puigdefabregas 88a164a9ee save system uuid only for smbios >= 2.6 2022-06-16 17:58:32 +02:00
Cayo Puigdefabregas c43e7fb578 fix splits texts 2022-06-16 11:47:36 +02:00
Cayo Puigdefabregas 08300ef612 add system_uuid in old devices 2022-06-16 10:38:57 +02:00
Cayo Puigdefabregas 41196ae445 add system uuid to snapshots list 2022-06-15 13:39:06 +02:00
Cayo Puigdefabregas 77c01ae80a migration change uuid for system_uuid 2022-06-15 12:52:46 +02:00
Cayo Puigdefabregas a566772c42 add files for tests system uuid 2022-06-15 12:23:27 +02:00
Cayo Puigdefabregas 95cf33fd3c fix tests system uuid 2022-06-15 12:19:15 +02:00
Cayo Puigdefabregas 34def901cb change uuid in views and forms for system_uuid 2022-06-15 12:18:44 +02:00
Cayo Puigdefabregas 0f916e5964 change uuid for system_uuid 2022-06-15 12:17:16 +02:00
Cayo Puigdefabregas a19126887a add tests for system uuid 2022-06-15 12:02:09 +02:00
Cayo Puigdefabregas dd3ff2fc5a fix weird 2022-06-14 10:49:00 +02:00
Cayo Puigdefabregas c0081e32b1 fix uuid in device not computer 2022-06-14 10:48:01 +02:00
Cayo Puigdefabregas 86446a268c fix uuid in device not computer 2022-06-14 10:46:21 +02:00
Cayo Puigdefabregas 309b0f9354 fix tests 2022-06-14 10:45:17 +02:00
Cayo Puigdefabregas 660e238468 fix order of vars declared 2022-06-13 17:59:54 +02:00
Cayo Puigdefabregas 3e3a2fbd34 add uuid for old versions from form upload 2022-06-13 17:36:03 +02:00
Cayo Puigdefabregas e1cdd56fa0 add uuid for old register api 2022-06-13 17:35:01 +02:00
Cayo Puigdefabregas 686d0a9307 add system_uuid to sync run function 2022-06-13 17:33:22 +02:00
cayop f86df91862
Merge pull request #301 from eReuse/feature/2972-add-logo-to-label
Feature/2972 add logo to label
2022-06-09 17:14:13 +02:00
Cayo Puigdefabregas dadfbdd605 add logo in printing pdf label 2022-06-09 16:57:15 +02:00
Cayo Puigdefabregas 3431bed49e managment save and load logo in template 2022-06-08 15:37:49 +02:00
Cayo Puigdefabregas c3fbc8a0c0 Merge branch 'testing' into feature/2972-add-logo-to-label 2022-06-08 12:27:06 +02:00
Cayo Puigdefabregas 328d417741 add upload logo in template 2022-06-08 12:26:47 +02:00
cayop cfe7639734
Merge pull request #300 from eReuse/change/2973-sid-in-label
Change/2973 sid in label
2022-06-08 12:18:42 +02:00
Cayo Puigdefabregas a65e93b470 add sid in template 2022-06-08 11:59:47 +02:00
Cayo Puigdefabregas dd68c5c410 fix dev.sid 2022-06-08 11:59:22 +02:00
cayop 00a2f47189
Merge pull request #299 from eReuse/feature/3426-shift-select
select with shift
2022-06-08 10:57:00 +02:00
Lint Action 8dbb4e6e9b Fix code style issues with ESLint 2022-06-08 08:56:46 +00:00
Cayo Puigdefabregas 2eab043f3c fix var 2022-06-08 10:55:52 +02:00
Cayo Puigdefabregas a1450f9810 fix var 2022-06-08 10:53:40 +02:00
Cayo Puigdefabregas 3997235e09 fix var 2022-06-08 10:52:52 +02:00
Santiago L 9516a666e5 Add issue and pull request template 2022-06-08 10:46:31 +02:00
Lint Action 42df98f7a2 Fix code style issues with ESLint 2022-06-08 08:17:46 +00:00
Cayo Puigdefabregas 070771c077 select with shift chromium 2022-06-08 10:16:15 +02:00
Cayo Puigdefabregas 5932213764 save sid in html label 2022-06-08 09:26:09 +02:00
cayop 92fafa2358
Merge pull request #298 from eReuse/bugfix/issues-297
Bugfix/issues 297
2022-06-07 15:43:04 +02:00
Cayo Puigdefabregas 99d0a61e87 return jwt.encode to snapshot code 2022-06-07 15:24:45 +02:00
Cayo Puigdefabregas eb66baf842 fix snapshot_uuid == None 2022-06-07 15:12:13 +02:00
Cayo Puigdefabregas 74f9b88ece preload SnapshotsLog in dummy 2022-06-07 15:06:18 +02:00
Cayo Puigdefabregas 7a0e21d682 dialects.postgresql.ENUM instead of sa.Enum 2022-06-07 15:05:39 +02:00
Santiago L 498ce6763d Release version 2.2.0rc1 2022-06-07 11:22:40 +02:00
Santiago L c84c63d05c
Merge pull request #296 from eReuse/changes/changelog
change order of changelog
2022-06-07 11:16:37 +02:00
Santiago L 523c832e10 Fix typo. 2022-06-07 11:16:20 +02:00
Cayo Puigdefabregas fa72c3aa13 change order of changelog 2022-06-07 11:03:12 +02:00
Santiago L 083e763b25
Merge pull request #212 from eReuse/feature/server-side-render-parser-3021
Feature/server side render parser 3021
2022-06-07 11:00:27 +02:00
cayop 39ac37fa5e
Merge pull request #294 from eReuse/changes/changelog
update README and CHANGELOG
2022-06-07 10:11:35 +02:00
Cayo Puigdefabregas e30c7d0533 update README and CHANGELOG 2022-06-07 10:09:47 +02:00
cayop 65d500c87d
Merge pull request #293 from eReuse/feature/3428-Increase-items-selected
increase 50 and 100 items per page
2022-06-07 09:35:30 +02:00
Cayo Puigdefabregas c615980535 increase 50 and 100 items per page 2022-06-06 18:25:56 +02:00
Santiago L 772d527ba6
Merge pull request #277 from RubenPX/add-developement-stuff-js
Add developement build & precomit build (javascript)
2022-06-06 16:45:10 +02:00
cayop 1297766577
Merge pull request #292 from eReuse/feature/3416-transaction-notes
Feature/3416 transaction notes
2022-06-06 13:57:35 +02:00
Cayo Puigdefabregas 03a18df080 add tests for notes 2022-06-06 13:38:22 +02:00
Cayo Puigdefabregas 83bdf79514 add render views for delivery and receiver notes 2022-06-06 13:37:58 +02:00
Cayo Puigdefabregas e635abdbbc views of delivery note and receiver note 2022-06-03 20:01:13 +02:00
Cayo Puigdefabregas 2b8e7232c3 add transfer note models 2022-06-03 13:13:50 +02:00
Cayo Puigdefabregas 88a0bdd44d resolv conflicts 2022-06-03 11:34:49 +02:00
Cayo Puigdefabregas 26f27127b8 fixed test errors 2022-06-03 11:18:07 +02:00
cayop d7023a9496
Merge pull request #291 from eReuse/feature/3462-snapshotlog-old-api
add snapshotLog in old api
2022-06-03 11:09:09 +02:00
Cayo Puigdefabregas ad7848edc6 add snapshotLog in old api 2022-06-03 11:06:49 +02:00
cayop 9eb02e82a3
Merge pull request #290 from eReuse/feature/3436-search-bulk-dhid
add view for advanced search
2022-06-02 14:59:56 +02:00
Cayo Puigdefabregas 7ea93b58f6 fix basic test 2022-06-02 14:09:21 +02:00
Cayo Puigdefabregas cce7dbfdf1 add view for advanced search 2022-06-02 13:46:10 +02:00
Santiago L 6745dbbf7c
Merge pull request #282 from eReuse/dependabot/pip/pyjwt-2.4.0
Bump pyjwt from 2.0.0a1 to 2.4.0
2022-06-02 13:30:45 +02:00
Santiago L 560920c85a
Merge pull request #287 from RubenPX/fix/lots-button-out-of-card
fix apply button out of card
2022-06-02 13:26:05 +02:00
Santiago L 78f9c269a8
Merge pull request #285 from RubenPX/fix/lots-search
hotfix lots search not working
2022-06-02 13:25:34 +02:00
Cayo Puigdefabregas 5fc3056907 fix version transfer migration 2022-06-01 16:47:40 +02:00
Cayo Puigdefabregas 29ef48c5b2 fixing actions in tests 2022-06-01 15:54:09 +02:00
Cayo Puigdefabregas 8ea0f028d6 fix test 2022-06-01 15:04:04 +02:00
Cayo Puigdefabregas f58993c9d1 resolve conflicts 2022-06-01 15:01:02 +02:00
cayop e43e47c4f5
Merge pull request #289 from eReuse/feature/3415-transfer
Feature/3415 transfer
2022-06-01 14:46:41 +02:00
Cayo Puigdefabregas ea5867e32a fixed tests 2022-06-01 14:00:16 +02:00
Cayo Puigdefabregas 29313e3470 add colors to open and closed 2022-06-01 13:26:17 +02:00
Cayo Puigdefabregas 1e50db9194 fix render lot 2022-06-01 13:15:04 +02:00
Cayo Puigdefabregas b7eb438767 fix migration datas 2022-06-01 13:14:45 +02:00
Cayo Puigdefabregas 96680937e9 add arrow right 2022-06-01 13:14:27 +02:00
Cayo Puigdefabregas e1e38015ee fix 2022-06-01 12:34:48 +02:00
Cayo Puigdefabregas ef36c11f6b change names of vars 2022-06-01 11:54:02 +02:00
Cayo Puigdefabregas f8f1276313 add description in transfer 2022-06-01 11:09:28 +02:00
Cayo Puigdefabregas 7e4bdfdc69 create transfer in angular version for code trades 2022-06-01 10:29:55 +02:00
Cayo Puigdefabregas 2dd3b7c276 upgrade the datas in the migration 2022-05-31 18:33:41 +02:00
Cayo Puigdefabregas dbd5645c94 show transfers if there are transfer 2022-05-31 16:28:38 +02:00
Cayo Puigdefabregas 01f2996c48 fixed query lots 2022-05-31 15:14:56 +02:00
RubenPX 54295556f1 fix style 2022-05-31 11:25:32 +02:00
Cayo Puigdefabregas c36bf77ab7 render test edit transfer 2022-05-31 10:22:21 +02:00
Cayo Puigdefabregas f6d4c48487 drop pdbs 2022-05-31 10:22:01 +02:00
RubenPX 5b164221ae hotfix lots search not working 2022-05-30 19:28:16 +02:00
Cayo Puigdefabregas 7cd59b4598 add test render transfers 2022-05-30 17:36:03 +02:00
Cayo Puigdefabregas a1728810d1 fixed bugs 2022-05-30 17:35:27 +02:00
Cayo Puigdefabregas b0c58595c1 add EditTransfer 2022-05-30 16:33:01 +02:00
Cayo Puigdefabregas 9ca5ce48d1 add edit transfer 2022-05-30 16:32:25 +02:00
Cayo Puigdefabregas 0f563d58d8 fix closed 2022-05-30 16:32:02 +02:00
Cayo Puigdefabregas b8819b7a4a change is_temporary, is_outgoing, is_incoming 2022-05-27 16:48:40 +02:00
Cayo Puigdefabregas b2e11527cb fix model transfer 2022-05-27 16:32:54 +02:00
Cayo Puigdefabregas a8368e92b8 add html and form for transfers 2022-05-27 16:32:22 +02:00
Cayo Puigdefabregas 0998adc956 add model transfer 2022-05-27 11:30:48 +02:00
cayop 776c27a082
Merge pull request #284 from eReuse/bugfix/3385-bug-date-allocate
fixed bugs of allocate
2022-05-26 18:11:37 +02:00
Cayo Puigdefabregas d3e7c49a86 fixed bugs of allocate 2022-05-26 17:55:52 +02:00
cayop cbba8c7908
Merge pull request #283 from eReuse/feature/3431-add-date-of-Registered
modify updated and add registered
2022-05-25 17:55:57 +02:00
Cayo Puigdefabregas ebe800158a modify updated and add registered 2022-05-25 17:37:24 +02:00
Cayo Puigdefabregas 83067fd2bb modify updated and add registered 2022-05-25 17:33:54 +02:00
Cayo Puigdefabregas 5f025ff869 fix env vars 2022-05-25 09:56:47 +02:00
dependabot[bot] e6e57e6608
Bump pyjwt from 2.0.0a1 to 2.4.0
Bumps [pyjwt](https://github.com/jpadilla/pyjwt) from 2.0.0a1 to 2.4.0.
- [Release notes](https://github.com/jpadilla/pyjwt/releases)
- [Changelog](https://github.com/jpadilla/pyjwt/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/jpadilla/pyjwt/compare/2.0.0a1...2.4.0)

---
updated-dependencies:
- dependency-name: pyjwt
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-25 05:05:46 +00:00
Cayo Puigdefabregas ef570232e7 fix env vars 2022-05-24 17:20:17 +02:00
Cayo Puigdefabregas a5d3976274 fix env vars 2022-05-24 17:16:50 +02:00
Cayo Puigdefabregas ab20cdd1d0 fix env vars 2022-05-24 17:12:53 +02:00
Cayo Puigdefabregas 0530fef414 fix env vars 2022-05-24 17:03:41 +02:00
Cayo Puigdefabregas a6b3e725be fix pip 2022-05-24 17:02:33 +02:00
Cayo Puigdefabregas 7299ce15cf fix pip 2022-05-24 16:57:42 +02:00
Cayo Puigdefabregas f6e115909f Merge branch 'testing' into feature/3096-testing_selenium 2022-05-24 16:53:12 +02:00
Cayo Puigdefabregas 7ce18e1482 add new process for check 2022-05-24 16:52:19 +02:00
Cayo Puigdefabregas af470c0ecd add selenium test 2022-05-24 16:41:23 +02:00
Santiago L 1bd0d6cc30
Merge pull request #280 from eReuse/bugfix/279-alembic
fix enums in migration process
2022-05-24 14:11:02 +02:00
Santiago L c2bff5dd92 Fix #279. Update existing enum 2022-05-24 14:08:23 +02:00
Santiago L e081310069 Apply pre-commit hook 2022-05-24 14:06:56 +02:00
Santiago L 7d7507c1d9
Merge pull request #273 from RubenPX/feature/lots-search
Feature: lots-search US 3334
2022-05-23 13:39:42 +02:00
Santiago L 20440a55ca Update CHANGELOG.md 2022-05-23 13:39:12 +02:00
Cayo Puigdefabregas 20b09f7b39 add selenium un requirements 2022-05-23 13:03:00 +02:00
Cayo Puigdefabregas 66b0da5fc1 add 2 new basic tests 2022-05-23 09:34:04 +02:00
cayop 7ac6d9989a
Merge pull request #225 from eReuse/feature/list-snapshots-view-#3113
Feature/list snapshots view #3113
2022-05-23 09:27:59 +02:00
Lint Action 14500ec4a2 Fix code style issues with ESLint 2022-05-22 17:01:11 +00:00
RubenPX 4164deae2e fix: only allow search when lots list is loaded 2022-05-22 19:00:26 +02:00
RubenPX 97ff171fa0 Change EOL `CRLF` to `LF` 2022-05-22 18:21:59 +02:00
RubenPX c13bc0f7ce fix dropdown not works when try to search DOM element 2022-05-22 18:20:04 +02:00
RubenPX c0a7415f33
Update ereuse_devicehub/templates/inventory/device_list.html
Co-authored-by: Santiago L <santiago@ribaguifi.com>
2022-05-21 10:58:40 +02:00
Cayo Puigdefabregas 59379b41a5 fix tests 2022-05-20 18:32:07 +02:00
Cayo Puigdefabregas d63a256da5 fix version in text 2022-05-20 18:31:47 +02:00
Cayo Puigdefabregas 3f2d3df817 fix list for query 2022-05-20 18:31:21 +02:00
Cayo Puigdefabregas a486486995 fix circular imports 2022-05-20 18:30:43 +02:00
Cayo Puigdefabregas 1a8dc80067 fix the info result 2022-05-20 13:52:32 +02:00
Cayo Puigdefabregas 9590cff193 bugfix parse errors messages 2022-05-20 13:44:11 +02:00
Cayo Puigdefabregas 6bf419f59a try to fix bug 2022-05-20 11:45:53 +02:00
Cayo Puigdefabregas bf455c40c9 try to fix bug 2022-05-20 11:42:39 +02:00
Cayo Puigdefabregas 6ecbd4e09d add details of one entry snapshot log 2022-05-19 18:16:47 +02:00
Cayo Puigdefabregas 744b14f286 join all snapshots logs in one for every uuid 2022-05-19 13:48:52 +02:00
Cayo Puigdefabregas cea143dcbe fix lot render 2022-05-19 10:58:07 +02:00
Cayo Puigdefabregas a919c0ee26 force query 2022-05-19 09:47:31 +02:00
Cayo Puigdefabregas 0bc75ec547 add get_status 2022-05-18 18:26:01 +02:00
Cayo Puigdefabregas f2a7a15851 drop pdbs 2022-05-18 18:25:21 +02:00
Cayo Puigdefabregas 04969ad939 clean template 2022-05-18 18:02:38 +02:00
Cayo Puigdefabregas b8c97780be add snapshotslog Ok result 2022-05-18 18:02:08 +02:00
Cayo Puigdefabregas 3d73e1a368 fix version in snaposhotslog 2022-05-18 18:00:54 +02:00
Cayo Puigdefabregas 1698f35e3d fix model 2022-05-18 17:59:05 +02:00
Cayo Puigdefabregas 112e6bd01a save ok in log 2022-05-18 12:47:23 +02:00
Cayo Puigdefabregas c0abfd6f0b change version 2022-05-18 12:46:57 +02:00
Cayo Puigdefabregas 3670fe0ff1 fixing migrations 2022-05-18 12:46:34 +02:00
RubenPX 79ce3dfc59 Load dev build on device_list 2022-05-18 11:16:22 +02:00
RubenPX e6399e9729 pre commit build js babel 2022-05-18 11:15:41 +02:00
Cayo Puigdefabregas a7ceab2cde change SnapshotErrors for SnapshotsLog 2022-05-18 11:03:58 +02:00
Cayo Puigdefabregas d9e94e66d3 change views 2022-05-18 11:01:58 +02:00
Cayo Puigdefabregas 99309162e3 change templates 2022-05-18 11:01:23 +02:00
Cayo Puigdefabregas e96c2c122d add snapshots_log instead of snapshot_errors 2022-05-18 11:00:04 +02:00
Cayo Puigdefabregas bf547b6f80 Merge branch 'feature/server-side-render-parser-3021' into feature/list-snapshots-view-#3113 2022-05-17 09:23:31 +02:00
Cayo Puigdefabregas db5bbeb796 resolv conflicts with csv files 2022-05-16 19:17:11 +02:00
Cayo Puigdefabregas 0206f831b2 fix GenericMixin in woekbench view 2022-05-16 18:38:36 +02:00
Cayo Puigdefabregas edeae562d6 resolve conflict 2022-05-16 18:33:34 +02:00
Cayo Puigdefabregas 68fc1cb2bb resolv conflicts 2022-05-16 18:23:03 +02:00
Cayo Puigdefabregas 960c971197 Change workbench_lite for schema_workbench 2022-05-16 17:57:09 +02:00
Cayo Puigdefabregas b309cc4410 change Mixin clases 2022-05-16 17:52:31 +02:00
cayop 8794223385
Merge pull request #276 from eReuse/bugfix/#3360-computermonitor-instead-monitor
computer monitor instead of monitor
2022-05-16 12:59:41 +02:00
Cayo Puigdefabregas d935c987b3 comiter monitor instead of monitor 2022-05-16 12:40:14 +02:00
Cayo Puigdefabregas 727c06c3de add public link to device list 2022-05-16 11:54:02 +02:00
cayop 9fdeef08ca
Merge pull request #275 from eReuse/change/#3370-Remove-components-in-filter
remove all components in the filter of the inventory
2022-05-16 11:31:11 +02:00
Cayo Puigdefabregas 3bd2dd79b1 remove all components in the filter of the inventory 2022-05-16 11:01:52 +02:00
cayop ac0d6c7a22
Merge pull request #274 from eReuse/feature/#3396-add-columns-status
Feature/#3396 add columns status
2022-05-16 10:50:48 +02:00
Cayo Puigdefabregas 0b78178ff4 fixed device public page 2022-05-16 10:29:07 +02:00
cayop 282b9490fb
Merge pull request #265 from eReuse/feature/#3100-wb-settings
Feature/#3100 wb settings
2022-05-16 10:18:45 +02:00
Cayo Puigdefabregas c1665ef4af Merge branch 'testing' into feature/#3396-add-columns-status 2022-05-16 10:16:23 +02:00
Cayo Puigdefabregas f7b6bdccb6 fix test_export_extended 2022-05-16 10:15:46 +02:00
Cayo Puigdefabregas ae221dadd1 fixed tests 2022-05-16 09:53:22 +02:00
RubenPX b329474a10 remove code dependecy 2022-05-13 21:54:03 +02:00
RubenPX ec0d9860f7 change map to forEach 2022-05-13 21:33:25 +02:00
RubenPX 6fef4616e5 eslint avoid class limit 2022-05-13 21:29:29 +02:00
RubenPX a10fb5a212 add Search functionality 2022-05-13 21:29:15 +02:00
RubenPX adde4f88e4 add lots search interface 2022-05-13 21:27:50 +02:00
Cayo Puigdefabregas dd081532ba #3402 change public page of device 2022-05-13 17:17:57 +02:00
Cayo Puigdefabregas 11913d68c3 fix state instead of states 2022-05-13 17:16:08 +02:00
Cayo Puigdefabregas 1dcebc0112 #3401 change the values of the status in the page of device details 2022-05-13 13:11:00 +02:00
Cayo Puigdefabregas d8c9bcbcf7 #3400 change the names of the status for the correct names 2022-05-13 13:06:04 +02:00
Cayo Puigdefabregas df44849ad3 add allocate status in devices export 2022-05-13 12:51:31 +02:00
Cayo Puigdefabregas 1b5f6412f0 #3397 add columns of status in the devices list 2022-05-13 12:17:14 +02:00
Santiago L af833a673a
Merge pull request #272 from RubenPX/Show-device-labels
Show lots on deviceList
2022-05-13 10:41:55 +02:00
Santiago L 56ccb7591a Cosmetics: display lots inline & use ligh bg
Lower visual weight because it's secundary information
2022-05-13 10:39:37 +02:00
Santiago L 300edac5a8 Dropped .badge-pill use the .rounded-pill utility instead.
Breaking change on Boostrap 5
https://getbootstrap.com/docs/5.0/migration/#badges
2022-05-13 10:35:11 +02:00
Santiago L a444579c05
Merge pull request #271 from eReuse/feature/all-device-list
Feature: 3196 all device list
2022-05-13 10:26:49 +02:00
Santiago L d54f2166dc Keep unassigned as default option on device list
Unassigned devices are the ones that require user attention and
also all devices view will generate larger responses and more
server load.
2022-05-13 10:22:32 +02:00
RubenPX c7e0501828 add soft init to reassign events 2022-05-12 18:58:06 +02:00
RubenPX 6a408a08c7 set const table to var
This allow modify variable
2022-05-12 18:44:26 +02:00
RubenPX cea1c2b717 full table replacament 2022-05-12 18:44:02 +02:00
Cayo Puigdefabregas 3c02a5480f fixed test render wbsettings 2022-05-12 17:42:26 +02:00
cayop 5026768eb5
Merge pull request #269 from eReuse/bugfix/allocate-bugs
Bugfix/allocate bugs
2022-05-12 17:38:37 +02:00
Cayo Puigdefabregas 3a2e0bd61a fixing bugs 2022-05-12 17:25:02 +02:00
Cayo Puigdefabregas 763d2d1361 minimalistic settings 2022-05-12 17:19:22 +02:00
Santiago L 4406c78aed Merge branch 'testing' into feature/all-device-list 2022-05-12 14:49:22 +02:00
Santiago L 8f3bdb71fe Add "All devices" item to sidebar menu 2022-05-12 14:44:02 +02:00
Santiago L 290c260511 Update breadcrum: All devices VS Unassigned 2022-05-12 14:43:41 +02:00
Santiago L 9e779d279c Allow retrieving all devices of a user 2022-05-12 14:42:55 +02:00
Santiago L 4ffbeec29d Refactor form initialization 2022-05-12 14:23:01 +02:00
Santiago L 3e33b7d63b Refactor DeviceListMix: split code in smaller methods 2022-05-12 14:03:09 +02:00
Cayo Puigdefabregas b927e1ac54 Merge branch 'testing' into feature/#3100-wb-settings 2022-05-12 11:57:55 +02:00
cayop b1feff324f
Merge pull request #270 from eReuse/feature/#3368-tag-list
add tags in device list
2022-05-12 11:39:28 +02:00
cayop e8edd8e2d7
Merge pull request #268 from eReuse/feature/#3368-tag-list
add column created and put order descendent from created field
2022-05-12 11:34:25 +02:00
Cayo Puigdefabregas 0e974c0e92 add tags in device list 2022-05-12 11:33:28 +02:00
Cayo Puigdefabregas fee1d6787c add column created and put order descendent from created field 2022-05-12 11:03:48 +02:00
Cayo Puigdefabregas 9b6d77573f fixed Enhancement #3384 2022-05-12 10:33:04 +02:00
Cayo Puigdefabregas 515f31c562 fixed bug #3387 2022-05-12 10:15:46 +02:00
Cayo Puigdefabregas b6966328fb fixed bug #3383 2022-05-12 10:09:03 +02:00
Cayo Puigdefabregas eac90d32cf fixed bug #3386 2022-05-12 10:05:37 +02:00
Santiago L cba3bca8cf
Merge pull request #267 from RubenPX/lint
[Small-fix] ESLint ignore builded JS files
2022-05-11 22:43:20 +02:00
RubenPX d10bb70da8 ESLint ignore builded JS files 2022-05-11 19:07:52 +02:00
Santiago L 2457f776e1 Bump to version 2.1.2.alpha0 2022-05-11 18:53:22 +02:00
Santiago L 90690bdd66 Release version 2.1.1 2022-05-11 18:50:39 +02:00
Santiago L 6a8a38eaab
Merge pull request #259 from RubenPX/fix-indeterminated-checkbox
fix indeterminated checkbox on select lots
2022-05-11 18:43:51 +02:00
RubenPX 42760e5b9e Fix print labels devices 2022-05-11 18:42:29 +02:00
Santiago L 80d18e34a8
Merge pull request #256 from RubenPX/makingPublic-fields
fix code issues & add support to old browsers
2022-05-11 18:38:14 +02:00
Santiago L e7a455018c Add babel instructions on CONTRIBUTING.md 2022-05-11 18:37:37 +02:00
Cayo Puigdefabregas a2bfbef8cf Merge branch 'testing' into feature/list-snapshots-view-#3113 2022-05-11 18:24:25 +02:00
Santiago L 87194cf090
Merge pull request #266 from eReuse/bugfix/#3380-to-text
Fix error when trade.document.url is None on device_list.html
2022-05-11 18:23:24 +02:00
Cayo Puigdefabregas bdc04c643c fixed url == None 2022-05-11 18:14:33 +02:00
Cayo Puigdefabregas 0f512d4bb3 fix link to device and show correctly date 2022-05-11 18:00:18 +02:00
RubenPX 60de8fde63
Merge branch 'testing' into fix-indeterminated-checkbox 2022-05-11 17:44:50 +02:00
Santiago L ef7e654c26 Bump to version 2.2.0.alpha0 2022-05-11 17:27:53 +02:00
Santiago L d218b19dd5 Release version 2.1.0 2022-05-11 17:24:59 +02:00
Santiago L 640cc99a71
Merge pull request #260 from RubenPX/fix/better-ui-selector
Show selected devices notification instead page select selection
2022-05-11 17:13:37 +02:00
Cayo Puigdefabregas 1baeddbd56 Merge branch 'feature/server-side-render-parser-3021' into feature/list-snapshots-view-#3113 2022-05-11 17:04:47 +02:00
Cayo Puigdefabregas 123757793f add link on sidebar and put empty data 2022-05-11 17:03:31 +02:00
Cayo Puigdefabregas 5e74255145 basic list snapshots 2022-05-11 16:59:36 +02:00
Cayo Puigdefabregas b8e980cabe fixed tests 2022-05-11 13:14:11 +02:00
Cayo Puigdefabregas ce001b64aa add test for wbsettings 2022-05-11 12:39:23 +02:00
Cayo Puigdefabregas 0e75865757 fix settings.html 2022-05-11 11:58:54 +02:00
Cayo Puigdefabregas 7ee2f2962b add view for download Workbench settings 2022-05-11 11:48:53 +02:00
RubenPX 411fe85b19 Check devices in current page 2022-05-11 11:20:25 +02:00
RubenPX cc7b453c06 Check initial state on dom loaded & check if has devices 2022-05-11 11:19:56 +02:00
RubenPX d27cc46f64 refactor device selection 2022-05-11 11:09:38 +02:00
RubenPX 881f56e3e4 Fix devices length comparation 2022-05-11 10:42:32 +02:00
Santiago L 4d354b377a
Merge pull request #258 from RubenPX/add-register-info-and-fix-text
#3333 - Add register info and fix text
2022-05-10 22:44:45 +02:00
cayop cbf8d68461
Merge pull request #262 from eReuse/changes/changelog
Changes/changelog
2022-05-10 11:03:39 +02:00
cayop 28cf52baab
Merge pull request #263 from eReuse/feature/#3325-new-features-filter
fix the All devices option
2022-05-10 11:03:23 +02:00
Cayo Puigdefabregas 37c43fe3d1 Merge branch 'testing' into feature/server-side-render-parser-3021 2022-05-10 11:00:40 +02:00
Cayo Puigdefabregas a54d57f4ab fix the All devices option 2022-05-10 10:22:22 +02:00
Cayo Puigdefabregas ae95e7c57a update CHANGELOG 2022-05-10 10:04:22 +02:00
Cayo Puigdefabregas f83163040c update CHANGELOG 2022-05-09 17:53:53 +02:00
cayop bb21ca6513
Merge pull request #261 from eReuse/feature/#3325-new-features-filter
fixed bug
2022-05-09 17:09:28 +02:00
Cayo Puigdefabregas b10a8c9e35 Merge branch 'testing' into feature/server-side-render-parser-3021 2022-05-09 17:07:07 +02:00
Cayo Puigdefabregas d800c6950c fixed bug 2022-05-09 16:48:34 +02:00
cayop 74597f2125
Merge pull request #257 from eReuse/feature/#3325-new-features-filter
Feature/#3325 new features filter
2022-05-09 16:36:42 +02:00
Cayo Puigdefabregas 1d51629796 resolve conflict 2022-05-09 16:35:44 +02:00
RubenPX 3da1bdcad1 Show selected devices notify instead page select 2022-05-09 14:40:28 +02:00
RubenPX ff00b88fd7 fix indeterminated checkbox 2022-05-09 14:18:41 +02:00
RubenPX ec9074ae7c add register user dialog 2022-05-09 14:03:51 +02:00
RubenPX 651c0cb9d8 Fix text select lots instead devices 2022-05-09 13:57:17 +02:00
Cayo Puigdefabregas 04e4f4ff74 add generics filters 2022-05-09 13:43:02 +02:00
Lint Action 776e38aa67 Fix code style issues with ESLint 2022-05-09 09:30:23 +00:00
RubenPX 8f80e7dff4 Fix declaration variable 2022-05-09 11:29:48 +02:00
Cayo Puigdefabregas 252c5285d8 refactorice 2022-05-09 11:12:34 +02:00
Lint Action 4f72654f50 Fix code style issues with ESLint 2022-05-09 09:10:08 +00:00
RubenPX 2e42b08519 use babel to support old browsers 2022-05-09 11:07:57 +02:00
RubenPX 275b7ad0c5 fix declaration variable 2022-05-09 11:06:48 +02:00
cayop d4e6469ddf
Merge pull request #255 from eReuse/bugfix/#3352-status-device
fixed bug #3352
2022-05-09 10:44:24 +02:00
Cayo Puigdefabregas 8d9abb58e3 fixed bug #3352 2022-05-09 10:18:22 +02:00
Santiago L 84b384c47b
Merge pull request #254 from RubenPX/patch-1
Fix minor typos
2022-05-06 20:17:36 +02:00
Santiago L 4c16065afa Fix typo: Unassgined to Unassigned #3339 2022-05-06 20:15:35 +02:00
Santiago L 563f13ea43
Merge pull request #237 from RubenPX/feature/confirm-trade-changes
Create confirmation dialog on apply lots changes
2022-05-06 19:46:29 +02:00
Santiago L e1513e2ccf Fix typos 2022-05-06 19:44:59 +02:00
RubenPX 02cb36371a
Make title bigger (H1) 2022-05-06 08:40:49 +02:00
RubenPX eb5c109220 Merge commit '7177b0fbfda37e495387834c7f2342b78f6559c8' into feature/confirm-trade-changes 2022-05-06 08:26:37 +02:00
Santiago L 7177b0fbfd
Merge pull request #233 from RubenPX/filter-in-out-trades
Filter in out trades from lots selector
2022-05-06 07:58:11 +02:00
Santiago L 00c5070784
Merge pull request #241 from RubenPX/bugfix/various-fixes
Several bug fixes on selector & lot component
2022-05-06 07:52:15 +02:00
cayop 1a04b44dbe
Merge pull request #253 from eReuse/changes/#3327-drop-public-link-csv
drop download public links
2022-05-05 18:56:08 +02:00
Cayo Puigdefabregas eca2795857 Merge branch 'testing' into feature/server-side-render-parser-3021 2022-05-05 18:52:59 +02:00
Cayo Puigdefabregas 3ca7292448 drop download public links 2022-05-05 18:36:52 +02:00
cayop 3f9e771ad6
Merge pull request #252 from eReuse/feature/#3308-device-details
Feature/#3308 device details
2022-05-05 13:35:29 +02:00
Cayo Puigdefabregas e34b591690 Merge branch 'testing' into feature/server-side-render-parser-3021 2022-05-05 13:32:32 +02:00
Cayo Puigdefabregas af30453c12 fix message of allocate bug 2022-05-05 13:10:02 +02:00
Cayo Puigdefabregas 33fd574f18 add lots tab in device details 2022-05-05 12:31:29 +02:00
Cayo Puigdefabregas 1c670641f4 add web: public link in device details page 2022-05-05 12:00:40 +02:00
Cayo Puigdefabregas 1023f3fdca add public link in model 2022-05-05 12:00:02 +02:00
cayop 34f7989553
Merge pull request #251 from eReuse/bugfix/allocate-#3304
add checks of device.allocated
2022-05-05 11:37:06 +02:00
Cayo Puigdefabregas 9eda5c0466 add checks of device.allocated 2022-05-05 11:31:13 +02:00
cayop ce32db6d37
Merge pull request #250 from eReuse/change/#3300-change-color-blue
add color in bordered navs links
2022-05-04 18:10:34 +02:00
Cayo Puigdefabregas 875fe7a340 Merge branch 'testing' into feature/server-side-render-parser-3021 2022-05-04 18:07:23 +02:00
Cayo Puigdefabregas 9a74eabc23 add color in bordered navs links 2022-05-04 18:06:19 +02:00
Cayo Puigdefabregas 20fc9ded06 fix url response 2022-05-04 17:58:14 +02:00
Cayo Puigdefabregas 780b7d4ef2 Merge branch 'testing' into feature/server-side-render-parser-3021 2022-05-04 17:56:30 +02:00
cayop de53649aa8
Merge pull request #249 from eReuse/change/#3300-change-color-blue
fix sidebar
2022-05-04 17:43:53 +02:00
Cayo Puigdefabregas 074fd4e542 fix sidebar 2022-05-04 17:39:20 +02:00
cayop 9826185e26
Merge pull request #248 from eReuse/change/#3300-change-color-blue
fix login
2022-05-04 12:58:18 +02:00
Cayo Puigdefabregas 8cd2f22fcc Merge branch 'testing' into feature/server-side-render-parser-3021 2022-05-04 12:55:10 +02:00
Cayo Puigdefabregas f2a85af1c2 fix login 2022-05-04 12:53:22 +02:00
cayop bba1e57f13
Merge pull request #247 from eReuse/change/#3300-change-color-blue
change colors and log
2022-05-04 12:28:41 +02:00
Cayo Puigdefabregas 16b8b4c78f Merge branch 'testing' into feature/server-side-render-parser-3021 2022-05-04 12:25:44 +02:00
Cayo Puigdefabregas 8a6b0cde37 change colors and log 2022-05-04 12:23:04 +02:00
RubenPX cb4f12eb1e Merge remote-tracking branch 'MyRepo/testing' into feature/confirm-trade-changes 2022-05-03 19:21:14 +02:00
RubenPX e30779fcde Merge remote-tracking branch 'MyRepo/testing' into bugfix/various-fixes 2022-05-03 19:20:59 +02:00
cayop 8591f061a8
Merge pull request #246 from eReuse/bugfix/change-lot-name
fix bug
2022-05-03 17:22:59 +02:00
Cayo Puigdefabregas d2b63af17a Merge branch 'testing' into feature/server-side-render-parser-3021 2022-05-03 17:20:09 +02:00
Cayo Puigdefabregas eaf8bdef65 fix bug 2022-05-03 17:00:02 +02:00
RubenPX 2aab4b49d3 Allow user to cancel all selection 2022-05-03 12:52:26 +02:00
RubenPX 9d9514e68b Select full list devices 2022-05-03 12:13:15 +02:00
RubenPX e31e3d3d45 Merge branch 'bugfix/various-fixes' into feature/confirm-trade-changes 2022-05-03 11:10:19 +02:00
RubenPX d7f7e4d2e5 fixed api not working on recive full list
Api needs filter devices to work well
2022-05-03 11:06:05 +02:00
Cayo Puigdefabregas db648a1bb0 fix render tests 2022-04-29 19:59:52 +02:00
Cayo Puigdefabregas 67ee1cdde8 resolve conflict 2022-04-29 19:26:44 +02:00
cayop 60a11794ae
Merge pull request #243 from eReuse/bugfix/#3288-common-lots
Bugfix/#3288 common lots
2022-04-29 19:25:55 +02:00
cayop 861515c46d
Merge pull request #229 from eReuse/feature/server-side-render-testing
Feature/server side render testing
2022-04-29 18:39:37 +02:00
Cayo Puigdefabregas 98ffe1092c Merge branch 'testing' into bugfix/#3288-common-lots 2022-04-29 18:36:52 +02:00
Cayo Puigdefabregas 921049a28b add more render basic tests 2022-04-29 18:23:05 +02:00
Cayo Puigdefabregas 7fe33f3a42 ass form errors in message 2022-04-29 17:53:59 +02:00
Cayo Puigdefabregas 322b340607 add fix test with redirects 2022-04-29 17:41:13 +02:00
RubenPX 6575e418e7 fix undefined
This will fix when you select all lots and you make change that clears list
2022-04-29 14:39:56 +02:00
RubenPX c1829a657e Merge branch 'bugfix/various-fixes' into feature/confirm-trade-changes 2022-04-29 14:28:24 +02:00
RubenPX c78c9c5d7d Lint 2022-04-29 14:07:04 +02:00
RubenPX 8bbca0301b Selection devices by page 2022-04-29 14:06:09 +02:00
RubenPX b88a514edf Fix reactivity un variables
avoid outdated data variable
2022-04-29 13:58:48 +02:00
RubenPX 7503895a4f Adds selector by pages 2022-04-29 13:34:45 +02:00
RubenPX f8f4e10f9f Restore state of checkbox before apply lots changes 2022-04-29 13:33:44 +02:00
RubenPX e238fb287a Fix remove rows using library API 2022-04-29 13:27:46 +02:00
Cayo Puigdefabregas ef71eed27f Merge branch 'testing' into feature/server-side-render-testing 2022-04-29 13:12:09 +02:00
Cayo Puigdefabregas ad0ced98e4 refactor common context 2022-04-29 13:10:44 +02:00
RubenPX 0fd12ee37c Use TableController to check all devices list 2022-04-29 12:36:42 +02:00
Cayo Puigdefabregas 02bfeea2fc Merge branch 'testing' into feature/server-side-render-parser-3021 2022-04-29 11:39:04 +02:00
Cayo Puigdefabregas 9f8f5ec9e0 fix unique identifier 2022-04-29 11:38:47 +02:00
RubenPX f26b441fef create TableController to access more easy to table info 2022-04-29 11:36:55 +02:00
Cayo Puigdefabregas 112f459db3 resolve conflict 2022-04-29 11:09:18 +02:00
Santiago L c176659cbe
Merge pull request #238 from eReuse/feature/#3262-customize-labels
Feature/#3262 customize labels
2022-04-29 09:09:49 +02:00
Cayo Puigdefabregas c82f173edf resolve conflict 2022-04-28 18:47:56 +02:00
cayop 09c5126b0c
Merge pull request #239 from eReuse/change/#3202-change-tag-for-unique-identifier
change tags for unique identifiers
2022-04-28 18:47:55 +02:00
Cayo Puigdefabregas d8a44c661a Merge branch 'testing' into feature/server-side-render-parser-3021 2022-04-28 18:45:51 +02:00
RubenPX 8d43128e68 fix render item in confirmation dialog 2022-04-28 18:43:38 +02:00
Cayo Puigdefabregas c14d8482be Merge branch 'testing' into change/#3202-change-tag-for-unique-identifier 2022-04-28 18:32:39 +02:00
RubenPX 9cef5188db Merge branch 'bugfix/various-fixes' into feature/confirm-trade-changes 2022-04-28 18:31:15 +02:00
RubenPX 962f7cb94c lint 2022-04-28 18:29:39 +02:00
RubenPX c824110b00 Send device model through the methods 2022-04-28 18:29:18 +02:00
cayop a5bc694d86
Merge pull request #242 from eReuse/feature/add-column-type-in-devices-list
add icons types of devices in list of devices
2022-04-28 18:19:09 +02:00
Cayo Puigdefabregas 7362eb4492 add computer monitor 2022-04-28 17:56:00 +02:00
Cayo Puigdefabregas 3a5e806104 add icons types of devices in list of devices 2022-04-28 17:46:12 +02:00
RubenPX 1727ab70a3 lint 2022-04-28 17:00:23 +02:00
RubenPX 4aa024b041 checkpoint: add confirmation dialog 2022-04-28 16:58:44 +02:00
RubenPX 1ff0401b38 Merge commit '8d8ce634023e71d463f87527097c3ec8a2cdd7cb' into feature/confirm-trade-changes 2022-04-28 16:52:26 +02:00
RubenPX 8d8ce63402 Optimize manage list 2022-04-28 15:32:35 +02:00
RubenPX 770ab8ea8d improvement sending variables data through methods 2022-04-28 15:29:57 +02:00
RubenPX bb284008cc Fix re render table 2022-04-28 15:01:39 +02:00
Santiago L 293364acfb
Merge pull request #222 from eReuse/feature/extend-user-datas-#3016
Feature: allow user to update its password #3016
2022-04-28 12:08:00 +02:00
Santiago L d0e033197c Drop Agent.get_full_name because is unused 2022-04-28 12:06:43 +02:00
Santiago L 9afe6bf9e6 Revert all changes related to ProfileForm
We need to talk about the concepts of Agent and User and their
relationship before allowing the user to update their data.
2022-04-28 12:03:12 +02:00
RubenPX 2ffa606bc3 Documentation API 2022-04-28 11:53:49 +02:00
Santiago L 3fd208c479 Restore tabs to include title "Change password" 2022-04-28 11:50:07 +02:00
Cayo Puigdefabregas 87c66cf5cd change tags for unique identifiers 2022-04-28 11:47:52 +02:00
Santiago L 46c9e3f0cf
Merge pull request #235 from eReuse/changes/Hidde-trade-#3250
hide 2 trade buttons
2022-04-28 11:41:27 +02:00
Santiago L 6946a2584b Refactor: group related code (delete button & modal status) 2022-04-28 11:39:40 +02:00
Santiago L 8125279619 Add comment to not rendered code 2022-04-28 11:38:31 +02:00
RubenPX a945fc085f Query using Api instead of javascript filter 2022-04-28 11:31:24 +02:00
RubenPX c8dc1b11e2 Add trade type on api options 2022-04-28 11:22:53 +02:00
Cayo Puigdefabregas c2e4313521 change tag for Unique identifier in label_details 2022-04-28 11:16:12 +02:00
Cayo Puigdefabregas ad11521b64 fix label details for new architecture 2022-04-28 10:14:10 +02:00
Cayo Puigdefabregas e378fef1a6 add customize options in print html and pdf 2022-04-27 18:56:15 +02:00
Cayo Puigdefabregas bf42a79ef7 change devices for tags in printlabels 2022-04-27 18:55:27 +02:00
Cayo Puigdefabregas b11bb163a0 hide 2 trade buttons 2022-04-26 17:35:29 +02:00
Cayo Puigdefabregas ef3ea288ce Merge branch 'testing' into feature/extend-user-datas-#3016 2022-04-26 16:37:12 +02:00
Cayo Puigdefabregas 13950a5ff6 show only password reset 2022-04-26 16:35:16 +02:00
Cayo Puigdefabregas 11201cc0bd Merge branch 'testing' into feature/server-side-render-parser-3021 2022-04-26 13:30:52 +02:00
Cayo Puigdefabregas ef65b1084e Revert "HiddenField instead of StringField"
This reverts commit 04063db60e.
2022-04-26 12:56:34 +02:00
Cayo Puigdefabregas c3bb5cb863 Revert "add print_labels instead of call submit from the template"
This reverts commit 022d40edbe.
2022-04-26 12:56:02 +02:00
Cayo Puigdefabregas 2a7eeb0b5d Revert "add print_labels instead of call submit from the template"
This reverts commit c8aefc6029.
2022-04-26 12:55:48 +02:00
Cayo Puigdefabregas ad9a8a04bd Revert "drop commits 04063db 022d40e c8aefc6"
This reverts commit 9dbebed9d5.
2022-04-26 12:55:01 +02:00
Cayo Puigdefabregas b933581b89 add file snapshotErrorsComponents.json 2022-04-26 12:12:31 +02:00
Cayo Puigdefabregas 9dbebed9d5 drop commits 04063db 022d40e c8aefc6 2022-04-26 11:52:51 +02:00
Cayo Puigdefabregas f34fedfb74 fix migration file 2022-04-26 11:49:40 +02:00
Cayo Puigdefabregas 53a43ff6cb add test for wb lite 2022-04-26 10:47:29 +02:00
Cayo Puigdefabregas 1c12548851 return 422 if no there are components neither hid 2022-04-26 10:47:04 +02:00
Cayo Puigdefabregas b836e0a9ae save exceptions of components 2022-04-26 10:44:49 +02:00
Cayo Puigdefabregas 6ef2d8795d clean try exception 2022-04-26 10:43:58 +02:00
Cayo Puigdefabregas f666047565 adapt test for error 400 instead of 422 2022-04-25 18:40:53 +02:00
Cayo Puigdefabregas aafebbb370 adapt correctly response 400 instead of default 422 2022-04-25 18:38:13 +02:00
Santiago L c6bc695881 Merge branch 'testing' into filter-in-out-trades 2022-04-25 18:35:02 +02:00
Cayo Puigdefabregas 767f7c3092 add tests wb lite errors 422 2022-04-25 17:21:25 +02:00
Cayo Puigdefabregas e818feeebd required datas in json of wb lite, error 422 2022-04-25 17:20:54 +02:00
Cayo Puigdefabregas 515dad5850 fix test for the new api response 201 2022-04-25 14:06:05 +02:00
Cayo Puigdefabregas f37e55e3b5 add response 201 2022-04-25 14:05:30 +02:00
Cayo Puigdefabregas 531e213eff change sid for wbid in tests 2022-04-25 11:54:16 +02:00
Cayo Puigdefabregas a362c8644b add sid instead of wbid in schema action snapshot 2022-04-25 11:53:27 +02:00
RubenPX 538541cd4d filter in out trades from lots selector 2022-04-25 11:49:11 +02:00
Cayo Puigdefabregas 7b784b6174 sid in snapshot action 2022-04-25 11:45:50 +02:00
Cayo Puigdefabregas be53827c02 sid in parser and inventory 2022-04-25 11:45:25 +02:00
Cayo Puigdefabregas 9b1e8617fa add sid in snapshot_errors 2022-04-25 11:43:30 +02:00
Cayo Puigdefabregas 4ab692405f add migrations change sid for wbid 2022-04-25 11:30:41 +02:00
Santiago L f299367ba7
Merge pull request #231 from RubenPX/testing
fix github actions ESLint
2022-04-25 11:29:47 +02:00
Santiago L b0f9a83dce
Merge pull request #232 from RubenPX/fix-max-lots-list
[Change] Set max lots list to 20
2022-04-25 11:29:04 +02:00
Santiago L 91277b048d
Merge pull request #230 from RubenPX/bugfix/fix-lots
[Bugfix] fix lots component issues
2022-04-25 11:27:47 +02:00
RubenPX e48a6c1ae4 set max lots list to 20 2022-04-25 11:19:55 +02:00
RubenPX f8b852708d Fix github actions 2022-04-25 11:15:33 +02:00
RubenPX 1c0cef120e Fix height list, use px instead of vh 2022-04-22 13:04:09 +02:00
Cayo Puigdefabregas c8aefc6029 add print_labels instead of call submit from the template 2022-04-22 12:54:27 +02:00
Cayo Puigdefabregas 022d40edbe add print_labels instead of call submit from the template 2022-04-22 12:36:14 +02:00
Cayo Puigdefabregas 04063db60e HiddenField instead of StringField 2022-04-22 12:35:16 +02:00
Santiago L 73d0e77281 Rename CSS files 2022-04-22 11:12:29 +02:00
Santiago L dd4e938d30 Split custom CSS & niceadmin theme CSS
Keep original source Nice Admin template to keep easy future updates
2022-04-22 11:07:18 +02:00
Cayo Puigdefabregas bb62798ffe Merge branch 'testing' into feature/server-side-render-parser-3021 2022-04-22 09:55:59 +02:00
Cayo Puigdefabregas 64511b33a1 change description buttons of print labels 2022-04-22 09:51:45 +02:00
Cayo Puigdefabregas 85d580c094 fix duplicity snapshotErrors 2022-04-22 09:51:17 +02:00
RubenPX 49c7caf5bd Fix set max height 2022-04-21 20:14:36 +02:00
Lint Action 7c96c5706c Fix code style issues with ESLint 2022-04-21 18:04:42 +00:00
RubenPX a9299077aa fix typo 2022-04-21 19:59:10 +02:00
RubenPX 454fb891e2 Order lots 2022-04-21 19:53:27 +02:00
RubenPX 740af8f7b6 Style fix show lots as list 2022-04-21 19:53:09 +02:00
Cayo Puigdefabregas 9f948df209 add always response 201 2022-04-21 18:55:00 +02:00
Cayo Puigdefabregas f9be7f0a14 return error response in post request 2022-04-21 14:02:16 +02:00
Cayo Puigdefabregas e37fa49c3e fix bug in validation actions 2022-04-21 14:01:33 +02:00
Cayo Puigdefabregas fd74804f35 add actions test 2022-04-21 14:01:03 +02:00
Cayo Puigdefabregas b986b6e95a more tests 2022-04-20 18:22:22 +02:00
Santiago L d1d693542f
Merge pull request #228 from RubenPX/ESLint-Action
ESLint integration to indent code (Github Actions)
2022-04-20 14:13:02 +02:00
Cayo Puigdefabregas 2fecd1aa60 add more test 2022-04-20 12:35:50 +02:00
Cayo Puigdefabregas 7c93fc68c5 fix encode of response in client 2022-04-20 12:35:25 +02:00
Lint Action 8a37217a38 Fix code style issues with ESLint 2022-04-20 10:12:59 +00:00
RubenPX 57c3bee109
Merge branch 'testing' into ESLint-Action 2022-04-20 12:12:30 +02:00
RubenPX 97e931e165 Action failed, fix issues 2022-04-20 12:09:56 +02:00
Santiago L dded82945e
Merge pull request #221 from RubenPX/change/frontend-fixes
Change: fix minor responsive issues
2022-04-20 12:05:56 +02:00
Lint Action a51cc9872d Fix code style issues with ESLint 2022-04-20 10:04:53 +00:00
Santiago L 33783b6e7d Revert "Fix login width"
This reverts commit d3564a6ba5.
2022-04-20 12:04:50 +02:00
RubenPX fb7b58bbae Change order steps 2022-04-20 12:04:18 +02:00
RubenPX b1746421a3 add prettier rule 2022-04-20 11:55:15 +02:00
RubenPX e68471d307 Create basic config 2022-04-20 11:54:58 +02:00
RubenPX 154362613e fix trade lots modal 2022-04-20 11:53:51 +02:00
Santiago L 9e47cd967c
Merge pull request #224 from RubenPX/bugfix/fix-clickable-lots
FIX: clickable lots selector not working when click in text
2022-04-19 19:49:07 +02:00
Cayo Puigdefabregas 4a5ad374f8 fix UserClientFlask 2022-04-19 18:39:42 +02:00
Cayo Puigdefabregas 25dc0047dc add tests 2022-04-19 18:39:05 +02:00
Cayo Puigdefabregas efbbdf3d44 Merge branch 'testing' into feature/server-side-render-testing 2022-04-19 11:03:05 +02:00
Cayo Puigdefabregas 7c0b3c190c test for check general snapshots 2022-04-19 10:47:49 +02:00
RubenPX 22ddea4a43
Merge branch 'testing' into change/frontend-fixes 2022-04-19 10:42:51 +02:00
Cayo Puigdefabregas 7d930551fa fix exit_status number 2022-04-18 19:09:03 +02:00
Cayo Puigdefabregas 7f6cac0242 fix qemu test 2022-04-18 19:08:23 +02:00
Cayo Puigdefabregas 5595d0ddcf fix Computer device in the list 2022-04-18 17:20:07 +02:00
Cayo Puigdefabregas 252c7b8d7d fix smartctl bugs 2022-04-18 17:14:26 +02:00
Cayo Puigdefabregas 093e78d2c8 add new test snapshot lite for clonic desktop 2022-04-18 17:13:38 +02:00
Cayo Puigdefabregas 379a2efca2 errors in snapshots 2022-04-13 20:15:40 +02:00
Cayo Puigdefabregas d870d254f1 drop pdbs 2022-04-13 19:12:12 +02:00
Cayo Puigdefabregas 4e19b9233b validate email is unique 2022-04-13 19:11:23 +02:00
Cayo Puigdefabregas 04cdb8181f drop settings and last_name of agent 2022-04-13 18:41:05 +02:00
Cayo Puigdefabregas a0a52d8248 view list for snapshot errors 2022-04-13 18:31:39 +02:00
Cayo Puigdefabregas 82bdfe3db5 Merge branch 'feature/server-side-render-parser-3021' into feature/list-snapshots-view-#3113 2022-04-13 17:30:24 +02:00
RubenPX 3f4b115575 fix clickable lots selector 2022-04-13 13:53:22 +02:00
Santiago L 5dcbc23235
Merge pull request #223 from RubenPX/testing
fix trade lots modal
2022-04-13 13:48:01 +02:00
Cayo Puigdefabregas febff54c6b fix bug 2022-04-13 13:28:22 +02:00
Cayo Puigdefabregas 0b5d8d46d1 fixing bug 2022-04-13 13:27:58 +02:00
RubenPX c256936b7d fix trade lots modal 2022-04-13 13:27:38 +02:00
Cayo Puigdefabregas 0d65dd7686 enums of tail 2022-04-13 13:14:01 +02:00
Cayo Puigdefabregas 89bb4770d9 fix individual call 2022-04-12 16:59:45 +02:00
Cayo Puigdefabregas 46bfc7fd47 fix save correctly the new password and fix save profile 2022-04-12 16:59:13 +02:00
Santiago L 160777dc35
Merge pull request #220 from RubenPX/lot-list-2
Change: Add reactive lots list
2022-04-12 16:33:15 +02:00
RubenPX 4611f79b44 lint 2022-04-12 14:12:21 +02:00
RubenPX dada6cc328 Fix close dialog when apply actions 2022-04-12 14:06:41 +02:00
RubenPX c733f0a1d8 Fix search count 2022-04-12 13:59:25 +02:00
Santiago L b8493d8f5c Sort changes and fix typo 2022-04-12 13:49:43 +02:00
Santiago L cdc3417c74 Remove unused code (part 2) 2022-04-12 13:49:00 +02:00
RubenPX 28bcf17083 Merge branch SearchPR and DeviceLotsList 2022-04-12 13:41:18 +02:00
RubenPX dcb61cf568 Merge commit '89647f6ed5a971d52e809ca37bfee1edb3439b48' into testing 2022-04-12 13:21:36 +02:00
RubenPX d985744fb8 fix device list padding 2022-04-12 13:19:56 +02:00
RubenPX d3564a6ba5 Fix login width 2022-04-12 13:17:17 +02:00
Santiago L 232d40c059
Merge pull request #219 from RubenPX/feature/Search
Feature: Search lots and devices
2022-04-12 13:01:58 +02:00
RubenPX 6c4d549c0a fix button spacing on tags management 2022-04-12 12:59:53 +02:00
RubenPX 08ebc862ae fix href link 2022-04-12 12:59:22 +02:00
RubenPX 23d8ba1570 fix lot buttons 2022-04-12 12:57:46 +02:00
RubenPX cb1f4377d6 Fix button spacing 2022-04-12 12:44:24 +02:00
RubenPX 89647f6ed5 Remove unused views 2022-04-12 12:41:05 +02:00
RubenPX 3feb84cf02 Update changelog 2022-04-12 12:32:28 +02:00
RubenPX 5ce535f5d5 Remove duplicated setup steps
See: Line 13
2022-04-12 12:32:20 +02:00
RubenPX 4b37fd6d87
Fix reference pull request 2022-04-12 12:31:18 +02:00
RubenPX f3387573d9 Remove duplicated setup steps
See: Line 13
2022-04-12 12:29:34 +02:00
RubenPX 286f56c52f Update changelog 2022-04-12 12:28:53 +02:00
RubenPX 938ccedac7 show message when search is empty 2022-04-12 12:06:38 +02:00
RubenPX 3ab7e8796f Fix use table library api instead replace content
https://github.com/fiduswriter/Simple-DataTables
2022-04-12 11:39:53 +02:00
RubenPX c910e0f7c0 Avoid hide dropdown when user clicked inside 2022-04-12 11:38:31 +02:00
Cayo Puigdefabregas 99e7764945 add check wbid and owner in lite wb 2022-04-12 11:19:56 +02:00
Cayo Puigdefabregas c8b11cf505 fix wbid bug 2022-04-12 11:13:08 +02:00
RubenPX 7d9d091a31
translate to english
Co-authored-by: Santiago L <santiago@ribaguifi.com>
2022-04-12 10:35:19 +02:00
RubenPX a910f9d76a
fix typo
Co-authored-by: Santiago L <santiago@ribaguifi.com>
2022-04-12 10:34:59 +02:00
Cayo Puigdefabregas 089dc92d62 fix bug upload snapshot from web 2022-04-12 10:25:45 +02:00
Cayo Puigdefabregas 388f586f95 migration file 2022-04-12 10:25:00 +02:00
Cayo Puigdefabregas b9a04b59f5 add wbid and owner in snapshot_errors 2022-04-12 10:24:32 +02:00
RubenPX 34da3599f3 Fix start search info 2022-04-12 09:40:45 +02:00
Cayo Puigdefabregas 9d4ca5a2dc change password 2022-04-11 19:48:59 +02:00
Cayo Puigdefabregas 1820b15255 save data profile 2022-04-11 17:16:20 +02:00
Santiago L 4065f46dd9 Merge branch 'testing' into PR-lots-list 2022-04-11 16:19:23 +02:00
RubenPX b08a013912 Remove demo data 2022-04-11 13:51:27 +02:00
RubenPX 756c7bd1c4 Search lots and devices 2022-04-11 11:44:48 +00:00
Cayo Puigdefabregas 874ca77286 Merge branch 'testing' into feature/extend-user-datas-#3016 2022-04-11 11:41:13 +02:00
Cayo Puigdefabregas e37e3b4c12 add file snapshot error timestamp 2022-04-11 11:39:43 +02:00
RubenPX e7dbb34315 Moved api lines to fork with others features branches
Future freature (Search feature)
2022-04-11 11:25:30 +02:00
Cayo Puigdefabregas cfe41e152b test for errors of snapshot schemas 2022-04-11 11:25:09 +02:00
Cayo Puigdefabregas e696f9b1af fix response with validation raise of the snapshot schemas 2022-04-11 11:24:25 +02:00
Cayo Puigdefabregas 8bd26b56f3 fix bug about version 2022-04-11 10:59:15 +02:00
RubenPX 06456b352f Refactor to reduche changes code 2022-04-11 10:42:56 +02:00
RubenPX 2cce025e58 Re-render when completed lots changes 2022-04-11 10:35:26 +02:00
Cayo Puigdefabregas 03e681a3d1 fix version of Werkzeug to 0.15.5 2022-04-08 18:25:08 +02:00
Cayo Puigdefabregas f6c332cdbf fix bug 2022-04-08 17:05:50 +02:00
Cayo Puigdefabregas 79672cc9ff add register api 2022-04-08 16:52:17 +02:00
Cayo Puigdefabregas a45c8d4fed Merge branch 'testing' into feature/server-side-render-parser-3021 2022-04-08 16:48:16 +02:00
Cayo Puigdefabregas 09738478ae change schema_version for schema_api 2022-04-08 16:46:57 +02:00
Cayo Puigdefabregas 50d0dffc16 add api to basic test 2022-04-08 12:45:35 +02:00
RubenPX 26275552c5 Select all functionality 2022-04-08 12:40:50 +02:00
RubenPX 832006f223 fix reset list to avoid repeat api calls 2022-04-08 12:40:11 +02:00
Cayo Puigdefabregas 2b5178c198 add parser schemas 2022-04-08 12:39:01 +02:00
RubenPX 458e267b46 fix lint javascript 2022-04-08 12:37:10 +02:00
Cayo Puigdefabregas 21c5cbce9f drop imports unused 2022-04-08 12:33:20 +02:00
Cayo Puigdefabregas 028f3c8e74 precommit 2022-04-08 12:26:36 +02:00
Cayo Puigdefabregas bd3befa0af fix test 2022-04-08 12:25:17 +02:00
Cayo Puigdefabregas 2471fa90cf use the common enum DataStorageInterface 2022-04-08 11:40:39 +02:00
Cayo Puigdefabregas 04e11586bf add schema_version to tests lite 2022-04-08 11:36:39 +02:00
Cayo Puigdefabregas 59e8db205d clean build2 from form uploadSnapshot 2022-04-08 11:17:58 +02:00
Cayo Puigdefabregas a8e05d76ae refactor build in form snapshot 2022-04-08 11:12:17 +02:00
Cayo Puigdefabregas 545a1013e9 add schema_version 2022-04-08 11:10:03 +02:00
Cayo Puigdefabregas cd6e079aee rebuild api views 2022-04-07 21:04:05 +02:00
Cayo Puigdefabregas d729b55f26 load json from snapshot schemas 2022-04-07 21:01:56 +02:00
Cayo Puigdefabregas 128140d4a8 refactoring build snapshot for reuse code 2022-04-07 21:00:45 +02:00
Cayo Puigdefabregas c92723d01b change resources for URIs in calls to api 2022-04-07 21:00:05 +02:00
Cayo Puigdefabregas b3ab6d306e add api resources un conftest 2022-04-07 20:59:13 +02:00
RubenPX 5fbcc6ba05 Fix multiple notifications & indetermined state 2022-04-07 14:59:19 +02:00
RubenPX 9489a70597 Fixed currentuser.token
It needs ":" at finally of string
2022-04-07 14:24:09 +02:00
RubenPX 184d22ac81 Fix User token
Needs encode string to Base64
2022-04-07 14:12:20 +02:00
RubenPX 629a773dd2 Add reactive lots list 2022-04-07 13:28:07 +02:00
Cayo Puigdefabregas 5df183edf1 add view for inventor snapshot 2022-04-06 20:23:08 +02:00
Cayo Puigdefabregas fe21ac3cd8 new validate api with out teal 2022-04-06 19:43:35 +02:00
Santiago L 63d99998a2
Merge pull request #213 from RubenPX/PR-Initial-setup
Add development setup & convert README.rst to Markdown
2022-04-06 17:37:43 +02:00
RubenPX 554d79d2f9 Upercase readme.md 2022-04-06 14:12:27 +02:00
Cayo Puigdefabregas d1310a67bf add profile form 2022-04-06 13:50:08 +02:00
Cayo Puigdefabregas 9f84659026 clean white space 2022-04-06 13:49:15 +02:00
Cayo Puigdefabregas 3114c678a4 add user model fields #3017 2022-04-06 12:35:08 +02:00
Cayo Puigdefabregas 58b4ead86c add components to check old snapshots 2022-04-05 19:17:26 +02:00
Cayo Puigdefabregas 0150b88e6e Merge branch 'testing' into feature/server-side-render-parser-3021 2022-04-05 12:49:53 +02:00
Cayo Puigdefabregas fbf3a20c1e add new snapshots 2022-04-05 12:37:43 +02:00
Cayo Puigdefabregas 7c6e5a8d2f add test for old snapshots 2022-04-05 12:35:33 +02:00
Cayo Puigdefabregas bf77934fdb fix uuid 2022-04-05 11:04:16 +02:00
Cayo Puigdefabregas 7f0184f049 add test for old snapshots 2022-04-05 11:03:40 +02:00
Cayo Puigdefabregas b13c3347b9 add SnapshotErrors in inventory form 2022-04-05 09:22:02 +02:00
Cayo Puigdefabregas db637a99ac add migrations for snapshot errors 2022-04-04 19:37:06 +02:00
Cayo Puigdefabregas 27d018a6a3 add new test snapshot qemu 2022-04-04 19:08:03 +02:00
Cayo Puigdefabregas d592e2fb06 bug fix uuid 2022-04-04 19:07:26 +02:00
RubenPX 57e35c016f fix link readme (reviewed) 2022-04-04 17:59:51 +02:00
RubenPX c5f006d40f fix troubleshooting and link 2022-04-04 17:45:04 +02:00
RubenPX 6b7cf88a2f fix typo developement to development 2022-04-04 17:25:39 +02:00
RubenPX 584f8b990a change config to set readme.md instead of rst
Necesary to build wheel package
2022-04-04 17:23:25 +02:00
RubenPX 3119658098
Update developement-setup.md
Co-authored-by: Santiago L <santiago@ribaguifi.com>
2022-04-04 17:17:07 +02:00
Cayo Puigdefabregas cb5fb14c92 add model for save errors of parse snapshots 2022-04-04 13:27:04 +02:00
RubenPX 4656bbf872 add developement setup guide 2022-04-04 12:35:52 +02:00
RubenPX e1821c3a8e Comment some app.py lines that cause an error
Request by @slamora
2022-04-04 12:35:32 +02:00
RubenPX 3967d6a0c4 Convert readme to markdown 2022-04-04 12:34:33 +02:00
Cayo Puigdefabregas 77a35ec1a3 fix test for new jsons 2022-04-01 18:27:19 +02:00
Cayo Puigdefabregas 09ba81e92d fix parser for qemu datas 2022-04-01 18:25:58 +02:00
Cayo Puigdefabregas 6271c717a3 pass lshw and smart loadeds instead of raw data 2022-03-31 19:44:06 +02:00
Cayo Puigdefabregas 7e3904700f pass lshw dict instead of raw data 2022-03-31 19:42:50 +02:00
Cayo Puigdefabregas 76336ff34d change schema for lshw and smart data 2022-03-31 19:41:22 +02:00
Cayo Puigdefabregas 026a88acb8 fix comparation datas put both in utc time 2022-03-31 19:40:05 +02:00
Cayo Puigdefabregas 6fad773c91 change version of wb 2022-03-31 19:38:33 +02:00
Cayo Puigdefabregas 5eab44b46f new file for test 2022-03-31 19:38:05 +02:00
Cayo Puigdefabregas 90ad7afdc8 review pr 212 mv schemas, refactor forms and clean code 2022-03-30 18:29:15 +02:00
Cayo Puigdefabregas 3be389c23f review pr 212 about refactor and schemas 2022-03-30 18:27:57 +02:00
Santiago L de23503f42 Drop numpy dependency: use math.hypot
Refactor code to adapt types: `numpy.hypot` supports pint units but
`math.hypot` expects float. It keeps behaviour because units are
not stored on database
2022-03-30 15:29:12 +02:00
Cayo Puigdefabregas ca71494e2b add wbid in the snapshots 2022-03-30 13:48:55 +02:00
Cayo Puigdefabregas 4881aac5c9 use numpy instead of math 2022-03-30 10:52:09 +02:00
Cayo Puigdefabregas cc2385cddf use py-dmidecode instead of dmidecode 2022-03-30 10:44:04 +02:00
Cayo Puigdefabregas 118726d207 math.hypot instead of numpy 2022-03-30 10:33:09 +02:00
Cayo Puigdefabregas 2c8d556396 add dmidecode instead of dmiparse 2022-03-30 10:30:34 +02:00
Cayo Puigdefabregas 7a6d2c33e0 add dmidecode instead of dmiparse 2022-03-30 10:26:51 +02:00
Cayo Puigdefabregas d70810e88b drop pdb 2022-03-30 10:21:33 +02:00
Cayo Puigdefabregas fb29a0b07f add DMIParse 2022-03-30 10:20:27 +02:00
Cayo Puigdefabregas b7b6586f9e Merge branch 'feature/server-side-render-parser-3021' of github.com:eReuse/devicehub-teal into feature/server-side-render-parser-3021 2022-03-30 10:13:04 +02:00
Cayo Puigdefabregas fe8f636498 requirements pint 2022-03-30 10:12:54 +02:00
Santiago L 1a17ce758d Lock Ninja2 < 3.1 is incompatible with Flask 1.0.x 2022-03-30 10:01:26 +02:00
Cayo Puigdefabregas 9bb03d282d fix tests 2022-03-29 18:42:43 +02:00
Cayo Puigdefabregas 8fa1f41006 add requirements and drop dependencies 2022-03-29 17:32:12 +02:00
Cayo Puigdefabregas 7e9a78428a flake8 fixes 2022-03-29 17:20:58 +02:00
Cayo Puigdefabregas 1c74e27fd2 fix models import not used 2022-03-29 17:09:40 +02:00
Cayo Puigdefabregas 94fd4ef21c drop rate of snapshot tests 2022-03-29 17:00:09 +02:00
Cayo Puigdefabregas d39644716e fix bug 2022-03-29 16:59:33 +02:00
Cayo Puigdefabregas 3cd943037c add migration for new column 2022-03-29 15:44:57 +02:00
Cayo Puigdefabregas 34096b13eb clean 2022-03-29 13:36:31 +02:00
Cayo Puigdefabregas e41ee5a987 add snapshot lite to new fornt end 2022-03-29 13:36:18 +02:00
Cayo Puigdefabregas a38c940e44 return to the origin of firewire 2 2022-03-29 13:35:00 +02:00
Cayo Puigdefabregas 2c71d69a9a return to the origin of firewire 2022-03-29 13:34:01 +02:00
Cayo Puigdefabregas 90dea5492e change integer for string in firewire bios 2022-03-29 12:23:51 +02:00
Cayo Puigdefabregas f3e8fa6cc1 add action data storage test 2022-03-29 11:24:54 +02:00
Cayo Puigdefabregas f4a657052a . 2022-03-29 11:20:28 +02:00
Cayo Puigdefabregas ff4f78a44b add test_data_storage in the parse disk for get lifetime 2022-03-29 11:19:29 +02:00
Cayo Puigdefabregas 7a09127de9 add parsing from lshw and reuse code of worbench computer for parse 2022-03-28 19:14:19 +02:00
Cayo Puigdefabregas 883c01053f fix a lot of bugs and add storage and disk to the snapshot 2022-03-25 13:55:05 +01:00
Cayo Puigdefabregas 7d1e1589b6 add file_json 2022-03-25 13:53:27 +01:00
Cayo Puigdefabregas 43b4437333 made test 2022-03-25 13:52:51 +01:00
Cayo Puigdefabregas 76a6da406f made test 2022-03-25 13:52:38 +01:00
Cayo Puigdefabregas 01ceeb1be1 links parsing with snapshot view 2022-03-24 13:30:53 +01:00
Cayo Puigdefabregas f7b149f926 parser module 2022-03-24 13:13:28 +01:00
Cayo Puigdefabregas 417276b88b init parse from wb 2022-03-22 13:17:41 +01:00
Cayo Puigdefabregas 3c27d3d421 display 2022-03-22 11:06:46 +01:00
Cayo Puigdefabregas 8052618d55 parsed for network geting of lshw 2022-03-21 19:22:47 +01:00
Cayo Puigdefabregas 649e456feb Parsing cpu and chassis of computer 2022-03-18 18:19:06 +01:00
Cayo Puigdefabregas 18883b2b8d validate fields for the new snapshot 2022-03-18 12:07:22 +01:00
Cayo Puigdefabregas 6bad17013d save snapshot 2022-03-17 18:52:58 +01:00
Cayo Puigdefabregas f2ab02804b new userclient from flask instead of teal 2022-03-17 13:13:15 +01:00
Cayo Puigdefabregas ec99ad22b5 . 2022-03-17 11:50:57 +01:00
Cayo Puigdefabregas ccc28435db merge 2022-03-17 10:18:02 +01:00
Cayo Puigdefabregas 39dc4d8635 add one example that how use client validate 2022-03-15 19:57:54 +01:00
Cayo Puigdefabregas 071e145264 Add body in the check of request 2022-03-15 11:17:05 +01:00
Cayo Puigdefabregas 4e35660080 change conftest 2022-03-14 13:32:39 +01:00
Cayo Puigdefabregas 0b1f856ce6 modify Changelog.md 2022-03-11 19:16:39 +01:00
371 changed files with 66758 additions and 7958 deletions

15
.babelrc.json Normal file
View File

@ -0,0 +1,15 @@
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"edge": "17",
"firefox": "60",
"chrome": "67",
"safari": "11.1"
}
}
]
]
}

5
.eslintignore Normal file
View File

@ -0,0 +1,5 @@
ereuse_devicehub/static/vendor
ereuse_devicehub/static/js/print.pdf.js
ereuse_devicehub/static/js/qrcode.js
*.build.js
*.min.js

37
.eslintrc.json Normal file
View File

@ -0,0 +1,37 @@
{
"env": {
"browser": true,
"es2021": true,
"jquery": true
},
"extends": [
"airbnb",
"prettier"
],
"plugins": [
"prettier"
],
"parserOptions": {
"ecmaVersion": "latest"
},
"rules": {
"quotes": ["error","double"],
"no-use-before-define": "off",
"no-unused-vars": "warn",
"no-undef": "warn",
"camelcase": "off",
"no-console": "off",
"no-plusplus": "off",
"no-param-reassign": "off",
"no-new": "warn",
"strict": "off",
"class-methods-use-this": "off",
"eqeqeq": "warn",
"radix": "warn",
"max-classes-per-file": "warn"
},
"globals": {
"API_URLS": true,
"Api": true
}
}

38
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,38 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.

View File

@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

27
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@ -0,0 +1,27 @@
## Description
Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change.
Fixes # (issue)
## Type of change
Please delete options that are not relevant.
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] This change requires a documentation update
## How Has This Been Tested?
Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration
- [ ] Test A
- [ ] Test B
## Checklist:
- [ ] I have performed a self-review of my own code
- [ ] I have added tests that prove my fix is effective or that my feature works
## TODO
- [x] something that was recently finished
- [ ] something you are working on
- [ ] something else you are working on

55
.github/workflows/eslint.yml vendored Normal file
View File

@ -0,0 +1,55 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# ESLint is a tool for identifying and reporting on patterns
# found in ECMAScript/JavaScript code.
# More details at https://github.com/eslint/eslint
# and https://eslint.org
name: ESLint
on:
push:
branches: [master, testing]
pull_request_target:
branches: [master, testing]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v1
with:
node-version: '16'
- name: Install dependencies
run: npm install
- name: Run linters
uses: wearerequired/lint-action@v1
with:
eslint: true
prettier: false
commit_message: "Fix code style issues with ${linter}"
auto_fix: true
commit: true
github_token: "${{ secrets.GITHUB_TOKEN }}"
git_name: "Lint Action"
- name: Save Code Linting Report JSON
# npm script for ESLint
# eslint --output-file eslint_report.json --format json src
# See https://eslint.org/docs/user-guide/command-line-interface#options
run: npm run lint:report
# Continue to the next step even if this fails
continue-on-error: true
- name: Annotate Code Linting Results
uses: ataylorme/eslint-annotate-action@1.2.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
report-json: "eslint_report.json"
only-pr-files: true
- name: Upload ESLint report
uses: actions/upload-artifact@v2
with:
name: eslint_report.json
path: eslint_report.json

View File

@ -32,12 +32,12 @@ jobs:
strategy: strategy:
max-parallel: 4 max-parallel: 4
matrix: matrix:
python-version: [3.7] python-version: [3.9]
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }} - name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2 uses: actions/setup-python@v4
with: with:
python-version: ${{ matrix.python-version }} python-version: ${{ matrix.python-version }}
cache: 'pip' cache: 'pip'
@ -47,7 +47,7 @@ jobs:
sudo apt-get update -qy sudo apt-get update -qy
sudo apt-get -y install postgresql-client --no-install-recommends sudo apt-get -y install postgresql-client --no-install-recommends
python -m pip install --upgrade pip python -m pip install --upgrade pip
pip install -r requirements-testing.txt pip install -r requirements-dev.txt
pip install -r requirements.txt pip install -r requirements.txt
- name: Prepare database - name: Prepare database

76
.github/workflows/selenium.yml vendored Normal file
View File

@ -0,0 +1,76 @@
name: Selenium
on:
pull_request:
types: [ready_for_review, review_requested]
jobs:
build:
runs-on: ubuntu-latest
# Service containers to run with `container-job`
services:
# Label used to access the service container
postgres:
# Docker Hub image
image: postgres:11
ports:
- 5432:5432
# Set health checks to wait until postgres has started
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
POSTGRES_DB: dh_test
POSTGRES_USER: dhub
POSTGRES_PASSWORD: ereuse
strategy:
max-parallel: 4
matrix:
python-version: [3.9]
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
- name: Install dependencies
run: |
sudo apt-get update -qy
sudo apt-get -y install postgresql-client --no-install-recommends
python -m pip install --upgrade pip
pip install -r requirements-dev.txt
pip install -r requirements.txt
pip install -e .
mkdir bin
wget https://github.com/mozilla/geckodriver/releases/download/v0.30.0/geckodriver-v0.30.0-linux64.tar.gz
tar xf geckodriver-v0.30.0-linux64.tar.gz -C bin/
- name: Prepare database
env:
POSTGRES_DB: dh_test
POSTGRES_USER: dhub
POSTGRES_PASSWORD: ereuse
run: |
export PGPASSWORD=$POSTGRES_PASSWORD
psql -h "localhost" -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c "CREATE EXTENSION pgcrypto SCHEMA public;"
psql -h "localhost" -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c "CREATE EXTENSION ltree SCHEMA public;"
psql -h "localhost" -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c "CREATE EXTENSION citext SCHEMA public;"
psql -h "localhost" -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c "CREATE EXTENSION pg_trgm SCHEMA public;"
- name: Selenium tests
env:
SECRET_KEY: 'f00046306835001b55c230092e3a7990485beda0bc3bf732088d1ba1b5b74110e22e3f9ec3a24890272554b37d4'
DB_DATABASE: dh_test
FLASK_APP: examples/app.py
dhi: dbtest
run: |
alembic -x inventory=dbtest upgrade head
dh dummy --yes
flask run & pytest tests/test_selenium.py

21
.gitignore vendored
View File

@ -119,3 +119,24 @@ ENV/
# Temporal dir # Temporal dir
tmp/ tmp/
# NPM modules
node_modules/
yarn.lock
# ESLint Report
eslint_report.json
# modules/
tmp/
.env*
bin/
env*
examples/create-db2.sh
package-lock.json
snapshots/
!examples/snapshots
modules/
# emacs
*~

View File

@ -1,10 +1,10 @@
repos: repos:
- repo: https://github.com/psf/black - repo: https://github.com/psf/black
rev: 22.1.0 rev: 22.6.0
hooks: hooks:
- id: black - id: black
- repo: https://github.com/PyCQA/isort - repo: https://github.com/PyCQA/isort
rev: 5.9.3 rev: 5.10.1
hooks: hooks:
- id: isort - id: isort
- repo: https://github.com/PyCQA/flake8 - repo: https://github.com/PyCQA/flake8
@ -15,3 +15,17 @@ repos:
rev: 0.0.9 rev: 0.0.9
hooks: hooks:
- id: check_pdb_hook - id: check_pdb_hook
- repo: local
hooks:
- id: build-js
name: build-js
# pre-commit pass as parameters files included on the commit
# so babel command should be wrapped to ignore these files on
# package.json script
entry: npm run babel
language: node
files: ^ereuse_devicehub/static/js/main_inventory.js
- repo: https://github.com/jazzband/pip-tools
rev: 6.8.0
hooks:
- id: pip-compile

3
.prettierrc.json Normal file
View File

@ -0,0 +1,3 @@
{
"printWidth": 250
}

View File

@ -5,11 +5,242 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.ht and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.ht
ml). ml).
## master
## testing ## testing
## [2.5.3] - 2023-05-13
- [added] #450 add new datawipe in csv.
- [changed] #447 Share a lot between 2 users, one is owner the other is read only.
- [changed] #448 enhancements in export lots.
- [changed] #449 remove button of submit in filter of list of devices.
- [changed] #452 New version of settings for workbench.
- [fixed] #445 required File for new documents bat optional for edit document.
- [fixed] #446 Fix id_supplier and id_internal in export devices.
- [fixed] #451 fix new datawipe in certificate erasure.
- [fixed] #453 fix value method in certificate erasure.
- [fixed] #454 remove validation of email for placeholders type mobile.
- [fixed] #455 add placeholders in csv metrics and pdf certificate.
- [fixed] #456 upload placeholders with type datastorage.
- [fixed] #457 change format erase datawipe.
- [fixed] #458 not datawipe for placeholders computers.
## [2.5.2] - 2023-04-20
- [added] #414 add new vars in the settings file for wb.
- [added] #440 add lots in export devices.
- [added] #441 allow remove documents.
- [added] #442 allow edit documents.
- [added] #443 add documents to devices.
- [added] #444 add new columns in list of documents.
- [changed] #439 move teal as internal module.
- [fixed] #437 replace names erasure by sanitization in templates.
## [2.5.1] - 2023-03-17
- [changed] #423 new hid.
- [changed] #426 new version of public page of device.
- [changed] #427 update links of terms and condotions.
- [changed] #428 only the data storage allow syncrinize, the rest are duplicate.
- [changed] #430 new version of erasure certificate.
- [fixed] #416 fix dhid in snapshot logs.
- [fixed] #419 fix settings version and template.
- [fixed] #420 not appear all lots in the dropdown menu for select the a lot.
- [fixed] #421 fix remove a placeholder from one old trade lot.
- [fixed] #422 fix simple datatables.
- [fixed] #424 fix new hid.
- [fixed] #431 fix forms for customer details.
- [fixed] #432 fix erasure certificate for a servers.
- [fixed] #433 fix get the last incoming for show customer datas in certificate.
- [fixed] #434 fix reopen transfer.
- [fixed] #436 fix hid in erasure certificate.
## [2.5.0] - 2022-11-30
- [added] #407 erasure section with tabs in top.
- [added] #411 add new generic device as Other.
- [changed] #409 add backend pagination instead of javascript.
- [changed] #410 change teh top search for advanced search.
- [fixed] #412 show in snapshots log, type upload correctly.
- [fixed] #413 put order in documents.
- [fixed] #415 put prefix of lot in result of search.
## [2.4.3] - 2022-11-18
- [added] #386 add registration module.
- [added] #387 add template settings for Secure Erasure.
- [added] #397 add obada standard export.
- [added] #402 add reset password module.
- [added] #406 add orphans disks page.
- [changed] #391 add dhid in table and export of Erasure section.
- [changed] #395 change response for the new api to workbench.
- [changed] #396 modularize commands.
- [fixed] #388 lock update different motherboard with the same id.
- [fixed] #389 some datastorage without placeholder.
- [fixed] #390 fix image in form edit device.
- [fixed] #398 placeholder in new components.
- [fixed] #399 add api_host in config.
- [fixed] #401 db_host need to be api address.
- [fixed] #403 change delimiter in obada export.
- [fixed] #404 javascript select all devices.
- [fixed] #405 update pillow.
## [2.4.2] - 2022-10-18
- [added] #373 Enhancement - UX Lots.
- [added] #377 add prefix in lots in device list.
- [added] #378 add new button transfer.
- [added] #381 add servers erase and show storage disk in list of device.
- [added] #383 new setup page and add server_erase in placeholder.
- [added] #384 add redirect snapshot to twin public page.
- [changed] #371 changes phid.
- [changed] #372 remove logo.
- [changed] #374 changes links UI management and Data Storage Erasure.
- [changed] #375 changes columns in snapshot logs.
- [changed] #379 changes representation date times.
- [fixed] #380 fix layout print label.
- [fixed] #382 fix template device list.
- [fixed] #385 components in unbinding process.
## [2.4.1] - 2022-10-05
- [added] #365 Manage dependencies using pip-tools.
- [added] #368 add migrations of monitors and mobiles.
- [changed]] #371 changes about phid, incremental per user.
- [fixed] #364 bad redirect to all devices.
- [fixed] #367 column PHID Erasure host.
- [fixed] #369 bug in test data storage.
- [fixed] #370 print label in details of the label.
## [2.4.0] - 2022-09-23
- [added] #312 Placeholder: new, edit, update. (manually and with excel).
- [added] #316 Placeholder: binding/unbinding. (manually).
- [added] #319 Add command report cli.
- [added] #326 settings for user demo.
- [added] #327 add Binding.
- [added] #328 export placeholders.
- [added] #330 workbench page.
- [added] #334 backup dhid and phid.
- [added] #340 add parth number for placeholders.
- [added] #349 add a new columns in report.
- [added] #356 new export hdds.
- [added] #362 add new columns in a snapshot log.
- [changed] #329 update Binding.
- [changed] #331 update workbench page.
- [changed] #338 change labels when add a new device.
- [changed] #339 change description upload placeholders page.
- [changed] #342 change concepts for binding, (Twin).
- [changed] #344 add "Ods File" as description in Placeholders Logs.
- [changed] #345 remove generation concept of device.
- [changed] #346 change editable device page.
- [changed] #347 change snapshot instead of abstract and placeholder instead of real.
- [changed] #348 change buttons new device.
- [changed] #355 changes links.
- [changed] #357 change button "New Actions".
- [changed] #358 change report device.
- [changed] #360 add placeholder device in lot instead of devices.
- [changed] #361 change message in form add device.
- [fixed] #313 Bump numpy from 1.21.6 to 1.22.0.
- [fixed] #314 bugs create placeholder from lot.
- [fixed] #317 bugs about exports placeholders.
- [fixed] #318 bugs about unlink tag of device.
- [fixed] #321 bugs in labels of serial number.
- [fixed] #322 validation imei for mobil.
- [fixed] #323 bug export devices.
- [fixed] #335 bugs in excel phid with nan.
- [fixed] #336 bugs Unassigned is visualized in all device view.
- [fixed] #337 bugs upload csv placeholders.
- [fixed] #343 forze Phid to by a string.
- [fixed] #350 bugs in certificates.
- [fixed] #351 bugs devices without phid.
- [fixed] #352 export certificate for placeholders.
- [fixed] #353 get the last update of the one device twin.
- [fixed] #354 titles of table.
- [fixed] #359 fix backup dhid.
- [fixed] #363 problems with render add documents in a transfer lot.
## [2.3.0] - 2022-07-12
- [added] #281 Add selenium test.
- [added] #305 Add button to download ISO Workbench.
- [added] #306 Add link to download JSON snapshot.
- [added] #308 Add sentry.
- [changed] #302 Add system uuid to check the identity of one device.
- [fixed] #309 Column lifecycle status is always empty.
**IMPORTANT**: PR #302 involves some changes in the deployment process:
```bash
# First, run script `extract_uuids.sh` before applying alembic migrations (e.g. with schema `dbtest`)
sh scripts/extract_uuids.sh
# Then, apply alembic migrations
alembic -x inventory=dbtest upgrade head
```
**NOTE**: If you forget (or don't need) to run this script before applying new migration it will work but any device will be updated.
## [2.2.0] - 2022-06-24
- [changed] #304 change anchor of link devices lots.
- [fixed] #315 create in a lot a new placeholder.
## [2.2.0 rc2] - 2022-06-22
- [added] #299 Multiselect with Shift.
- [added] #300 Add Sid in label.
- [added] #301 Add logo in label.
- [added] #303 Add export Lots.
- [added] #303 Add export relating lots with devices.
- [added] #303 To do possible add and remove one device in one lot transfer.
## [2.2.0 rc1] - 2022-06-07
- [added] #212 Server side render parser Workbench Snapshots.
- [added] #225 List of snapshots.
- [added] #265 Add feature for download Workbench settings.
- [added] #268 Add column created in device list.
- [added] #270 Add tags in device list.
- [added] #271 Add view for show all devices.
- [added] #272 Show lots on deviceList.
- [added] #273 Allow search/filter lots on lots management component.
- [added] #274 Add columns status in device list.
- [added] #277 Add developement build & precomit build.
- [added] #289 Add transfer.
- [added] #290 Add advanced search.
- [added] #291 SnapshotLog in old api.
- [added] #292 Add delivery note and receiver note.
- [changed] #275 remove all components in the filter of the device list.
- [changed] #282 upgrade dependencies pyjwt from 2.0.0a1 to 2.4.0.
- [changed] #283 Change visual format for dates in device list.
- [changed] #293 add options in select number of items per page. (50, 100)
- [fixed] #263 Fix select All devices options in select filter.
- [fixed] #267 ESLint ignore builded JS files.
- [fixed] #269 Allocate bugs.
- [fixed] #276 Create Computer Monitor instead of Monitor in form of create a new device.
- [fixed] #280 fix enums in migration process.
- [fixed] #284 Allocate bugs.
- [fixed] #285 lots search not working.
- [fixed] #287 apply button out of card.
## [2.1.1] - 2022-05-11
Hot fix release.
- [fixed] #256 JS support to old browsers using babel.
- [fixed] #266 Fix error when trade.document.url is None on device_list.html
## [2.1.0] - 2022-05-11
- [added] #219 Add functionality to searchbar (Lots and devices).
- [added] #222 Allow user to update its password.
- [added] #233 Filter in out trades from lots selector.
- [added] #236 Allow select multiple devices in multiple pages.
- [added] #237 Confirmation dialog on apply lots changes.
- [added] #238 Customize labels.
- [added] #242 Add icons in list of devices.
- [added] #244 Select full devices.
- [added] #257 Add functionality to search generic categories like all components.
- [added] #252 new tabs lots and public link in details of one device.
- [changed] #211 Print DHID-QR label for selected devices. - [changed] #211 Print DHID-QR label for selected devices.
- [changed] #218 Add reactivity to device lots.
- [changed] #220 Add reactive lots list.
- [changed] #232 Set max lots list to 20.
- [changed] #235 Hide trade buttons.
- [changed] #239 Change Tags for Unique Identifier.
- [changed] #247 Change colors.
- [changed] #253 Drop download public links.
- [fixed] #214 Login workflow - [fixed] #214 Login workflow
- [fixed] #221 Fix responsive issues on frontend.
- [fixed] #223 fix trade lots modal.
- [fixed] #224 fix clickable lots selector not working when click in text.
- [fixed] #254 Fix minor types in frontend.
- [fixed] #255 Fix status column on device list.
## [2.0.0] - 2022-03-15 ## [2.0.0] - 2022-03-15
First server render HTML version. Completely rewrites views of angular JS client on flask. First server render HTML version. Completely rewrites views of angular JS client on flask.

View File

@ -2,6 +2,15 @@
## Writing code ## Writing code
### Javascript and compatibility with "old" browsers
**Warning:** This project is using babel compiler... You need run an additional build step to make build js file
```bash
npm install
npm run babel
```
NOTE: If you prefer you can use yarn instead, it's compatible
NOTE2: This only affect to file `ereuse_devicehub/static/js/main_inventory.js`.
### Coding style ### Coding style
#### Python style #### Python style
@ -21,3 +30,29 @@ pre-commit install
Do this: `device_detail.html` Do this: `device_detail.html`
Don't do this: `DeviceDetail.html`, `Device-detail.html` Don't do this: `DeviceDetail.html`, `Device-detail.html`
## Adding a new dependency to the project
This project tracks its packages using pip-tools, it could be installed by running:
```
pip install pip-tools
```
Whenever you need to install a new package using pip install <package-name>:
1. Put the package name into `requirements.in` instead.
```
# requirements.in
...
new_package
```
2. Compile the requirements
```
pip-compile requirements.in --output-file=requirements.txt
```
3. Then install upgraded dependencies:
```
pip install -U -r requirements.txt
```

43
Definition-dpp.md Normal file
View File

@ -0,0 +1,43 @@
# Definitions
* A dpp is two hash strings joined by the character ":"
We call the first chain chid and the second phid.
* The chid and phid are hash strings of certain values.
We call the set of these values Documents.
Here we define these values.
## Chid
The chid is the part of dpp that defines a device, be it a computer,
a hard drive, etc. The chid is the most important part of a dpp since
anyone who comes across a device should be able to play it.
The chid is made up of four values:
* type
* manufacturer
* model
* serial_number
type represents the device type according to the devicehub.
These values are always represented in lowercase.
These values have to be ordered and concatenated with the character "-"
So:
{type}-{manufacturer}-{model}-{serial_number}
For example:
```
harddrive-seagate-st500lt0121dg15-s3p9a81f
```
In computer types this combination is not perfect and **can lead to collisions**.
That is why we need a value that is reliable and comes from the manufacturer.
## Phid
The values of the phid do not have to be reproducible. For this reason, each inventory can establish its own values and its order as a document.
It is important that each inventory store the document in string so that it can reproduce exactly the document that was hashed. So a document can be verifiable.
In the case of the DeviceHub, we use as the chid document all the values that the Workbench collects that describe the hardware's own data.
These data change depending on the version of the Workbench used.

49
Makefile Normal file
View File

@ -0,0 +1,49 @@
project := dkr-dsg.ac.upc.edu/ereuse
branch := `git branch --show-current`
commit := `git log -1 --format=%h`
#tag := ${branch}__${commit}
tag := latest
# docker images
devicehub_image := ${project}/devicehub:${tag}
postgres_image := ${project}/postgres:${tag}
# 2. Create a virtual environment.
docker_build:
docker build -f docker/devicehub.Dockerfile -t ${devicehub_image} .
# DEBUG
#docker build -f docker/devicehub.Dockerfile -t ${devicehub_image} . --progress=plain --no-cache
docker build -f docker/postgres.Dockerfile -t ${postgres_image} .
# DEBUG
#docker build -f docker/postgres.Dockerfile -t ${postgres_image} . --progress=plain --no-cache
@printf "\n##########################\n"
@printf "\ndevicehub image: ${devicehub_image}\n"
@printf "postgres image: ${postgres_image}\n"
@printf "\ndocker images built\n"
@printf "\n##########################\n\n"
docker_publish:
docker push ${devicehub_image}
docker push ${postgres_image}
.PHONY: docker
docker:
$(MAKE) docker_build
$(MAKE) docker_publish
@printf "\ndocker images published\n"
# manage 2 kinds of deployments with docker compose
dc_up_devicehub:
docker compose -f docker-compose_devicehub.yml up || true
dc_down_devicehub:
docker compose -f docker-compose_devicehub.yml down -v || true
dc_up_devicehub_dpp:
docker compose -f docker-compose_devicehub-dpp.yml up || true
dc_down_devicehub_dpp:
docker compose -f docker-compose_devicehub-dpp.yml down -v || true

122
README.md Normal file
View File

@ -0,0 +1,122 @@
# Devicehub
Devicehub is a distributed IT Asset Management System focused on reusing digital devices, created under the [eReuse.org](https://www.ereuse.org) initiative.
This README explains how to install and use Devicehub. [The documentation](http://devicehub.ereuse.org) explains the concepts, usage and the API it provides.
Devicehub is built with [Teal](https://github.com/ereuse/teal) and [Flask](http://flask.pocoo.org).
Devicehub relies on the existence of an [API_DLT connector](https://gitlab.com/dsg-upc/ereuse-dpp) verifiable data registry service, where specific operations are recorded to keep an external track record (ledger).
# Installing
Please visit the [Manual Installation](README_MANUAL_INSTALLATION.md) instructions to understand the detailed steps to install it locally or deploy it on a server. However, we recommend the following Docker deployment process.
# Docker
There is a Docker compose file for an automated deployment. Two instances of DeviceHub will be deployed. The following steps describe how to run and use it.
1. Download the sources:
```
git clone https://github.com/eReuse/devicehub-teal.git -b oidc4vp
cd devicehub-teal
```
2. If you want to initialise one of DeviceHub instances (running on port 5000) with sample device snapshots, copy it/them into that directory. e.g.
```
cp snapshot01.json examples/snapshots/
```
Otherwise, the device inventory of your DeviceHub instance will be empty and ready to add new devices. For that (no snapshot import), you need to change the var to 'n' in the **.env** file
```
IMPORT_SNAPSHOTS='n'
```
To register new devices, the [workbench software](https://github.com/eReuse/workbench) can be run on a device to generate its hardware snapshot that can be uploaded to one of the two DeviceHub instance.
3. Setup the environment variables in the .env file. You can find one example in examples/env.example.
If you don't have any, you can copy that example and modify the basic vars
```
cp examples/env.example .env
```
You can use these parameters as default for a local test, but default values may not be suitable for an internet-exposed service for security reasons. However, these six variables need to be initialised:
```
API_DLT
API_DLT_TOKEN
API_RESOLVER
ABAC_TOKEN
ABAC_USER
ABAC_URL
SERVER_ID_FEDERATED
CLIENT_ID_FEDERATED
```
The first six values should come from an already operational [API_DLT connector](https://gitlab.com/dsg-upc/ereuse-dpp) service instance.
For the last two values check [manual install step 9]('https://github.com/eReuse/devicehub-teal/blob/oidc4vp/README_MANUAL_INSTALLATION.md#installing') for more details.
4. Build and run the docker containers:
```
./launcher.sh
```
To stop these docker containers, you can use Ctl+C. You'll maintain the data and infrastructure state if you run "compose up" again.
On the terminal screen, you can follow the installation steps. If there are any problems, error messages will appear here. The appearance of several warnings is normal and can be ignored.
If the last line you see one text like this, *exited with code*:
```
devicehub-teal-devicehub-id-client-1 exited with code 1
```
means the installation failed.
If the deployment was end-to-end successful (two running Devicehub instances successfully connected to the DLT backend selected in the .env file), you can see this text in the last lines:
```
devicehub-teal-devicehub-id-client-1 | * Running on http://172.28.0.2:5000/ (Press CTRL+C to quit)
devicehub-teal-devicehub-id-server-1 | * Running on all addresses.
devicehub-teal-devicehub-id-server-1 | WARNING: This is a development server. Do not use it in a production deployment.
devicehub-teal-devicehub-id-server-1 | * Running on http://172.28.0.5:5000/ (Press CTRL+C to quit)
```
That means the two Devicehub instances are running in their containers, which can be reached as http://localhost:5000/ and http://localhost:5001/
Once the DeviceHub instances are running, you might want to register a user binding to the DLT with the following commands (here, it assumes you want to execute it on devicehub-id-client, you might also want to do it in devicehub-id-server). Change the variables accordingly
```
FILE=my_users_devicehub.json
DOCKER_SERVICE=devicehub-id-server
docker compose cp /path/to/${FILE} ${DOCKER_SERVICE}:/tmp/
docker compose exec ${DOCKER_SERVICE} flask dlt_register_user /tmp/${FILE}
```
**my_users_devicehub.json** is a custom file which is similar to the one provided in `examples/users_devicehub.json`
5. To shut down the services and remove the corresponding data, you can use:
```
docker compose down -v
```
If you want to enter a shell inside a **new instance of the container**:
```
docker run -it --entrypoint= ${target_docker_image} bash
```
If you want to enter a shell on an **already running container**:
```
docker exec -it ${target_docker_image} bash
```
To know the valid value for ${target_docker_image} you can use:
```
docker ps
```
6. These are the details for use in this implementation:
Devicehub with URL (http://localhost:5000) is the identity provider of OIDC and have a user defined in **.env** file with SERVER_ID_EMAIL_DEMO var.
Devicehub with URL (http://localhost:5001) is the client identity of OIDC and have a user defined in **.env** file with SERVER_ID_EMAIL_DEMO var.
You can change these values in the *.env* file
7. If you want to use Workbench for these DeviceHub instances, you need to go to
```
http://localhost:5001/workbench/
```
with the demo user and then download the settings and ISO files. Follow the instructions on the [help](https://help.usody.com/en/setup/setup-pendrive/) page.

View File

@ -1,159 +0,0 @@
Devicehub
#########
Devicehub is a distributed IT Asset Management System focused in reusing
devices, created under the project
`eReuse.org <https://www.ereuse.org>`__.
This README explains how to install and use Devicehub.
`The documentation <http://devicehub.ereuse.org>`_ explains the concepts
and the API.
Devicehub is built with `Teal <https://github.com/ereuse/teal>`__ and
`Flask <http://flask.pocoo.org>`__.
Installing
**********
The requirements are:
- Python 3.7.3 or higher. In debian 10 is ``# apt install python3``.
- `PostgreSQL 11 or higher <https://www.postgresql.org/download/>`__.
- Weasyprint
`dependencies <http://weasyprint.readthedocs.io/en/stable/install.html>`__.
Install Devicehub with *pip*:
``pip3 install -U -r requirements.txt -e .``.
Running
*******
Create a PostgreSQL database called *devicehub* by running
`create-db <examples/create-db.sh>`__:
- In Linux, execute the following two commands (adapt them to your distro):
1. ``sudo su - postgres``.
2. ``bash examples/create-db.sh devicehub dhub``, and password
``ereuse``.
- In MacOS: ``bash examples/create-db.sh devicehub dhub``, and password
``ereuse``.
Configure project using environment file (you can use provided example as quickstart):
.. code:: bash
$ cp examples/env.example .env
Using the `dh` tool for set up with one or multiple inventories.
Create the tables in the database by executing:
.. code:: bash
$ export dhi=dbtest; dh inv add --common --name dbtest
Finally, run the app:
.. code:: bash
$ export dhi=dbtest;dh run --debugger
The error bdist_wheel can happen when you work with a *virtual environment*.
To fix it, install in the *virtual environment* wheel
package. ``pip3 install wheel``
Multiple instances
------------------
Devicehub can run as a single inventory or with multiple inventories,
each inventory being an instance of the ``devicehub``. To add a new inventory
execute:
.. code:: bash
$ export dhi=dbtest; dh inv add --name dbtest
Note: The ``dh`` command is like ``flask``, but
it allows you to create and delete instances, and interface to them
directly.
Testing
*******
1. ``git clone`` this project.
2. Create a database for testing executing ``create-db.sh`` like the
normal installation but changing the first parameter from
``devicehub`` to ``dh_test``: ``create-db.sh dh_test dhub`` and
password ``ereuse``.
3. Execute at the root folder of the project ``python3 setup.py test``.
Migrations
**********
At this stage, migration files are created manually.
Set up the database:
.. code:: bash
$ sudo su - postgres
$ bash $PATH_TO_DEVIHUBTEAL/examples/create-db.sh devicehub dhub
Initialize the database:
.. code:: bash
$ export dhi=dbtest; dh inv add --common --name dbtest
This command will create the schemas, tables in the specified database.
Then we need to stamp the initial migration.
.. code:: bash
$ alembic stamp head
This command will set the revision **fbb7e2a0cde0_initial** as our initial migration.
For more info in migration stamping please see https://alembic.sqlalchemy.org/en/latest/cookbook.html
Whenever a change needed eg to create a new schema, alter an existing table, column or perform any
operation on tables, create a new revision file:
.. code:: bash
$ alembic revision -m "A table change"
This command will create a new revision file with name `<revision_id>_a_table_change`.
Edit the generated file with the necessary operations to perform the migration:
.. code:: bash
$ alembic edit <revision_id>
Apply migrations using:
.. code:: bash
$ alembic -x inventory=dbtest upgrade head
Then to go back to previous db version:
.. code:: bash
$ alembic -x inventory=dbtest downgrade <revision_id>
To see a full list of migrations use
.. code:: bash
$ alembic history
Generating the docs
*******************
1. ``git clone`` this project.
2. Install plantuml. In Debian 9 is ``# apt install plantuml``.
3. Execute ``pip3 install -e .[docs]`` in the project root folder.
4. Go to ``<project root folder>/docs`` and execute ``make html``.
Repeat this step to generate new docs.
To auto-generate the docs do ``pip3 install -e .[docs-auto]``, then
execute, in the root folder of the project
``sphinx-autobuild docs docs/_build/html``.

View File

@ -0,0 +1,187 @@
# Devicehub
Devicehub is a distributed IT Asset Management System focused in reusing devices, created under the project [eReuse.org](https://www.ereuse.org)
This README explains how to install and use Devicehub. [The documentation](http://devicehub.ereuse.org) explains the concepts and the API.
Devicehub is built with [Teal](https://github.com/ereuse/teal) and [Flask](http://flask.pocoo.org).
# Installing
The requirements are:
0. Required
- python3.9
- [PostgreSQL 11 or higher](https://www.postgresql.org/download/).
- Weasyprint [dependencie](http://weasyprint.readthedocs.io/en/stable/install.html)
1. Generate a clone of the repository.
```
git clone git@github.com:eReuse/devicehub-teal.git -b oidc4vp
cd devicehub-teal
```
2. Create a virtual environment and install Devicehub with *pip*.
```
python3.9 -m venv env
source env/bin/activate
sh examples/pip_install.sh
```
3. Create a PostgreSQL database called *devicehub* by running [create-db](examples/create-db.sh):
- In Linux, execute the following two commands (adapt them to your distro):
1. `sudo su - postgres`.
2. `bash examples/create-db.sh devicehub dhub`, and password `ereuse`.
- In MacOS: `bash examples/create-db.sh devicehub dhub`, and password `ereuse`.
Configure project using environment file (you can use provided example as quickstart):
```bash
$ cp examples/env.example .env
```
You can use these parameters as default for a local test, but default values may not be suitable for an internet-exposed service for security reasons. However, these six variables need to be initialized:
```
API_DLT
API_DLT_TOKEN
API_RESOLVER
ABAC_TOKEN
ABAC_USER
ABAC_URL
```
These values should come from an already operational [API_DLT connector](https://gitlab.com/dsg-upc/ereuse-dpp) service instance.
4. Running alembic from oidc module.
```
alembic -x inventory=dbtest upgrade head
```
5. Running alembic from oidc module.
```
cd ereuse_devicehub/modules/oidc
alembic -x inventory=dbtest upgrade head
```
6. Running alembic from dpp module.
```
cd ereuse_devicehub/modules/dpp/
alembic -x inventory=dbtest upgrade head
```
7. Add a suitable app.py file.
```
cp examples/app.py .
```
8. Generate a minimal data structure.
```
flask initdata
```
9. Add a new server to the 'api resolver' to be able to integrate it into the federation.
The domain name for this new server has to be unique. When installing two instances their domain name must differ: e.g. dpp.mydomain1.cxm, dpp.mydomain2.cxm.
If your domain is dpp.mydomain.cxm:
```
flask dlt_insert_members http://dpp.mydomain.cxm
```
modify the .env file as indicated in point 3.
Add the corresponding 'DH' in ID_FEDERATED.
example: ID_FEDERATED='DH10'
10. Do a rsync api resolve.
```
flask dlt_rsync_members
```
11. Register a new user in devicehub.
```
flask adduser email@example.org password
```
12. Register a new user to the DLT.
```
flask dlt_register_user examples/users_devicehub.json
```
You need define your users in the file **users_devicehub.json**
13. Finally, run the app:
```bash
$ flask run --debugger
```
The error bdist_wheel can happen when you work with a *virtual environment*.
To fix it, install in the *virtual environment* wheel
package. `pip3 install wheel`
# Testing
1. `git clone` this project.
2. Create a database for testing executing `create-db.sh` like the normal installation but changing the first parameter from `devicehub` to `dh_test`: `create-db.sh dh_test dhub` and password `ereuse`.
3. Execute at the root folder of the project `python3 setup.py test`.
# Upgrade a deployment
For upgrade an instance of devicehub you need to do:
```bash
$ cd $PATH_TO_DEVIHUBTEAL
$ source venv/bin/activate
$ git pull
$ alembic -x inventory=dbtest upgrade head
```
If all migrations pass successfully, then it is necessary restart the devicehub.
Normaly you can use a little script for restart or run.
```
# systemctl stop gunicorn_devicehub.socket
# systemctl stop gunicorn_devicehub.service
# systemctl start gunicorn_devicehub.service
```
# OpenId Connect:
We want to interconnect two devicehub instances already installed. One has a set of devices (OIDC client), the other has a set of users (OIDC identity server). Let's assume their domains are: dpp.mydomain1.cxm, dpp.mydomain2.cxm
20. In order to connect the two devicehub instances, it is necessary:
* 20.1. Register a user in the devicehub instance acting as OIDC identity server.
* 20.2. Fill in the openid connect form.
* 20.3. Add in the OIDC client inventory the data of client_id, client_secret.
For 20.1. This can be achieved on the terminal on the devicehub instance acting as OIDC identity server.
```
flask adduser email@example.org password
```
* 20.2. This is an example of how to fill in the form.
In the web interface of the OIDC identity service, click on the profile of the just added user, select "My Profile" and click on "OpenID Connect":
Then we can go to the "OpenID Connect" panel and fill out the form:
The important thing about this form is:
* "Client URL" The URL of the OIDC Client instance, as registered in point 12. dpp.mydomain1.cxm in our example.
* "Allowed Scope" has to have these three words:
```
openid profile rols
```
* "Redirect URIs" it has to be the URL that was put in "Client URL" plus "/allow_code"
* "Allowed Grant Types" has to be "authorization_code"
* "Allowed Response Types" has to be "code"
* "Token Endpoint Auth Method" has to be "Client Secret Basic"
After clicking on "Submit" the "OpenID Connect" tab of the user profile should now include details for "client_id" and "client_secret".
* 20.3. In the OIDC client inventory run: (in our example: url_domain is dpp.mydomain2.cxm, client_id and client_secret as resulting from the previous step)
```
flask add_client_oidc url_domain client_id client_secret
```
After this step, both servers must be connected. Opening one DPP page on dpp.mydomain1.cxm (OIDC Client) the user can choose to authenticate using dpp.mydomain2.cxm (OIDC Server).
## Generating the docs
1. `git clone` this project.
2. Install plantuml. In Debian 9 is `# apt install plantuml`.
3. Execute `pip3 install -e .[docs]` in the project root folder.
4. Go to `<project root folder>/docs` and execute `make html`. Repeat this step to generate new docs.
To auto-generate the docs do `pip3 install -e .[docs-auto]`, then execute, in the root folder of the project `sphinx-autobuild docs docs/_build/html`.

49
development-setup.md Executable file
View File

@ -0,0 +1,49 @@
# Setup developement project
## Installing
complete this steps from [README - Installing](README.md#installing)
## Setup project
Create a PostgreSQL database called devicehub by running [create-db](examples/create-db.sh):
- Start postgresDB
- `bash examples/create-db.sh devicehub dhub, and password ereuse.`
- `cp examples/env.example .env`
Create a secretkey and add into `.env`
```bash
echo "SECRET_KEY=$(python3 -c 'import secrets; print(secrets.token_hex())')" >> .env
```
Using the dh tool for set up with one or multiple inventories. Create the tables in the database by executing:
```bash
export dhi=dbtest; dh inv add --common --name dbtest
```
Create a demo table
```bash
export dhi=dbtest; dh dummy
```
## Run project
Run the app
```bash
export FLASK_APP=app.py; export FLASK_ENV=development; flask run --debugger
```
Finally login into `localhost:5000/login/`
- User: user@dhub.com
- Pass: 1234
## Troubleshooting
- If when execute dh command it thows an error, install this dependencies in your distro
- `sudo apt install -y libpango1.0-0 libcairo2 libpq-dev`

1
docker-compose.yml Symbolic link
View File

@ -0,0 +1 @@
docker-compose_devicehub-dpp.yml

View File

@ -0,0 +1,103 @@
version: "3.9"
services:
devicehub-id-server:
init: true
image: dkr-dsg.ac.upc.edu/ereuse/devicehub:latest
environment:
- DB_USER=${DB_USER}
- DB_PASSWORD=${DB_PASSWORD}
- DB_HOST=postgres-id-server
- DB_DATABASE=${DB_DATABASE}
- HOST=${HOST}
- EMAIL_DEMO=${SERVER_ID_EMAIL_DEMO}
- PASSWORD_DEMO=${PASSWORD_DEMO}
- JWT_PASS=${JWT_PASS}
- SECRET_KEY=${SECRET_KEY}
- API_DLT=${API_DLT}
- API_RESOLVER=${API_RESOLVER}
- API_DLT_TOKEN=${API_DLT_TOKEN}
- DEVICEHUB_HOST=${SERVER_ID_DEVICEHUB_HOST}
- ID_FEDERATED=${SERVER_ID_FEDERATED}
- URL_MANUALS=${URL_MANUALS}
- ID_SERVICE=${SERVER_ID_SERVICE}
- AUTHORIZED_CLIENT_URL=${CLIENT_ID_DEVICEHUB_HOST}
- DPP_MODULE=y
- IMPORT_SNAPSHOTS=${IMPORT_SNAPSHOTS}
ports:
- 5000:5000
volumes:
- ${SNAPSHOTS_PATH:-./examples/snapshots}:/mnt/snapshots:ro
- shared:/shared:rw
- app_id_server:/opt/devicehub:rw
postgres-id-server:
image: dkr-dsg.ac.upc.edu/ereuse/postgres:latest
# 4. To create the database.
# 5. Give permissions to the corresponding users in the database.
# extra src https://github.com/docker-library/docs/blob/master/postgres/README.md#environment-variables
environment:
- POSTGRES_PASSWORD=${DB_PASSWORD}
- POSTGRES_USER=${DB_USER}
- POSTGRES_DB=${DB_DATABASE}
# DEBUG
#ports:
# - 5432:5432
# TODO persistence
#volumes:
# - pg_data:/var/lib/postgresql/data
devicehub-id-client:
init: true
image: dkr-dsg.ac.upc.edu/ereuse/devicehub:latest
environment:
- DB_USER=${DB_USER}
- DB_PASSWORD=${DB_PASSWORD}
- DB_HOST=postgres-id-client
- DB_DATABASE=${DB_DATABASE}
- HOST=${HOST}
- EMAIL_DEMO=${CLIENT_ID_EMAIL_DEMO}
- PASSWORD_DEMO=${PASSWORD_DEMO}
- JWT_PASS=${JWT_PASS}
- SECRET_KEY=${SECRET_KEY}
- API_DLT=${API_DLT}
- API_RESOLVER=${API_RESOLVER}
- API_DLT_TOKEN=${API_DLT_TOKEN}
- DEVICEHUB_HOST=${CLIENT_ID_DEVICEHUB_HOST}
- SERVER_ID_HOST=${SERVER_ID_DEVICEHUB_HOST}
- ID_FEDERATED=${CLIENT_ID_FEDERATED}
- URL_MANUALS=${URL_MANUALS}
- ID_SERVICE=${CLIENT_ID_SERVICE}
- DPP_MODULE=y
- IMPORT_SNAPSHOTS=${IMPORT_SNAPSHOTS}
ports:
- 5001:5000
volumes:
- ${SNAPSHOTS_PATH:-./examples/snapshots}:/mnt/snapshots:ro
- shared:/shared:ro
- app_id_client:/opt/devicehub:rw
postgres-id-client:
image: dkr-dsg.ac.upc.edu/ereuse/postgres:latest
# 4. To create the database.
# 5. Give permissions to the corresponding users in the database.
# extra src https://github.com/docker-library/docs/blob/master/postgres/README.md#environment-variables
environment:
- POSTGRES_PASSWORD=${DB_PASSWORD}
- POSTGRES_USER=${DB_USER}
- POSTGRES_DB=${DB_DATABASE}
# DEBUG
#ports:
# - 5432:5432
# TODO persistence
#volumes:
# - pg_data:/var/lib/postgresql/data
# TODO https://testdriven.io/blog/dockerizing-django-with-postgres-gunicorn-and-nginx/
#nginx
volumes:
shared:
app_id_client:
app_id_server:

View File

@ -0,0 +1,54 @@
version: "3.9"
services:
devicehub:
init: true
image: dkr-dsg.ac.upc.edu/ereuse/devicehub:dpp__c6ec6658
environment:
- DB_USER=${DB_USER}
- DB_PASSWORD=${DB_PASSWORD}
- DB_HOST=postgres
- DB_DATABASE=${DB_DATABASE}
- HOST=${HOST}
- EMAIL_DEMO=${EMAIL_DEMO}
- PASSWORD_DEMO=${PASSWORD_DEMO}
- JWT_PASS=${JWT_PASS}
- SECRET_KEY=${SECRET_KEY}
- DEVICEHUB_HOST=${DEVICEHUB_HOST}
- URL_MANUALS=${URL_MANUALS}
- DPP_MODULE=n
- IMPORT_SNAPSHOTS=${IMPORT_SNAPSHOTS}
- DEPLOYMENT=${DEPLOYMENT}
ports:
- 5000:5000
volumes:
- ${SNAPSHOTS_PATH:-./examples/snapshots}:/mnt/snapshots:ro
- shared:/shared:rw
- app:/opt/devicehub:rw
postgres:
image: dkr-dsg.ac.upc.edu/ereuse/postgres:dpp__c6ec6658
# 4. To create the database.
# 5. Give permissions to the corresponding users in the database.
# extra src https://github.com/docker-library/docs/blob/master/postgres/README.md#environment-variables
environment:
- POSTGRES_PASSWORD=${DB_PASSWORD}
- POSTGRES_USER=${DB_USER}
- POSTGRES_DB=${DB_DATABASE}
volumes:
- pg_data:/var/lib/postgresql/data
# DEBUG
#ports:
# - 5432:5432
nginx:
image: nginx
ports:
- 8080:8080
volumes:
- ./docker/nginx-devicehub.nginx.conf:/etc/nginx/nginx.conf:ro
volumes:
shared:
pg_data:
app:

View File

@ -0,0 +1,32 @@
FROM debian:bullseye-slim
RUN apt update && apt-get install --no-install-recommends -y \
python3-minimal \
python3-pip \
python-is-python3 \
python3-psycopg2 \
python3-dev \
libpq-dev \
build-essential \
libpangocairo-1.0-0 \
curl \
jq \
time \
netcat
WORKDIR /opt/devicehub
# this is exactly the same as examples/pip_install.sh except the last command
# to improve the docker layer builds, it has been separated
RUN pip install --upgrade pip
RUN pip install alembic==1.8.1 anytree==2.8.0 apispec==0.39.0 atomicwrites==1.4.0 blinker==1.5 boltons==23.0.0 cairocffi==1.4.0 cairosvg==2.5.2 certifi==2022.9.24 cffi==1.15.1 charset-normalizer==2.0.12 click==6.7 click-spinner==0.1.8 colorama==0.3.9 colour==0.1.5 cssselect2==0.7.0 defusedxml==0.7.1 et-xmlfile==1.1.0 flask==1.0.2 flask-cors==3.0.10 flask-login==0.5.0 flask-sqlalchemy==2.5.1 flask-weasyprint==0.4 flask-wtf==1.0.0 hashids==1.2.0 html5lib==1.1 idna==3.4 inflection==0.5.1 itsdangerous==2.0.1 jinja2==3.0.3 mako==1.2.3 markupsafe==2.1.1 marshmallow==3.0.0b11 marshmallow-enum==1.4.1 more-itertools==8.12.0 numpy==1.22.0 odfpy==1.4.1 openpyxl==3.0.10 pandas==1.3.5 passlib==1.7.1 phonenumbers==8.9.11 pillow==9.2.0 pint==0.9 psycopg2-binary==2.8.3 py-dmidecode==0.1.0 pycparser==2.21 pyjwt==2.4.0 pyphen==0.13.0 python-dateutil==2.7.3 python-decouple==3.3 python-dotenv==0.14.0 python-editor==1.0.4 python-stdnum==1.9 pytz==2022.2.1 pyyaml==5.4 requests==2.27.1 requests-mock==1.5.2 requests-toolbelt==0.9.1 six==1.16.0 sortedcontainers==2.1.0 sqlalchemy==1.3.24 sqlalchemy-citext==1.3.post0 sqlalchemy-utils==0.33.11 tinycss2==1.1.1 tqdm==4.32.2 urllib3==1.26.12 weasyprint==44 webargs==5.5.3 webencodings==0.5.1 werkzeug==2.0.3 wtforms==3.0.1 xlrd==2.0.1 cryptography==39.0.1 Authlib==1.2.1 gunicorn==21.2.0
RUN pip install -i https://test.pypi.org/simple/ ereuseapitest==0.0.14
COPY . .
# this operation might be overriding inside container another app.py you would have
COPY examples/app.py .
RUN pip install -e .
COPY docker/devicehub.entrypoint.sh /
ENTRYPOINT sh /devicehub.entrypoint.sh

View File

@ -0,0 +1,12 @@
.git
.env
# TODO need to comment it to copy the entrypoint
#docker
Makefile
# Emacs backup files
*~
.\#*
# Vim swap files
*.swp
*.swo

228
docker/devicehub.entrypoint.sh Executable file
View File

@ -0,0 +1,228 @@
#!/bin/sh
set -e
set -u
# DEBUG
set -x
# 3. Generate an environment .env file.
gen_env_vars() {
CONFIG_OIDC="${CONFIG_OIDC:-y}"
# specific dpp env vars
if [ "${DPP_MODULE}" = 'y' ]; then
dpp_env_vars="$(cat <<END
API_DLT='${API_DLT}'
API_DLT_TOKEN='${API_DLT_TOKEN}'
API_RESOLVER='${API_RESOLVER}'
ID_FEDERATED='${ID_FEDERATED}'
END
)"
fi
# generate config using env vars from docker
cat > .env <<END
${dpp_env_vars:-}
DB_USER='${DB_USER}'
DB_PASSWORD='${DB_PASSWORD}'
DB_HOST='${DB_HOST}'
DB_DATABASE='${DB_DATABASE}'
URL_MANUALS='${URL_MANUALS}'
HOST='${HOST}'
SCHEMA='dbtest'
DB_SCHEMA='dbtest'
EMAIL_DEMO='${EMAIL_DEMO}'
PASSWORD_DEMO='${PASSWORD_DEMO}'
JWT_PASS=${JWT_PASS}
SECRET_KEY=${SECRET_KEY}
END
}
wait_for_postgres() {
# old one was
#sleep 4
default_postgres_port=5432
# thanks https://testdriven.io/blog/dockerizing-django-with-postgres-gunicorn-and-nginx/
while ! nc -z ${DB_HOST} ${default_postgres_port}; do
sleep 0.5
done
}
init_data() {
# 7. Run alembic of the project.
alembic -x inventory=dbtest upgrade head
# 8. Running alembic from oidc module.y
cd ereuse_devicehub/modules/oidc
alembic -x inventory=dbtest upgrade head
cd -
# 9. Running alembic from dpp module.
cd ereuse_devicehub/modules/dpp/
alembic -x inventory=dbtest upgrade head
cd -
# 11. Generate a minimal data structure.
# TODO it has some errors (?)
flask initdata || true
if [ "${EREUSE_PILOT:-}" = 'y' ]; then
flask dlt_register_user /opt/devicehub/users_devicehub.json || true
fi
}
big_error() {
local message="${@}"
echo "###############################################" >&2
echo "# ERROR: ${message}" >&2
echo "###############################################" >&2
exit 1
}
handle_federated_id() {
# devicehub host and id federated checker
# //getAll queries are not accepted by this service, so we remove them
EXPECTED_ID_FEDERATED="$(curl -s "${API_RESOLVER%/}/getAll" \
| jq -r '.url | to_entries | .[] | select(.value == "'"${DEVICEHUB_HOST}"'") | .key' \
| head -n 1)"
# if is a new DEVICEHUB_HOST, then register it
if [ -z "${EXPECTED_ID_FEDERATED}" ]; then
# TODO better docker compose run command
cmd="docker compose run --entrypoint= devicehub flask dlt_insert_members ${DEVICEHUB_HOST}"
big_error "No FEDERATED ID maybe you should run \`${cmd}\`"
fi
# if not new DEVICEHUB_HOST, then check consistency
# if there is already an ID in the DLT, it should match with my internal ID
if [ ! "${EXPECTED_ID_FEDERATED}" = "${ID_FEDERATED}" ]; then
big_error "ID_FEDERATED should be ${EXPECTED_ID_FEDERATED} instead of ${ID_FEDERATED}"
fi
# not needed, but reserved
# EXPECTED_DEVICEHUB_HOST="$(curl -s "${API_RESOLVER%/}/getAll" \
# | jq -r '.url | to_entries | .[] | select(.key == "'"${ID_FEDERATED}"'") | .value' \
# | head -n 1)"
# if [ ! "${EXPECTED_DEVICEHUB_HOST}" = "${DEVICEHUB_HOST}" ]; then
# big_error "ERROR: DEVICEHUB_HOST should be ${EXPECTED_DEVICEHUB_HOST} instead of ${DEVICEHUB_HOST}"
# fi
}
config_oidc() {
# TODO test allowing more than 1 client
if [ "${ID_SERVICE}" = "server_id" ]; then
client_description="client identity from docker compose demo"
# in AUTHORIZED_CLIENT_URL we remove anything before ://
flask add_contract_oidc \
"${EMAIL_DEMO}" \
"${client_description}" \
"${AUTHORIZED_CLIENT_URL}" \
> /shared/client_id_${AUTHORIZED_CLIENT_URL#*://}
elif [ "${ID_SERVICE}" = "client_id" ]; then
# in DEVICEHUB_HOST we remove anything before ://
client_id_config="/shared/client_id_${DEVICEHUB_HOST#*://}"
client_id=
client_secret=
# wait that the file generated by the server_id is readable
while true; do
if [ -f "${client_id_config}" ]; then
client_id="$(cat "${client_id_config}" | jq -r '.client_id')"
client_secret="$(cat "${client_id_config}" | jq -r '.client_secret')"
if [ "${client_id}" ] && [ "${client_secret}" ]; then
break
fi
fi
sleep 1
done
flask add_client_oidc \
"${SERVER_ID_HOST}" \
"${client_id}" \
"${client_secret}"
else
big_error "Something went wrong ${ID_SERVICE} is not server_id nor client_id"
fi
}
config_dpp_part1() {
# 12. Add a new server to the 'api resolver'
handle_federated_id
# 13. Do a rsync api resolve
flask dlt_rsync_members
# 14. Register a new user to the DLT
#flask dlt_register_user "${EMAIL_DEMO}" ${PASSWORD_DEMO} Operator
}
config_phase() {
init_flagfile='docker__already_configured'
if [ ! -f "${init_flagfile}" ]; then
# 7, 8, 9, 11
init_data
if [ "${DPP_MODULE}" = 'y' ]; then
# 12, 13, 14
config_dpp_part1
fi
# non DL user (only for the inventory)
# flask adduser user2@dhub.com ${PASSWORD_DEMO}
# # 15. Add inventory snapshots for user "${EMAIL_DEMO}".
if [ "${IMPORT_SNAPSHOTS}" = 'y' ]; then
mkdir -p ereuse_devicehub/commands/snapshot_files
cp /mnt/snapshots/snapshot*.json ereuse_devicehub/commands/snapshot_files/
/usr/bin/time flask snapshot "${EMAIL_DEMO}" ${PASSWORD_DEMO}
fi
if [ "${CONFIG_OIDC}" = 'y' ]; then
# 16.
# commented because this fails with wrong DLT credentials
#flask check_install "${EMAIL_DEMO}" "${PASSWORD_DEMO}"
# 20. config server or client ID
config_oidc
fi
# remain next command as the last operation for this if conditional
touch "${init_flagfile}"
fi
}
main() {
gen_env_vars
wait_for_postgres
config_phase
# 17. Use gunicorn
# thanks https://akira3030.github.io/formacion/articulos/python-flask-gunicorn-docker.html
if [ "${DEPLOYMENT:-}" = "PROD" ]; then
# TODO workers 1 because we have a shared secret in RAM
gunicorn --access-logfile - --error-logfile - --workers 1 -b :5000 app:app
else
# run development server
FLASK_DEBUG=1 flask run --host=0.0.0.0 --port 5000
fi
# DEBUG
#sleep infinity
}
main "${@}"

View File

@ -0,0 +1,32 @@
user www-data;
worker_processes auto;
pid /run/nginx.pid;
error_log /var/log/nginx/error.log;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
# multi_accept on;
}
http {
#upstream socket_backend {
# server unix:/socket/gunicorn.sock fail_timeout=0;
#}
server {
listen 8080;
listen [::]:8080;
#server_name devicehub.example.org;
location / {
# TODO env var on proxy_pass
proxy_pass http://devicehub:5000/;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
}
}
}

View File

@ -0,0 +1,8 @@
FROM postgres:15.4-bookworm
# this is the latest in 2023-09-14_13-01-38
#FROM postgres:latest
# Add a SQL script that will be executed upon container startup
COPY docker/postgres.setupdb.sql /docker-entrypoint-initdb.d/
EXPOSE 5432

View File

@ -0,0 +1,5 @@
-- 6. Create the necessary extensions.
CREATE EXTENSION pgcrypto SCHEMA public;
CREATE EXTENSION ltree SCHEMA public;
CREATE EXTENSION citext SCHEMA public;
CREATE EXTENSION pg_trgm SCHEMA public;

View File

@ -30,7 +30,6 @@ from teal.enums import Country, Currency, Layouts, Subdivision
from teal.marshmallow import EnumField from teal.marshmallow import EnumField
from ereuse_devicehub.marshmallow import NestedOn from ereuse_devicehub.marshmallow import NestedOn
from ereuse_devicehub.resources.schemas import Thing
project = 'Devicehub' project = 'Devicehub'
copyright = '2020, eReuse.org team' copyright = '2020, eReuse.org team'
@ -56,7 +55,7 @@ extensions = [
'sphinx.ext.viewcode', 'sphinx.ext.viewcode',
'sphinxcontrib.plantuml', 'sphinxcontrib.plantuml',
'sphinx.ext.autosectionlabel', 'sphinx.ext.autosectionlabel',
'sphinx.ext.autodoc' 'sphinx.ext.autodoc',
] ]
# Add any paths that contain templates here, relative to this directory. # Add any paths that contain templates here, relative to this directory.
@ -126,15 +125,12 @@ latex_elements = {
# The paper size ('letterpaper' or 'a4paper'). # The paper size ('letterpaper' or 'a4paper').
# #
# 'papersize': 'letterpaper', # 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt'). # The font size ('10pt', '11pt' or '12pt').
# #
# 'pointsize': '10pt', # 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble. # Additional stuff for the LaTeX preamble.
# #
# 'preamble': '', # 'preamble': '',
# Latex figure (float) alignment # Latex figure (float) alignment
# #
# 'figure_align': 'htbp', # 'figure_align': 'htbp',
@ -144,18 +140,20 @@ latex_elements = {
# (source start file, target name, title, # (source start file, target name, title,
# author, documentclass [howto, manual, or own class]). # author, documentclass [howto, manual, or own class]).
latex_documents = [ latex_documents = [
(master_doc, 'Devicehub.tex', 'Devicehub Documentation', (
'eReuse.org team', 'manual'), master_doc,
'Devicehub.tex',
'Devicehub Documentation',
'eReuse.org team',
'manual',
),
] ]
# -- Options for manual page output ------------------------------------------ # -- Options for manual page output ------------------------------------------
# One entry per manual page. List of tuples # One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section). # (source start file, name, description, authors, manual section).
man_pages = [ man_pages = [(master_doc, 'devicehub', 'Devicehub Documentation', [author], 1)]
(master_doc, 'devicehub', 'Devicehub Documentation',
[author], 1)
]
# -- Options for Texinfo output ---------------------------------------------- # -- Options for Texinfo output ----------------------------------------------
@ -163,9 +161,15 @@ man_pages = [
# (source start file, target name, title, author, # (source start file, target name, title, author,
# dir menu entry, description, category) # dir menu entry, description, category)
texinfo_documents = [ texinfo_documents = [
(master_doc, 'Devicehub', 'Devicehub Documentation', (
author, 'Devicehub', 'One line description of project.', master_doc,
'Miscellaneous'), 'Devicehub',
'Devicehub Documentation',
author,
'Devicehub',
'One line description of project.',
'Miscellaneous',
),
] ]
# -- Extension configuration ------------------------------------------------- # -- Extension configuration -------------------------------------------------
@ -199,6 +203,7 @@ class DhlistDirective(Directive):
This requires :py:class:`ereuse_devicehub.resources.schemas.SchemaMeta`. This requires :py:class:`ereuse_devicehub.resources.schemas.SchemaMeta`.
You will find in that module more information. You will find in that module more information.
""" """
has_content = False has_content = False
# Definition of passed-in options # Definition of passed-in options
@ -216,7 +221,7 @@ class DhlistDirective(Directive):
sections = [] sections = []
sections.append(self.links(things)) # Make index sections.append(self.links(things)) # Make index
for thng in things: # type: Thing for thng in things:
# Generate a section for each class, with a title, # Generate a section for each class, with a title,
# fields description and a paragraph # fields description and a paragraph
section = n.section(ids=[self._id(thng)]) section = n.section(ids=[self._id(thng)])
@ -228,7 +233,9 @@ class DhlistDirective(Directive):
for key, f in thng._own: for key, f in thng._own:
name = n.field_name(text=f.data_key or key) name = n.field_name(text=f.data_key or key)
body = [ body = [
self.parse('{} {}'.format(self.type(f), f.metadata.get('description', ''))) self.parse(
'{} {}'.format(self.type(f), f.metadata.get('description', ''))
)
] ]
if isinstance(f, EnumField): if isinstance(f, EnumField):
body.append(self._parse_enum_field(f)) body.append(self._parse_enum_field(f))
@ -244,6 +251,7 @@ class DhlistDirective(Directive):
def _parse_enum_field(self, f): def _parse_enum_field(self, f):
from ereuse_devicehub.resources.device import states from ereuse_devicehub.resources.device import states
if issubclass(f.enum, (Subdivision, Currency, Country, Layouts, states.State)): if issubclass(f.enum, (Subdivision, Currency, Country, Layouts, states.State)):
return self.parse(f.enum.__doc__) return self.parse(f.enum.__doc__)
else: else:
@ -298,7 +306,7 @@ class DhlistDirective(Directive):
def parse(self, text) -> n.container: def parse(self, text) -> n.container:
"""Parses text possibly containing ReST stuff and adds it in """Parses text possibly containing ReST stuff and adds it in
a node.""" a node."""
p = n.container('') p = n.container('')
self.state.nested_parse(StringList(string2lines(inspect.cleandoc(text))), 0, p) self.state.nested_parse(StringList(string2lines(inspect.cleandoc(text))), 0, p)
return p return p

View File

@ -9,6 +9,12 @@ dags-with-materialized-paths-using-postgres-ltree/>`_ you have
a low-level technical implementation of how lots and their a low-level technical implementation of how lots and their
relationships are mapped. relationships are mapped.
Getting lots
************
You can get lots list by ``GET /lots/``
There are one optional filter ``type``, only works with this 3 values ``temporary``, ``incoming`` and ``outgoing``
Create lots Create lots
*********** ***********
You create a lot by ``POST /lots/`` a `JSON Lot object <https:// You create a lot by ``POST /lots/`` a `JSON Lot object <https://
@ -28,7 +34,6 @@ And for devices is all the same:
``POST /lots/<parent-lot-id>/devices/?id=<device-id-1>&id=<device-id-2>``; ``POST /lots/<parent-lot-id>/devices/?id=<device-id-1>&id=<device-id-2>``;
idem for removing devices. idem for removing devices.
Sharing lots Sharing lots
************ ************
Sharing a lot means giving certain permissions to users, like reading Sharing a lot means giving certain permissions to users, like reading

View File

@ -1 +1 @@
__version__ = "2.1.0.dev" __version__ = "2.5.3"

View File

View File

@ -0,0 +1,113 @@
import json
from binascii import Error as asciiError
from flask import Blueprint
from flask import current_app as app
from flask import g, jsonify, request
from flask.views import View
from flask.wrappers import Response
from marshmallow.exceptions import ValidationError
from werkzeug.exceptions import Unauthorized
from ereuse_devicehub.auth import Auth
from ereuse_devicehub.db import db
from ereuse_devicehub.parser.models import SnapshotsLog
from ereuse_devicehub.parser.parser import ParseSnapshotLsHw
from ereuse_devicehub.parser.schemas import Snapshot_lite
from ereuse_devicehub.resources.action.views.snapshot import (
SnapshotMixin,
move_json,
save_json,
)
from ereuse_devicehub.resources.enums import Severity
api = Blueprint('api', __name__, url_prefix='/api')
class LoginMixin(View):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.authenticate()
def authenticate(self):
unauthorized = Unauthorized('Provide a suitable token.')
basic_token = request.headers.get('Authorization', " ").split(" ")
if not len(basic_token) == 2:
raise unauthorized
token = basic_token[1]
try:
token = Auth.decode(token)
except asciiError:
raise unauthorized
self.user = Auth().authenticate(token)
g.user = self.user
class InventoryView(LoginMixin, SnapshotMixin):
methods = ['POST']
def dispatch_request(self):
snapshot_json = json.loads(request.data)
self.tmp_snapshots = app.config['TMP_SNAPSHOTS']
self.path_snapshot = save_json(snapshot_json, self.tmp_snapshots, g.user.email)
snapshot_json = self.validate(snapshot_json)
if type(snapshot_json) == Response:
return snapshot_json
self.snapshot_json = ParseSnapshotLsHw(snapshot_json).get_snapshot()
snapshot = self.build()
snapshot.device.set_hid()
snapshot.device.binding.device.set_hid()
db.session.add(snapshot)
snap_log = SnapshotsLog(
description='Ok',
snapshot_uuid=snapshot.uuid,
severity=Severity.Info,
sid=snapshot.sid,
version=str(snapshot.version),
snapshot=snapshot,
)
snap_log.save()
db.session().final_flush()
db.session.commit()
url = "https://{}/".format(app.config['HOST'])
public_url = "{}{}".format(url.strip("/"), snapshot.device.url.to_text())
self.response = jsonify(
{
'dhid': snapshot.device.dhid,
'url': url,
'public_url': public_url,
}
)
self.response.status_code = 201
move_json(self.tmp_snapshots, self.path_snapshot, g.user.email)
return self.response
def validate(self, snapshot_json):
self.schema = Snapshot_lite()
try:
return self.schema.load(snapshot_json)
except ValidationError as err:
txt = "{}".format(err)
uuid = snapshot_json.get('uuid')
sid = snapshot_json.get('sid')
version = snapshot_json.get('version')
error = SnapshotsLog(
description=txt,
snapshot_uuid=uuid,
severity=Severity.Error,
sid=sid,
version=str(version),
)
error.save(commit=True)
# raise err
self.response = jsonify(err)
self.response.status_code = 400
return self.response
api.add_url_rule('/inventory/', view_func=InventoryView.as_view('inventory'))

View File

@ -1,9 +1,9 @@
from sqlalchemy.exc import DataError from sqlalchemy.exc import DataError
from teal.auth import TokenAuth
from teal.db import ResourceNotFound
from werkzeug.exceptions import Unauthorized from werkzeug.exceptions import Unauthorized
from ereuse_devicehub.resources.user.models import User, Session from ereuse_devicehub.resources.user.models import Session, User
from ereuse_devicehub.teal.auth import TokenAuth
from ereuse_devicehub.teal.db import ResourceNotFound
class Auth(TokenAuth): class Auth(TokenAuth):

View File

@ -2,21 +2,23 @@ import os
import click.testing import click.testing
import flask.cli import flask.cli
import ereuse_utils import ereuse_devicehub.ereuse_utils
from ereuse_devicehub.config import DevicehubConfig from ereuse_devicehub.config import DevicehubConfig
from ereuse_devicehub.devicehub import Devicehub from ereuse_devicehub.devicehub import Devicehub
import sys import sys
sys.ps1 = '\001\033[92m\002>>> \001\033[0m\002' sys.ps1 = '\001\033[92m\002>>> \001\033[0m\002'
sys.ps2= '\001\033[94m\002... \001\033[0m\002' sys.ps2 = '\001\033[94m\002... \001\033[0m\002'
import os, readline, atexit import os, readline, atexit
history_file = os.path.join(os.environ['HOME'], '.python_history') history_file = os.path.join(os.environ['HOME'], '.python_history')
try: try:
readline.read_history_file(history_file) readline.read_history_file(history_file)
except IOError: except IOError:
pass pass
readline.parse_and_bind("tab: complete") readline.parse_and_bind("tab: complete")
readline.parse_and_bind('"\e[5~": history-search-backward') readline.parse_and_bind('"\e[5~": history-search-backward')
readline.parse_and_bind('"\e[6~": history-search-forward') readline.parse_and_bind('"\e[6~": history-search-forward')
@ -29,6 +31,7 @@ readline.parse_and_bind('"\e[1;5D": backward-word')
readline.set_history_length(100000) readline.set_history_length(100000)
atexit.register(readline.write_history_file, history_file) atexit.register(readline.write_history_file, history_file)
class DevicehubGroup(flask.cli.FlaskGroup): class DevicehubGroup(flask.cli.FlaskGroup):
# todo users cannot make cli to use a custom db this way! # todo users cannot make cli to use a custom db this way!
CONFIG = DevicehubConfig CONFIG = DevicehubConfig
@ -49,26 +52,37 @@ class DevicehubGroup(flask.cli.FlaskGroup):
def get_version(ctx, param, value): def get_version(ctx, param, value):
if not value or ctx.resilient_parsing: if not value or ctx.resilient_parsing:
return return
click.echo('Devicehub {}'.format(ereuse_utils.version('ereuse-devicehub')), color=ctx.color) click.echo(
'Devicehub {}'.format(
ereuse_devicehub.ereuse_utils.version('ereuse-devicehub')
),
color=ctx.color,
)
flask.cli.get_version(ctx, param, value) flask.cli.get_version(ctx, param, value)
@click.option('--version', @click.option(
help='Devicehub version.', '--version',
expose_value=False, help='Devicehub version.',
callback=get_version, expose_value=False,
is_flag=True, callback=get_version,
is_eager=True) is_flag=True,
@click.group(cls=DevicehubGroup, is_eager=True,
context_settings=Devicehub.cli_context_settings, )
add_version_option=False, @click.group(
help="""Manages the Devicehub of the inventory {}. cls=DevicehubGroup,
context_settings=Devicehub.cli_context_settings,
add_version_option=False,
help="""Manages the Devicehub of the inventory {}.
Use 'export dhi=xx' to set the inventory that this CLI Use 'export dhi=xx' to set the inventory that this CLI
manages. For example 'export dhi=db1' and then executing manages. For example 'export dhi=db1' and then executing
'dh tag add' adds a tag in the db1 database. Operations 'dh tag add' adds a tag in the db1 database. Operations
that affect the common database (like creating an user) that affect the common database (like creating an user)
are not affected by this. are not affected by this.
""".format(os.environ.get('dhi'))) """.format(
os.environ.get('dhi')
),
)
def cli(): def cli():
pass pass

View File

@ -1,11 +1,14 @@
from inspect import isclass from inspect import isclass
from typing import Dict, Iterable, Type, Union from typing import Dict, Iterable, Type, Union
from ereuse_utils.test import JSON, Res from ereuse_devicehub.ereuse_utils.test import JSON, Res
from teal.client import Client as TealClient, Query, Status from flask.testing import FlaskClient
from flask_wtf.csrf import generate_csrf
from werkzeug.exceptions import HTTPException from werkzeug.exceptions import HTTPException
from ereuse_devicehub.resources import models, schemas from ereuse_devicehub.resources import models, schemas
from ereuse_devicehub.teal.client import Client as TealClient
from ereuse_devicehub.teal.client import Query, Status
ResourceLike = Union[Type[Union[models.Thing, schemas.Thing]], str] ResourceLike = Union[Type[Union[models.Thing, schemas.Thing]], str]
@ -13,110 +16,156 @@ ResourceLike = Union[Type[Union[models.Thing, schemas.Thing]], str]
class Client(TealClient): class Client(TealClient):
"""A client suited for Devicehub main usage.""" """A client suited for Devicehub main usage."""
def __init__(self, application, def __init__(
response_wrapper=None, self,
use_cookies=False, application,
allow_subdomain_redirects=False): response_wrapper=None,
super().__init__(application, response_wrapper, use_cookies, allow_subdomain_redirects) use_cookies=False,
allow_subdomain_redirects=False,
):
super().__init__(
application, response_wrapper, use_cookies, allow_subdomain_redirects
)
def open(self, def open(
uri: str, self,
res: ResourceLike = None, uri: str,
status: Status = 200, res: ResourceLike = None,
query: Query = tuple(), status: Status = 200,
accept=JSON, query: Query = tuple(),
content_type=JSON, accept=JSON,
item=None, content_type=JSON,
headers: dict = None, item=None,
token: str = None, headers: dict = None,
**kw) -> Res: token: str = None,
**kw,
) -> Res:
if isclass(res) and issubclass(res, (models.Thing, schemas.Thing)): if isclass(res) and issubclass(res, (models.Thing, schemas.Thing)):
res = res.t res = res.t
return super().open(uri, res, status, query, accept, content_type, item, headers, token, return super().open(
**kw) uri, res, status, query, accept, content_type, item, headers, token, **kw
)
def get(self, def get(
uri: str = '', self,
res: ResourceLike = None, uri: str = '',
query: Query = tuple(), res: ResourceLike = None,
status: Status = 200, query: Query = tuple(),
item: Union[int, str] = None, status: Status = 200,
accept: str = JSON, item: Union[int, str] = None,
headers: dict = None, accept: str = JSON,
token: str = None, headers: dict = None,
**kw) -> Res: token: str = None,
**kw,
) -> Res:
return super().get(uri, res, query, status, item, accept, headers, token, **kw) return super().get(uri, res, query, status, item, accept, headers, token, **kw)
def post(self, def post(
data: str or dict, self,
uri: str = '', data: str or dict,
res: ResourceLike = None, uri: str = '',
query: Query = tuple(), res: ResourceLike = None,
status: Status = 201, query: Query = tuple(),
content_type: str = JSON, status: Status = 201,
accept: str = JSON, content_type: str = JSON,
headers: dict = None, accept: str = JSON,
token: str = None, headers: dict = None,
**kw) -> Res: token: str = None,
return super().post(data, uri, res, query, status, content_type, accept, headers, token, **kw,
**kw) ) -> Res:
return super().post(
data, uri, res, query, status, content_type, accept, headers, token, **kw
)
def patch(self, def patch(
data: str or dict, self,
uri: str = '', data: str or dict,
res: ResourceLike = None, uri: str = '',
query: Query = tuple(), res: ResourceLike = None,
item: Union[int, str] = None, query: Query = tuple(),
status: Status = 200, item: Union[int, str] = None,
content_type: str = JSON, status: Status = 200,
accept: str = JSON, content_type: str = JSON,
headers: dict = None, accept: str = JSON,
token: str = None, headers: dict = None,
**kw) -> Res: token: str = None,
return super().patch(data, uri, res, query, item, status, content_type, accept, token, **kw,
headers, **kw) ) -> Res:
return super().patch(
data,
uri,
res,
query,
item,
status,
content_type,
accept,
token,
headers,
**kw,
)
def put(self, def put(
data: str or dict, self,
uri: str = '', data: str or dict,
res: ResourceLike = None, uri: str = '',
query: Query = tuple(), res: ResourceLike = None,
item: Union[int, str] = None, query: Query = tuple(),
status: Status = 201, item: Union[int, str] = None,
content_type: str = JSON, status: Status = 201,
accept: str = JSON, content_type: str = JSON,
headers: dict = None, accept: str = JSON,
token: str = None, headers: dict = None,
**kw) -> Res: token: str = None,
return super().put(data, uri, res, query, item, status, content_type, accept, token, **kw,
headers, **kw) ) -> Res:
return super().put(
data,
uri,
res,
query,
item,
status,
content_type,
accept,
token,
headers,
**kw,
)
def delete(self, def delete(
uri: str = '', self,
res: ResourceLike = None, uri: str = '',
query: Query = tuple(), res: ResourceLike = None,
status: Status = 204, query: Query = tuple(),
item: Union[int, str] = None, status: Status = 204,
accept: str = JSON, item: Union[int, str] = None,
headers: dict = None, accept: str = JSON,
token: str = None, headers: dict = None,
**kw) -> Res: token: str = None,
return super().delete(uri, res, query, status, item, accept, headers, token, **kw) **kw,
) -> Res:
return super().delete(
uri, res, query, status, item, accept, headers, token, **kw
)
def login(self, email: str, password: str): def login(self, email: str, password: str):
assert isinstance(email, str) assert isinstance(email, str)
assert isinstance(password, str) assert isinstance(password, str)
return self.post({'email': email, 'password': password}, '/users/login/', status=200) return self.post(
{'email': email, 'password': password}, '/users/login/', status=200
)
def get_many(self, def get_many(
res: ResourceLike, self,
resources: Iterable[Union[dict, int]], res: ResourceLike,
key: str = None, resources: Iterable[Union[dict, int]],
**kw) -> Iterable[Union[Dict[str, object], str]]: key: str = None,
**kw,
) -> Iterable[Union[Dict[str, object], str]]:
"""Like :meth:`.get` but with many resources.""" """Like :meth:`.get` but with many resources."""
return ( return (
self.get(res=res, item=r[key] if key else r, **kw)[0] self.get(res=res, item=r[key] if key else r, **kw)[0] for r in resources
for r in resources
) )
@ -126,33 +175,119 @@ class UserClient(Client):
It will automatically perform login on the first request. It will automatically perform login on the first request.
""" """
def __init__(self, application, def __init__(
email: str, self,
password: str, application,
response_wrapper=None, email: str,
use_cookies=False, password: str,
allow_subdomain_redirects=False): response_wrapper=None,
super().__init__(application, response_wrapper, use_cookies, allow_subdomain_redirects) use_cookies=False,
allow_subdomain_redirects=False,
):
super().__init__(
application, response_wrapper, use_cookies, allow_subdomain_redirects
)
self.email = email # type: str self.email = email # type: str
self.password = password # type: str self.password = password # type: str
self.user = None # type: dict self.user = None # type: dict
def open(self, def open(
uri: str, self,
res: ResourceLike = None, uri: str,
status: int or HTTPException = 200, res: ResourceLike = None,
query: Query = tuple(), status: int or HTTPException = 200,
accept=JSON, query: Query = tuple(),
content_type=JSON, accept=JSON,
item=None, content_type=JSON,
headers: dict = None, item=None,
token: str = None, headers: dict = None,
**kw) -> Res: token: str = None,
return super().open(uri, res, status, query, accept, content_type, item, headers, **kw,
self.user['token'] if self.user else token, **kw) ) -> Res:
return super().open(
uri,
res,
status,
query,
accept,
content_type,
item,
headers,
self.user['token'] if self.user else token,
**kw,
)
# noinspection PyMethodOverriding # noinspection PyMethodOverriding
def login(self): def login(self):
response = super().login(self.email, self.password) response = super().login(self.email, self.password)
self.user = response[0] self.user = response[0]
return response return response
class UserClientFlask:
def __init__(
self,
application,
email: str,
password: str,
response_wrapper=None,
use_cookies=True,
follow_redirects=True,
):
self.email = email
self.password = password
self.follow_redirects = follow_redirects
self.user = None
self.client = FlaskClient(application, use_cookies=use_cookies)
self.client.get('/login/')
data = {
'email': email,
'password': password,
'csrf_token': generate_csrf(),
}
body, status, headers = self.client.post(
'/login/', data=data, follow_redirects=True
)
self.headers = headers
body = next(body).decode("utf-8")
assert "Unassigned" in body
def get(
self,
uri='',
data=None,
follow_redirects=True,
content_type='text/html; charset=utf-8',
decode=True,
**kw,
):
body, status, headers = self.client.get(
uri, data=data, follow_redirects=follow_redirects, headers=self.headers
)
if decode:
body = next(body).decode("utf-8")
return (body, status)
def post(
self,
uri='',
data=None,
follow_redirects=True,
content_type='application/x-www-form-urlencoded',
decode=True,
**kw,
):
body, status, headers = self.client.post(
uri,
data=data,
follow_redirects=follow_redirects,
headers=self.headers,
content_type=content_type,
)
if decode:
body = next(body).decode("utf-8")
return (body, status)

View File

View File

@ -0,0 +1,24 @@
import click
from ereuse_devicehub.db import db
from ereuse_devicehub.resources.agent.models import Person
from ereuse_devicehub.resources.user.models import User
class AddUser:
def __init__(self, app) -> None:
super().__init__()
self.app = app
self.schema = app.config.get('DB_SCHEMA')
self.app.cli.command('adduser', short_help='add a user.')(self.run)
@click.argument('email')
@click.argument('password')
def run(self, email, password):
name = email.split('@')[0]
user = User(email=email, password=password)
user.individuals.add(Person(name=name))
db.session.add(user)
db.session.commit()

View File

@ -0,0 +1,125 @@
"""This command is used for up one snapshot."""
import json
import click
from ereuse_devicehub.resources.action.models import Snapshot
from ereuse_devicehub.resources.user.models import User
class CheckInstall:
"""Command.
This command check if the installation was ok and the
integration with the api of DLT was ok too.
"""
def __init__(self, app) -> None:
"""Init function."""
super().__init__()
self.app = app
self.schema = app.config.get('DB_SCHEMA')
self.app.cli.command('check_install', short_help='Upload snapshots.')(self.run)
@click.argument('email')
@click.argument('password')
def run(self, email, password):
"""Run command."""
self.email = email
self.password = password
self.OKGREEN = '\033[92m'
# self.WARNING = '\033[93m'
self.FAIL = '\033[91m'
self.ENDC = '\033[0m'
print("\n")
try:
self.check_user()
self.check_snapshot()
except Exception:
txt = "There was an Error in the installation!"
print("\n" + self.FAIL + txt + self.ENDC)
return
txt = "The installation is OK!"
print("\n" + self.OKGREEN + txt + self.ENDC)
def check_user(self):
"""Get datamodel of user."""
self.user = User.query.filter_by(email=self.email).first()
txt = "Register user to the DLT "
try:
assert self.user.api_keys_dlt is not None
token_dlt = self.user.get_dlt_keys(self.password)
assert token_dlt.get('data', {}).get('eth_pub_key') is not None
except Exception:
self.print_fail(txt)
raise (txt)
self.print_ok(txt)
api_token = token_dlt.get('data', {}).get('api_token')
txt = "Register user roles in the DLT "
try:
rols = self.user.get_rols(api_token)
assert self.user.rols_dlt is not None
assert self.user.rols_dlt != []
assert self.user.rols_dlt == json.dumps([x for x, y in rols])
except Exception:
self.print_fail(txt)
raise (txt)
self.print_ok(txt)
def check_snapshot(self):
self.snapshot = Snapshot.query.filter_by(author=self.user).first()
if not self.snapshot:
txt = "Impossible register snapshot "
self.print_fail(txt)
raise (txt)
self.device = self.snapshot.device
txt = "Generate DPP "
try:
assert self.device.chid is not None
assert self.snapshot.json_wb is not None
assert self.snapshot.phid_dpp is not None
except Exception:
self.print_fail(txt)
raise (txt)
self.print_ok(txt)
txt = "Register DPP in the DLT "
try:
assert len(self.device.dpps) > 0
dpp = self.device.dpps[0]
assert type(dpp.timestamp) == int
assert dpp in self.snapshot.dpp
assert dpp.documentId == str(self.snapshot.uuid)
# if 'Device already exists' in DLT before
# device.proofs == 0
# Snapshot.proof == 1 [erase]
# if Device is new in DLT before
# device.proofs == 1
# Snapshot.proof == 1 or 2 [Register, erase]
assert len(self.device.proofs) in [0, 1]
assert len(self.snapshot.proofs) in [0, 1, 2]
except Exception:
self.print_fail(txt)
raise (txt)
self.print_ok(txt)
def print_ok(self, msg):
print(msg + self.OKGREEN + " OK!" + self.ENDC)
def print_fail(self, msg):
print(msg + self.FAIL + " FAIL!" + self.ENDC)

View File

@ -0,0 +1,41 @@
from uuid import uuid4
from boltons.urlutils import URL
from decouple import config
from ereuse_devicehub.db import db
from ereuse_devicehub.resources.agent.models import Person
from ereuse_devicehub.resources.inventory.model import Inventory
from ereuse_devicehub.resources.user.models import User
class InitDatas:
def __init__(self, app) -> None:
super().__init__()
self.app = app
self.schema = app.config.get('DB_SCHEMA')
self.email = config('EMAIL_DEMO')
self.name = self.email.split('@')[0] if self.email else None
self.password = config('PASSWORD_DEMO')
self.app.cli.command(
'initdata', short_help='Save a minimum structure of datas.'
)(self.run)
def run(self):
inv = Inventory(
id=self.schema,
name="usody",
tag_provider=URL('http://localhost:8081'),
tag_token=uuid4(),
org_id=uuid4(),
)
db.session.add(inv)
db.session.commit()
if self.email:
user = User(email=self.email, password=self.password)
user.individuals.add(Person(name=self.name))
db.session.add(user)
db.session.commit()

View File

@ -0,0 +1,103 @@
"""This command is used for up one snapshot."""
import json
# from uuid import uuid4
from io import BytesIO
from os import listdir
from os import remove as remove_file
from os.path import isfile, join
from pathlib import Path
import click
from flask.testing import FlaskClient
from flask_wtf.csrf import generate_csrf
from ereuse_devicehub.resources.user.models import User
class UploadSnapshots:
"""Command.
This command allow upload all snapshots than exist
in the directory snapshots_upload.
If this snapshot exist replace it.
"""
def __init__(self, app) -> None:
"""Init function."""
super().__init__()
self.app = app
self.schema = app.config.get('DB_SCHEMA')
self.app.cli.command('snapshot', short_help='Upload snapshots.')(self.run)
@click.argument('email')
@click.argument('password')
def run(self, email, password=None):
"""Run command."""
self.email = email
self.password = password
self.json_wb = None
self.onlyfiles = []
self.get_user()
self.get_files()
for f in self.onlyfiles:
self.file_snapshot = f
self.open_snapshot()
self.build_snapshot()
self.remove_files()
def get_user(self):
"""Get datamodel of user."""
self.user = User.query.filter_by(email=self.email).one()
self.client = FlaskClient(self.app, use_cookies=True)
self.client.get('/login/')
data = {
'email': self.email,
'password': self.password,
'remember': False,
'csrf_token': generate_csrf(),
}
self.client.post('/login/', data=data, follow_redirects=True)
def remove_files(self):
"""Open snapshot file."""
for f in self.onlyfiles:
remove_file(Path(__file__).parent.joinpath('snapshot_files').joinpath(f))
def open_snapshot(self):
"""Open snapshot file."""
with Path(__file__).parent.joinpath('snapshot_files').joinpath(
self.file_snapshot,
).open() as file_snapshot:
self.json_wb = json.loads(file_snapshot.read())
b_snapshot = bytes(json.dumps(self.json_wb), 'utf-8')
self.file_snap = (BytesIO(b_snapshot), self.file_snapshot)
def build_snapshot(self):
"""Build the devices of snapshot."""
uri = '/inventory/upload-snapshot/'
if not self.json_wb:
return
self.client.get(uri)
data = {
'snapshot': self.file_snap,
'csrf_token': generate_csrf(),
}
self.client.post(uri, data=data, content_type="multipart/form-data")
def get_files(self):
"""Read snaoshot_files dir."""
mypath = Path(__file__).parent.joinpath('snapshot_files')
for f in listdir(mypath):
if not isfile(join(mypath, f)):
continue
if not f[-5:] == ".json":
continue
self.onlyfiles.append(f)

View 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))

View File

@ -1,58 +1,79 @@
from distutils.version import StrictVersion from distutils.version import StrictVersion
from itertools import chain from itertools import chain
from typing import Set
from decouple import config from decouple import config
from teal.auth import TokenAuth from ereuse_devicehub.resources import (
from teal.config import Config action,
from teal.enums import Currency agent,
from teal.utils import import_resource deliverynote,
inventory,
from ereuse_devicehub.resources import action, agent, deliverynote, inventory, \ lot,
lot, tag, user tag,
user,
)
from ereuse_devicehub.resources.device import definitions from ereuse_devicehub.resources.device import definitions
from ereuse_devicehub.resources.did import did
from ereuse_devicehub.resources.documents import documents from ereuse_devicehub.resources.documents import documents
from ereuse_devicehub.resources.tradedocument import definitions as tradedocument
from ereuse_devicehub.resources.enums import PriceSoftware from ereuse_devicehub.resources.enums import PriceSoftware
from ereuse_devicehub.resources.versions import versions
from ereuse_devicehub.resources.licences import licences from ereuse_devicehub.resources.licences import licences
from ereuse_devicehub.resources.metric import definitions as metric_def from ereuse_devicehub.resources.metric import definitions as metric_def
from ereuse_devicehub.resources.tradedocument import definitions as tradedocument
from ereuse_devicehub.resources.versions import versions
from ereuse_devicehub.teal.auth import TokenAuth
from ereuse_devicehub.teal.config import Config
from ereuse_devicehub.teal.enums import Currency
from ereuse_devicehub.teal.utils import import_resource
class DevicehubConfig(Config): class DevicehubConfig(Config):
RESOURCE_DEFINITIONS = set(chain(import_resource(definitions), RESOURCE_DEFINITIONS = set(
import_resource(action), chain(
import_resource(user), import_resource(definitions),
import_resource(tag), import_resource(action),
import_resource(agent), import_resource(user),
import_resource(lot), import_resource(tag),
import_resource(deliverynote), import_resource(did),
import_resource(documents), import_resource(agent),
import_resource(tradedocument), import_resource(lot),
import_resource(inventory), import_resource(deliverynote),
import_resource(versions), import_resource(documents),
import_resource(licences), import_resource(tradedocument),
import_resource(metric_def), import_resource(inventory),
),) import_resource(versions),
PASSWORD_SCHEMES = {'pbkdf2_sha256'} # type: Set[str] import_resource(licences),
import_resource(metric_def),
),
)
PASSWORD_SCHEMES = {'pbkdf2_sha256'}
SECRET_KEY = config('SECRET_KEY') SECRET_KEY = config('SECRET_KEY')
DB_USER = config('DB_USER', 'dhub') DB_USER = config('DB_USER', 'dhub')
DB_PASSWORD = config('DB_PASSWORD', 'ereuse') DB_PASSWORD = config('DB_PASSWORD', 'ereuse')
DB_HOST = config('DB_HOST', 'localhost') DB_HOST = config('DB_HOST', 'localhost')
DB_DATABASE = config('DB_DATABASE', 'devicehub') DB_DATABASE = config('DB_DATABASE', 'devicehub')
DB_SCHEMA = config('DB_SCHEMA', 'dbtest') DB_SCHEMA = config('DB_SCHEMA', 'dbtest')
SQLALCHEMY_DATABASE_URI = 'postgresql://{user}:{pw}@{host}/{db}'.format( SQLALCHEMY_DATABASE_URI = 'postgresql://{user}:{pw}@{host}/{db}'.format(
user=DB_USER, user=DB_USER,
pw=DB_PASSWORD, pw=DB_PASSWORD,
host=DB_HOST, host=DB_HOST,
db=DB_DATABASE, db=DB_DATABASE,
) # type: str ) # type: str
SQLALCHEMY_POOL_SIZE = int(config("SQLALCHEMY_POOL_SIZE", 10))
SQLALCHEMY_MAX_OVERFLOW = int(config("SQLALCHEMY_MAX_OVERFLOW", 20))
SQLALCHEMY_TRACK_MODIFICATIONS = bool(config("SQLALCHEMY_TRACK_MODIFICATIONS", False))
SQLALCHEMY_POOL_TIMEOUT = int(config("SQLALCHEMY_POOL_TIMEOUT", 0))
SQLALCHEMY_POOL_RECYCLE = int(config("SQLALCHEMY_POOL_RECYCLE", 3600))
SCHEMA = config('SCHEMA', 'dbtest') SCHEMA = config('SCHEMA', 'dbtest')
HOST = config('HOST', 'localhost') HOST = config('HOST', 'localhost')
API_HOST = config('API_HOST', 'localhost')
MIN_WORKBENCH = StrictVersion('11.0a1') # type: StrictVersion MIN_WORKBENCH = StrictVersion('11.0a1') # type: StrictVersion
"""The minimum version of ereuse.org workbench that this devicehub """The minimum version of ereuse.org workbench that this devicehub
accepts. we recommend not changing this value. accepts. we recommend not changing this value.
""" """
SCHEMA_WORKBENCH = ["1.0.0"]
TMP_SNAPSHOTS = config('TMP_SNAPSHOTS', '/tmp/snapshots') TMP_SNAPSHOTS = config('TMP_SNAPSHOTS', '/tmp/snapshots')
TMP_LIVES = config('TMP_LIVES', '/tmp/lives') TMP_LIVES = config('TMP_LIVES', '/tmp/lives')
@ -60,11 +81,7 @@ class DevicehubConfig(Config):
"""This var is for save a snapshots in json format when fail something""" """This var is for save a snapshots in json format when fail something"""
API_DOC_CONFIG_TITLE = 'Devicehub' API_DOC_CONFIG_TITLE = 'Devicehub'
API_DOC_CONFIG_VERSION = '0.2' API_DOC_CONFIG_VERSION = '0.2'
API_DOC_CONFIG_COMPONENTS = { API_DOC_CONFIG_COMPONENTS = {'securitySchemes': {'bearerAuth': TokenAuth.API_DOCS}}
'securitySchemes': {
'bearerAuth': TokenAuth.API_DOCS
}
}
API_DOC_CLASS_DISCRIMINATOR = 'type' API_DOC_CLASS_DISCRIMINATOR = 'type'
PRICE_SOFTWARE = PriceSoftware.Ereuse PRICE_SOFTWARE = PriceSoftware.Ereuse
@ -74,7 +91,34 @@ class DevicehubConfig(Config):
"""Admin email""" """Admin email"""
EMAIL_ADMIN = config('EMAIL_ADMIN', '') EMAIL_ADMIN = config('EMAIL_ADMIN', '')
EMAIL_DEMO = config('EMAIL_DEMO', 'hello@usody.com')
"""Definition of path where save the documents of customers""" """Definition of path where save the documents of customers"""
PATH_DOCUMENTS_STORAGE = config('PATH_DOCUMENTS_STORAGE', '/tmp/') PATH_DOCUMENTS_STORAGE = config('PATH_DOCUMENTS_STORAGE', '/tmp/')
JWT_PASS = config('JWT_PASS', '') JWT_PASS = config('JWT_PASS', '')
MAIL_SERVER = config('MAIL_SERVER', '')
MAIL_USERNAME = config('MAIL_USERNAME', '')
MAIL_PASSWORD = config('MAIL_PASSWORD', '')
MAIL_PORT = config('MAIL_PORT', 587)
MAIL_USE_TLS = config('MAIL_USE_TLS', True)
MAIL_DEFAULT_SENDER = config('MAIL_DEFAULT_SENDER', '')
API_DLT = config('API_DLT', None)
API_DLT_TOKEN = config('API_DLT_TOKEN', None)
ID_FEDERATED = config('ID_FEDERATED', None)
URL_MANUALS = config('URL_MANUALS', None)
ABAC_TOKEN = config('ABAC_TOKEN', None)
ABAC_COOKIE = config('ABAC_COOKIE', None)
ABAC_URL = config('ABAC_URL', None)
VERIFY_URL = config('VERIFY_URL', None)
"""Definition of oauth jwt details."""
OAUTH2_JWT_ENABLED = config('OAUTH2_JWT_ENABLED', False)
OAUTH2_JWT_ISS = config('OAUTH2_JWT_ISS', '')
OAUTH2_JWT_KEY = config('OAUTH2_JWT_KEY', None)
OAUTH2_JWT_ALG = config('OAUTH2_JWT_ALG', 'HS256')
if API_DLT:
API_DLT = API_DLT.strip("/")
WALLET_INX_EBSI_PLUGIN_TOKEN = config('WALLET_INX_EBSI_PLUGIN_TOKEN', None)
WALLET_INX_EBSI_PLUGIN_URL = config('WALLET_INX_EBSI_PLUGIN_URL', None)

View File

@ -4,7 +4,8 @@ from sqlalchemy.dialects import postgresql
from sqlalchemy.orm import sessionmaker from sqlalchemy.orm import sessionmaker
from sqlalchemy.sql import expression from sqlalchemy.sql import expression
from sqlalchemy_utils import view from sqlalchemy_utils import view
from teal.db import SchemaSQLAlchemy, SchemaSession
from ereuse_devicehub.teal.db import SchemaSession, SchemaSQLAlchemy
class DhSession(SchemaSession): class DhSession(SchemaSession):
@ -23,6 +24,7 @@ class DhSession(SchemaSession):
# flush, all the new / dirty interesting things in a variable # flush, all the new / dirty interesting things in a variable
# until DeviceSearch is executed # until DeviceSearch is executed
from ereuse_devicehub.resources.device.search import DeviceSearch from ereuse_devicehub.resources.device.search import DeviceSearch
DeviceSearch.update_modified_devices(session=self) DeviceSearch.update_modified_devices(session=self)
@ -31,6 +33,7 @@ class SQLAlchemy(SchemaSQLAlchemy):
schema of the database, as it is in the `search_path` schema of the database, as it is in the `search_path`
defined in teal. defined in teal.
""" """
# todo add here all types of columns used so we don't have to # todo add here all types of columns used so we don't have to
# manually import them all the time # manually import them all the time
UUID = postgresql.UUID UUID = postgresql.UUID
@ -60,11 +63,15 @@ def create_view(name, selectable):
# We need to ensure views are created / destroyed before / after # We need to ensure views are created / destroyed before / after
# SchemaSQLAlchemy's listeners execute # SchemaSQLAlchemy's listeners execute
# That is why insert=True in 'after_create' # That is why insert=True in 'after_create'
event.listen(db.metadata, 'after_create', view.CreateView(name, selectable), insert=True) event.listen(
db.metadata, 'after_create', view.CreateView(name, selectable), insert=True
)
event.listen(db.metadata, 'before_drop', view.DropView(name)) event.listen(db.metadata, 'before_drop', view.DropView(name))
return table return table
db = SQLAlchemy(session_options={'autoflush': False}) db = SQLAlchemy(
session_options={'autoflush': False},
)
f = db.func f = db.func
exp = expression exp = expression

View File

@ -5,28 +5,66 @@ from typing import Type
import boltons.urlutils import boltons.urlutils
import click import click
import click_spinner import click_spinner
import ereuse_utils.cli
from ereuse_utils.session import DevicehubClient
from flask import _app_ctx_stack, g from flask import _app_ctx_stack, g
from flask_login import LoginManager, current_user from flask_login import LoginManager, current_user
from flask_sqlalchemy import SQLAlchemy from flask_sqlalchemy import SQLAlchemy
from teal.db import ResourceNotFound, SchemaSQLAlchemy
from teal.teal import Teal
import ereuse_devicehub.ereuse_utils.cli
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.adduser import AddUser
from ereuse_devicehub.commands.check_install import CheckInstall
from ereuse_devicehub.commands.initdatas import InitDatas
from ereuse_devicehub.commands.snapshots import UploadSnapshots
# 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
from ereuse_devicehub.ereuse_utils.session import DevicehubClient
from ereuse_devicehub.resources.device.search import DeviceSearch from ereuse_devicehub.resources.device.search import DeviceSearch
from ereuse_devicehub.resources.inventory import Inventory, InventoryDef from ereuse_devicehub.resources.inventory import Inventory, InventoryDef
from ereuse_devicehub.resources.user.models import User from ereuse_devicehub.resources.user.models import User
from ereuse_devicehub.teal.db import ResourceNotFound, SchemaSQLAlchemy
from ereuse_devicehub.teal.teal import Teal
from ereuse_devicehub.templating import Environment from ereuse_devicehub.templating import Environment
try:
from ereuse_devicehub.modules.oidc.commands.sync_dlt import GetMembers
except Exception:
GetMembers = None
try:
from ereuse_devicehub.modules.dpp.commands.register_user_dlt import RegisterUserDlt
except Exception:
RegisterUserDlt = None
try:
from ereuse_devicehub.modules.oidc.commands.add_member import AddMember
except Exception:
AddMember = None
try:
from ereuse_devicehub.modules.oidc.commands.client_member import AddClientOidc
except Exception:
AddClientOidc = None
try:
from ereuse_devicehub.modules.oidc.commands.insert_member_in_dlt import InsertMember
except Exception:
InsertMembe = None
try:
from ereuse_devicehub.modules.oidc.commands.add_contract_oidc import AddContractOidc
except Exception:
AddContractOidc = None
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 +105,26 @@ 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.initdata = InitDatas(self)
self.adduser = AddUser(self)
self.uploadsnapshots = UploadSnapshots(self)
self.checkinstall = CheckInstall(self)
if GetMembers:
self.get_members = GetMembers(self)
if RegisterUserDlt:
self.dlt_register_user = RegisterUserDlt(self)
if AddMember:
self.dlt_insert_members = AddMember(self)
if AddClientOidc:
self.add_client_oidc = AddClientOidc(self)
if InsertMember:
self.dlt_insert_members = InsertMember(self)
if AddContractOidc:
self.add_contract_oidc = AddContractOidc(self)
@self.cli.group( @self.cli.group(
short_help='Inventory management.', short_help='Inventory management.',
@ -116,7 +174,7 @@ class Devicehub(Teal):
@click.option( @click.option(
'--tag-url', '--tag-url',
'-tu', '-tu',
type=ereuse_utils.cli.URL(scheme=True, host=True, path=False), type=ereuse_devicehub.ereuse_utils.cli.URL(scheme=True, host=True, path=False),
default='http://example.com', default='http://example.com',
help='The base url (scheme and host) of the tag provider.', help='The base url (scheme and host) of the tag provider.',
) )

View File

@ -1,40 +1,37 @@
import itertools import itertools
import json import json
import jwt import uuid
from pathlib import Path from pathlib import Path
from typing import Set
import click import click
import click_spinner import click_spinner
import ereuse_utils.cli import jwt
import yaml import yaml
from ereuse_utils.test import ANY from ereuse_devicehub.ereuse_utils.test import ANY
from ereuse_devicehub import ereuse_utils
from ereuse_devicehub.client import UserClient from ereuse_devicehub.client import UserClient
from ereuse_devicehub.db import db from ereuse_devicehub.db import db
from ereuse_devicehub.parser.models import SnapshotsLog
from ereuse_devicehub.resources.action import models as m from ereuse_devicehub.resources.action import models as m
from ereuse_devicehub.resources.agent.models import Person from ereuse_devicehub.resources.agent.models import Person
from ereuse_devicehub.resources.device.models import Device from ereuse_devicehub.resources.device.models import Device
from ereuse_devicehub.resources.enums import SessionType
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
from ereuse_devicehub.resources.user import User from ereuse_devicehub.resources.user import User
from ereuse_devicehub.resources.user.models import Session from ereuse_devicehub.resources.user.models import Session
from ereuse_devicehub.resources.enums import SessionType
class Dummy: class Dummy:
TAGS = ( TAGS = ('tag1', 'tag2', 'tag3')
'tag1',
'tag2',
'tag3'
)
"""Tags to create.""" """Tags to create."""
ET = ( ET = (
('DT-AAAAA', 'A0000000000001'), ('DT-AAAAA', 'A0000000000001'),
('DT-BBBBB', 'A0000000000002'), ('DT-BBBBB', 'A0000000000002'),
('DT-CCCCC', 'A0000000000003'), ('DT-CCCCC', 'A0000000000003'),
('DT-BRRAB', '04970DA2A15984'), ('DT-BRRAB', '04970DA2A15984'),
('DT-XXXXX', '04e4bc5af95980') ('DT-XXXXX', '04e4bc5af95980'),
) )
"""eTags to create.""" """eTags to create."""
ORG = 'eReuse.org CAT', '-t', 'G-60437761', '-c', 'ES' ORG = 'eReuse.org CAT', '-t', 'G-60437761', '-c', 'ES'
@ -43,28 +40,35 @@ class Dummy:
def __init__(self, app) -> None: def __init__(self, app) -> None:
super().__init__() super().__init__()
self.app = app self.app = app
self.app.cli.command('dummy', short_help='Creates dummy devices and users.')(self.run) self.app.cli.command('dummy', short_help='Creates dummy devices and users.')(
self.run
)
@click.option('--tag-url', '-tu', @click.option(
type=ereuse_utils.cli.URL(scheme=True, host=True, path=False), '--tag-url',
default='http://localhost:8081', '-tu',
help='The base url (scheme and host) of the tag provider.') type=ereuse_utils.cli.URL(scheme=True, host=True, path=False),
@click.option('--tag-token', '-tt', default='http://localhost:8081',
type=click.UUID, help='The base url (scheme and host) of the tag provider.',
default='899c794e-1737-4cea-9232-fdc507ab7106', )
help='The token provided by the tag provider. It is an UUID.') @click.option(
@click.confirmation_option(prompt='This command (re)creates the DB from scratch.' '--tag-token',
'Do you want to continue?') '-tt',
type=click.UUID,
default='899c794e-1737-4cea-9232-fdc507ab7106',
help='The token provided by the tag provider. It is an UUID.',
)
@click.confirmation_option(
prompt='This command (re)creates the DB from scratch.'
'Do you want to continue?'
)
def run(self, tag_url, tag_token): def run(self, tag_url, tag_token):
runner = self.app.test_cli_runner() runner = self.app.test_cli_runner()
self.app.init_db('Dummy', self.app.init_db(
'ACME', 'Dummy', 'ACME', 'acme-id', tag_url, tag_token, erase=True, common=True
'acme-id', )
tag_url,
tag_token,
erase=True,
common=True)
print('Creating stuff...'.ljust(30), end='') print('Creating stuff...'.ljust(30), end='')
assert SnapshotsLog.query.filter().all() == []
with click_spinner.spinner(): with click_spinner.spinner():
out = runner.invoke('org', 'add', *self.ORG).output out = runner.invoke('org', 'add', *self.ORG).output
org_id = json.loads(out)['id'] org_id = json.loads(out)['id']
@ -77,55 +81,84 @@ class Dummy:
for id in self.TAGS: for id in self.TAGS:
user1.post({'id': id}, res=Tag) user1.post({'id': id}, res=Tag)
for id, sec in self.ET: for id, sec in self.ET:
runner.invoke('tag', 'add', id, runner.invoke(
'-p', 'https://t.devicetag.io', 'tag',
'-s', sec, 'add',
'-u', user1.user["id"], id,
'-o', org_id) '-p',
'https://t.devicetag.io',
'-s',
sec,
'-u',
user1.user["id"],
'-o',
org_id,
)
# create tag for pc-laudem # create tag for pc-laudem
runner.invoke('tag', 'add', 'tagA', runner.invoke(
'-p', 'https://t.devicetag.io', 'tag',
'-u', user1.user["id"], 'add',
'-s', 'tagA-secondary') 'tagA',
'-p',
'https://t.devicetag.io',
'-u',
user1.user["id"],
'-s',
'tagA-secondary',
)
files = tuple(Path(__file__).parent.joinpath('files').iterdir()) files = tuple(Path(__file__).parent.joinpath('files').iterdir())
print('done.') print('done.')
sample_pc = None # We treat this one as a special sample for demonstrations sample_pc = None # We treat this one as a special sample for demonstrations
pcs = set() # type: Set[int] pcs = set()
with click.progressbar(files, label='Creating devices...'.ljust(28)) as bar: with click.progressbar(files, label='Creating devices...'.ljust(28)) as bar:
for path in bar: for path in bar:
with path.open() as f: with path.open() as f:
snapshot = yaml.load(f) snapshot = yaml.load(f)
if snapshot['device']['type'] in ['Desktop', 'Laptop']:
snapshot['device']['system_uuid'] = uuid.uuid4()
s, _ = user1.post(res=m.Snapshot, data=self.json_encode(snapshot)) s, _ = user1.post(res=m.Snapshot, data=self.json_encode(snapshot))
if s.get('uuid', None) == 'ec23c11b-80b6-42cd-ac5c-73ba7acddbc4': if s.get('uuid', None) == 'ec23c11b-80b6-42cd-ac5c-73ba7acddbc4':
sample_pc = s['device']['id'] sample_pc = s['device']['id']
sample_pc_devicehub_id = s['device']['devicehubID'] sample_pc_devicehub_id = s['device']['devicehubID']
else: else:
pcs.add(s['device']['id']) pcs.add(s['device']['id'])
if s.get('uuid', None) == 'de4f495e-c58b-40e1-a33e-46ab5e84767e': # oreo if (
s.get('uuid', None) == 'de4f495e-c58b-40e1-a33e-46ab5e84767e'
): # oreo
# Make one hdd ErasePhysical # Make one hdd ErasePhysical
hdd = next(hdd for hdd in s['components'] if hdd['type'] == 'HardDrive') hdd = next(
user1.post({'type': 'ErasePhysical', 'method': 'Shred', 'device': hdd['id']}, hdd for hdd in s['components'] if hdd['type'] == 'HardDrive'
res=m.Action) )
user1.post(
{
'type': 'ErasePhysical',
'method': 'Shred',
'device': hdd['id'],
},
res=m.Action,
)
assert sample_pc assert sample_pc
print('PC sample is', sample_pc) print('PC sample is', sample_pc)
# Link tags and eTags # Link tags and eTags
for tag, pc in zip((self.TAGS[1], self.TAGS[2], self.ET[0][0], self.ET[1][1]), pcs): for tag, pc in zip(
(self.TAGS[1], self.TAGS[2], self.ET[0][0], self.ET[1][1]), pcs
):
user1.put({}, res=Tag, item='{}/device/{}'.format(tag, pc), status=204) user1.put({}, res=Tag, item='{}/device/{}'.format(tag, pc), status=204)
# Perform generic actions # Perform generic actions
for pc, model in zip(pcs, for pc, model in zip(
{m.ToRepair, m.Repair, m.ToPrepare, m.Ready, m.ToPrepare, pcs, {m.ToRepair, m.Repair, m.ToPrepare, m.Ready, m.ToPrepare, m.Prepare}
m.Prepare}): ):
user1.post({'type': model.t, 'devices': [pc]}, res=m.Action) user1.post({'type': model.t, 'devices': [pc]}, res=m.Action)
# Perform a Sell to several devices # Perform a Sell to several devices
# user1.post( # user1.post(
# { # {
# 'type': m.Sell.t, # 'type': m.Sell.t,
# 'to': user1.user['individuals'][0]['id'], # 'to': user1.user['individuals'][0]['id'],
# 'devices': list(itertools.islice(pcs, len(pcs) // 2)) # 'devices': list(itertools.islice(pcs, len(pcs) // 2))
# }, # },
# res=m.Action) # res=m.Action)
lot_user, _ = user1.post({'name': 'LoteStephan'}, res=Lot) lot_user, _ = user1.post({'name': 'LoteStephan'}, res=Lot)
@ -135,35 +168,43 @@ class Dummy:
lot_user4, _ = user4.post({'name': 'LoteJordi'}, res=Lot) lot_user4, _ = user4.post({'name': 'LoteJordi'}, res=Lot)
lot, _ = user1.post({}, lot, _ = user1.post(
res=Lot, {},
item='{}/devices'.format(lot_user['id']), res=Lot,
query=[('id', pc) for pc in itertools.islice(pcs, 1, 4)]) item='{}/devices'.format(lot_user['id']),
query=[('id', pc) for pc in itertools.islice(pcs, 1, 4)],
)
# assert len(lot['devices']) # assert len(lot['devices'])
lot2, _ = user2.post({}, lot2, _ = user2.post(
res=Lot, {},
item='{}/devices'.format(lot_user2['id']), res=Lot,
query=[('id', pc) for pc in itertools.islice(pcs, 4, 6)]) item='{}/devices'.format(lot_user2['id']),
query=[('id', pc) for pc in itertools.islice(pcs, 4, 6)],
)
lot3, _ = user3.post({}, lot3, _ = user3.post(
res=Lot, {},
item='{}/devices'.format(lot_user3['id']), res=Lot,
query=[('id', pc) for pc in itertools.islice(pcs, 11, 14)]) item='{}/devices'.format(lot_user3['id']),
query=[('id', pc) for pc in itertools.islice(pcs, 11, 14)],
)
lot4, _ = user4.post({}, lot4, _ = user4.post(
res=Lot, {},
item='{}/devices'.format(lot_user4['id']), res=Lot,
query=[('id', pc) for pc in itertools.islice(pcs, 14, 16)]) item='{}/devices'.format(lot_user4['id']),
query=[('id', pc) for pc in itertools.islice(pcs, 14, 16)],
)
# Keep this at the bottom # Keep this at the bottom
inventory, _ = user1.get(res=Device) inventory, _ = user1.get(res=Device)
assert len(inventory['items']) assert len(inventory['items'])
i, _ = user1.get(res=Device, query=[('search', 'intel')]) # i, _ = user1.get(res=Device, query=[('search', 'intel')])
assert 12 == len(i['items']) # assert len(i['items']) in [14, 12]
i, _ = user1.get(res=Device, query=[('search', 'pc')]) # i, _ = user1.get(res=Device, query=[('search', 'pc')])
assert 14 == len(i['items']) # assert len(i['items']) in [17, 14]
# Let's create a set of actions for the pc device # Let's create a set of actions for the pc device
# Make device Ready # Make device Ready
@ -171,23 +212,25 @@ class Dummy:
user1.post({'type': m.ToPrepare.t, 'devices': [sample_pc]}, res=m.Action) user1.post({'type': m.ToPrepare.t, 'devices': [sample_pc]}, res=m.Action)
user1.post({'type': m.Prepare.t, 'devices': [sample_pc]}, res=m.Action) user1.post({'type': m.Prepare.t, 'devices': [sample_pc]}, res=m.Action)
user1.post({'type': m.Ready.t, 'devices': [sample_pc]}, res=m.Action) user1.post({'type': m.Ready.t, 'devices': [sample_pc]}, res=m.Action)
user1.post({'type': m.Price.t, 'device': sample_pc, 'currency': 'EUR', 'price': 85}, user1.post(
res=m.Action) {'type': m.Price.t, 'device': sample_pc, 'currency': 'EUR', 'price': 85},
res=m.Action,
)
# todo test reserve # todo test reserve
# user1.post( # Sell device # user1.post( # Sell device
# { # {
# 'type': m.Sell.t, # 'type': m.Sell.t,
# 'to': user1.user['individuals'][0]['id'], # 'to': user1.user['individuals'][0]['id'],
# 'devices': [sample_pc] # 'devices': [sample_pc]
# }, # },
# res=m.Action) # res=m.Action)
# todo Receive # todo Receive
user1.get(res=Device, item=sample_pc_devicehub_id) # Test user1.get(res=Device, item=sample_pc_devicehub_id) # Test
anonymous = self.app.test_client() anonymous = self.app.test_client()
html, _ = anonymous.get(res=Device, item=sample_pc_devicehub_id, accept=ANY) html, _ = anonymous.get(res=Device, item=sample_pc_devicehub_id, accept=ANY)
assert 'intel core2 duo cpu' in html assert 'hewlett-packard' in html
# For netbook: to preapre -> torepair -> to dispose -> disposed # For netbook: to preapre -> torepair -> to dispose -> disposed
print('⭐ Done.') print('⭐ Done.')
@ -203,19 +246,20 @@ class Dummy:
db.session.add(session_external) db.session.add(session_external)
db.session.commit() db.session.commit()
client = UserClient(self.app, user.email, password, client = UserClient(
response_wrapper=self.app.response_class) self.app, user.email, password, response_wrapper=self.app.response_class
)
client.login() client.login()
return client return client
def json_encode(self, dev: str) -> dict: def json_encode(self, dev: str) -> dict:
"""Encode json.""" """Encode json."""
data = {"type": "Snapshot"} data = {"type": "Snapshot"}
data['data'] = jwt.encode(dev, data['data'] = jwt.encode(
self.app.config['JWT_PASS'], dev,
algorithm="HS256", self.app.config['JWT_PASS'],
json_encoder=ereuse_utils.JSONEncoder algorithm="HS256",
json_encoder=ereuse_utils.JSONEncoder,
) )
return data return data

View File

@ -178,6 +178,7 @@
], ],
"type": "Laptop" "type": "Laptop"
}, },
"debug": {"lshw": {"configuration": {"uuid": "79c5098f-bc44-4834-8a59-9ea61d956c31"}}},
"elapsed": 14725, "elapsed": 14725,
"endTime": "2018-11-24T18:06:37.611704+00:00", "endTime": "2018-11-24T18:06:37.611704+00:00",
"software": "Workbench", "software": "Workbench",

View File

@ -119,6 +119,7 @@
"manufacturer": "ASUSTeK Computer INC." "manufacturer": "ASUSTeK Computer INC."
} }
], ],
"debug": {"lshw": {"configuration": {"uuid": "645f00bf-1ec0-4fdb-9608-b5ac73e285f6"}}},
"version": "11.0a4", "version": "11.0a4",
"elapsed": 6, "elapsed": 6,
"endTime": "2016-11-03T17:17:17.266543+00:00" "endTime": "2016-11-03T17:17:17.266543+00:00"

View File

@ -148,6 +148,7 @@
"model": "0UG982" "model": "0UG982"
} }
], ],
"debug": {"lshw": {"configuration": {"uuid": "5dcdd380-5a54-48bc-99bf-aff6019e8491"}}},
"version": "11.0a3", "version": "11.0a3",
"closed": false, "closed": false,
"elapsed": 1512, "elapsed": 1512,

View File

@ -132,5 +132,6 @@
"model": "HP Compaq 8100 Elite SFF", "model": "HP Compaq 8100 Elite SFF",
"manufacturer": "Hewlett-Packard" "manufacturer": "Hewlett-Packard"
}, },
"debug": {"lshw": {"configuration": {"uuid": "f6cfe48a-93d5-4e94-ab7b-3ee371e4d048"}}},
"version": "11.0a3" "version": "11.0a3"
} }

View File

@ -170,5 +170,6 @@
}, },
"software": "Workbench", "software": "Workbench",
"endTime": "2018-07-11T10:30:22.395958+00:00", "endTime": "2018-07-11T10:30:22.395958+00:00",
"debug": {"lshw": {"configuration": {"uuid": "75dcb454-ae80-4a87-a192-185d3b0250c0"}}},
"elapsed": 2766 "elapsed": 2766
} }

View File

@ -146,6 +146,7 @@
"pcmcia": 0 "pcmcia": 0
} }
], ],
"debug": {"lshw": {"configuration": {"uuid": "fcaf784e-5e57-43a2-b03f-8c56dabd0415"}}},
"uuid": "a01eacdb-db01-43ec-b6fb-a9b8cd21492d", "uuid": "a01eacdb-db01-43ec-b6fb-a9b8cd21492d",
"type": "Snapshot", "type": "Snapshot",
"version": "11.0a4", "version": "11.0a4",

View File

@ -4,6 +4,7 @@
"closed": false, "closed": false,
"endTime": "2018-07-11T13:26:29.365504+00:00", "endTime": "2018-07-11T13:26:29.365504+00:00",
"type": "Snapshot", "type": "Snapshot",
"debug": {"lshw": {"configuration": {"uuid": "4f256440-e43f-429a-a2c6-1e8f3365de56"}}},
"device": { "device": {
"serialNumber": "PB357N0", "serialNumber": "PB357N0",
"actions": [ "actions": [

View File

@ -148,6 +148,7 @@
"slots": 4 "slots": 4
} }
], ],
"debug": {"lshw": {"configuration": {"uuid": "077cad5d-ae1b-4156-a9a1-98bca6fa5c35"}}},
"version": "11.0a3", "version": "11.0a3",
"endTime": "2018-07-11T10:28:55.879745+00:00", "endTime": "2018-07-11T10:28:55.879745+00:00",
"type": "Snapshot", "type": "Snapshot",

View File

@ -136,8 +136,8 @@
], ],
"elapsed": 203, "elapsed": 203,
"device": { "device": {
"manufacturer": null, "manufacturer": "Asus",
"model": null, "model": "P7P55D",
"chassis": "Tower", "chassis": "Tower",
"type": "Desktop", "type": "Desktop",
"serialNumber": null, "serialNumber": null,
@ -158,7 +158,7 @@
] ]
}, },
"version": "11.0a6", "version": "11.0a6",
"debug": {"lshw": {"configuration": {"uuid": "59ca9a2a-65bd-4802-89bb-315156a9352b"}}},
"type": "Snapshot", "type": "Snapshot",
"closed": true, "closed": true,
"software": "Workbench" "software": "Workbench"

View File

@ -142,7 +142,7 @@
}, },
"elapsed": 238, "elapsed": 238,
"endTime": "2018-10-15T13:59:37.431309+00:00", "endTime": "2018-10-15T13:59:37.431309+00:00",
"debug": {"lshw": {"configuration": {"uuid": "43686b8e-e1ae-4e4e-bc51-f98f51e97c2d"}}},
"software": "Workbench", "software": "Workbench",
"type": "Snapshot", "type": "Snapshot",
"uuid": "ec23c11b-80b6-42cd-ac5c-73ba7acddbc4", "uuid": "ec23c11b-80b6-42cd-ac5c-73ba7acddbc4",

View File

@ -158,5 +158,6 @@
} }
] ]
}, },
"debug": {"lshw": {"configuration": {"uuid": "a0cef731-9a78-4087-889c-dfb6ba5c2e9b"}}},
"closed": false "closed": false
} }

View File

@ -114,6 +114,7 @@
} }
], ],
"version": "11.0a3", "version": "11.0a3",
"debug": {"lshw": {"configuration": {"uuid": "f2c50acd-501a-4f0b-b07c-58254b2ab8c9"}}},
"device": { "device": {
"type": "Desktop", "type": "Desktop",
"model": "HP Compaq 8000 Elite SFF", "model": "HP Compaq 8000 Elite SFF",

View File

@ -1,6 +1,7 @@
{ {
"closed": false, "closed": false,
"uuid": "f9e5e587-baee-44e1-9a94-255d216bbda9", "uuid": "f9e5e587-baee-44e1-9a94-255d216bbda9",
"debug": {"lshw": {"configuration": {"uuid": "4d21dd26-aa45-4902-a5f2-8a06e364cf25"}}},
"components": [ "components": [
{ {
"actions": [], "actions": [],

View File

@ -131,6 +131,7 @@
"model": "NB200" "model": "NB200"
}, },
"uuid": "918726ae-c6bc-40aa-97cf-ad80d69268f9", "uuid": "918726ae-c6bc-40aa-97cf-ad80d69268f9",
"debug": {"lshw": {"configuration": {"uuid": "33627ef0-89a9-4659-bb29-faa936727e0b"}}},
"closed": false, "closed": false,
"type": "Snapshot" "type": "Snapshot"
} }

View File

@ -0,0 +1,173 @@
import enum
import ipaddress
import json
import locale
from collections import Iterable
from datetime import datetime, timedelta
from decimal import Decimal
from distutils.version import StrictVersion
from functools import wraps
from typing import Generator, Union
from uuid import UUID
class JSONEncoder(json.JSONEncoder):
"""An overloaded JSON Encoder with extra type support."""
def default(self, obj):
if isinstance(obj, enum.Enum):
return obj.name
elif isinstance(obj, datetime):
return obj.isoformat()
elif isinstance(obj, timedelta):
return round(obj.total_seconds())
elif isinstance(obj, UUID):
return str(obj)
elif isinstance(obj, StrictVersion):
return str(obj)
elif isinstance(obj, set):
return list(obj)
elif isinstance(obj, Decimal):
return float(obj)
elif isinstance(obj, Dumpeable):
return obj.dump()
elif isinstance(obj, ipaddress._BaseAddress):
return str(obj)
# Instead of failing, return the string representation by default
return str(obj)
class Dumpeable:
"""Dumps dictionaries and jsons for Devicehub.
A base class to allow subclasses to generate dictionaries
and json suitable for sending to a Devicehub, i.e. preventing
private and constants to be in the JSON and camelCases field names.
"""
ENCODER = JSONEncoder
def dump(self):
"""
Creates a dictionary consisting of the
non-private fields of this instance with camelCase field names.
"""
import inflection
return {
inflection.camelize(name, uppercase_first_letter=False): getattr(self, name)
for name in self._field_names()
if not name.startswith('_') and not name[0].isupper()
}
def _field_names(self):
"""An iterable of the names to dump."""
# Feel free to override this
return vars(self).keys()
def to_json(self):
"""
Creates a JSON representation of the non-private fields of
this class.
"""
return json.dumps(self, cls=self.ENCODER, indent=2)
class DumpeableModel(Dumpeable):
"""A dumpeable for SQLAlchemy models.
Note that this does not avoid recursive relations.
"""
def _field_names(self):
from sqlalchemy import inspect
return (a.key for a in inspect(self).attrs)
def ensure_utf8(app_name_to_show_on_error: str):
"""
Python3 uses by default the system set, but it expects it to be
utf-8 to work correctly.
This can generate problems in reading and writing files and in
``.decode()`` method.
An example how to 'fix' it::
echo 'export LC_CTYPE=en_US.UTF-8' > .bash_profile
echo 'export LC_ALL=en_US.UTF-8' > .bash_profile
"""
encoding = locale.getpreferredencoding()
if encoding.lower() != 'utf-8':
raise OSError(
'{} works only in UTF-8, but yours is set at {}'
''.format(app_name_to_show_on_error, encoding)
)
def now() -> datetime:
"""
Returns a compatible 'now' with DeviceHub's API,
this is as UTC and without microseconds.
"""
return datetime.utcnow().replace(microsecond=0)
def flatten_mixed(values: Iterable) -> Generator:
"""
Flatten a list containing lists and other elements. This is not deep.
>>> list(flatten_mixed([1, 2, [3, 4]]))
[1, 2, 3, 4]
"""
for x in values:
if isinstance(x, list):
for y in x:
yield y
else:
yield x
def if_none_return_none(f):
"""If the first value is None return None, otherwise execute f."""
@wraps(f)
def wrapper(self, value, *args, **kwargs):
if value is None:
return None
return f(self, value, *args, **kwargs)
return wrapper
def local_ip(
dest='109.69.8.152',
) -> Union[ipaddress.IPv4Address, ipaddress.IPv6Address]:
"""Gets the local IP of the interface that has access to the
Internet.
This is a reliable way to test if a device has an active
connection to the Internet.
This method works by connecting, by default,
to the IP of ereuse01.ereuse.org.
>>> local_ip()
:raise OSError: The device cannot connect to the Internet.
"""
import socket, ipaddress
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect((dest, 80))
ip = s.getsockname()[0]
s.close()
return ipaddress.ip_address(ip)
def version(package_name: str) -> StrictVersion:
"""Returns the version of a package name installed with pip."""
# From https://stackoverflow.com/a/2073599
import pkg_resources
return StrictVersion(pkg_resources.require(package_name)[0].version)

View File

@ -0,0 +1,301 @@
import enum as _enum
import getpass
import itertools
import os
import pathlib
import threading
from contextlib import contextmanager
from time import sleep
from typing import Any, Iterable, Type
from boltons import urlutils
from click import types as click_types
from colorama import Fore
from tqdm import tqdm
from ereuse_devicehub.ereuse_utils import if_none_return_none
COMMON_CONTEXT_S = {'help_option_names': ('-h', '--help')}
"""Common Context settings used for our implementations of the
Click cli.
"""
# Py2/3 compat. Empty conditional to avoid coverage
try:
_unicode = unicode
except NameError:
_unicode = str
class Enum(click_types.Choice):
"""
Enum support for click.
Use it as a collection: @click.option(..., type=cli.Enum(MyEnum)).
Then, this expects you to pass the *name* of a member of the enum.
From `this github issue <https://github.com/pallets/click/issues/
605#issuecomment-277539425>`_.
"""
def __init__(self, enum: Type[_enum.Enum]):
self.__enum = enum
super().__init__(enum.__members__)
def convert(self, value, param, ctx):
return self.__enum[super().convert(value, param, ctx)]
class Path(click_types.Path):
"""Like click.Path but returning ``pathlib.Path`` objects."""
def convert(self, value, param, ctx):
return pathlib.Path(super().convert(value, param, ctx))
class URL(click_types.StringParamType):
"""Returns a bolton's URL."""
name = 'url'
def __init__(
self,
scheme=None,
username=None,
password=None,
host=None,
port=None,
path=None,
query_params=None,
fragment=None,
) -> None:
super().__init__()
"""Creates the type URL. You can require or enforce parts
of the URL by setting parameters of this constructor.
If the param is...
- None, no check is performed (default).
- True, it is then required as part of the URL.
- False, it is then required NOT to be part of the URL.
- Any other value, then such value is required to be in
the URL.
"""
self.attrs = (
('scheme', scheme),
('username', username),
('password', password),
('host', host),
('port', port),
('path', path),
('query_params', query_params),
('fragment', fragment),
)
@if_none_return_none
def convert(self, value, param, ctx):
url = urlutils.URL(super().convert(value, param, ctx))
for name, attr in self.attrs:
if attr is True:
if not getattr(url, name):
self.fail(
'URL {} must contain {} but it does not.'.format(url, name)
)
elif attr is False:
if getattr(url, name):
self.fail('URL {} cannot contain {} but it does.'.format(url, name))
elif attr:
if getattr(url, name) != attr:
self.fail('{} form {} can only be {}'.format(name, url, attr))
return url
def password(service: str, username: str, prompt: str = 'Password:') -> str:
"""Gets a password from the keyring or the terminal."""
import keyring
return keyring.get_password(service, username) or getpass.getpass(prompt)
class Line(tqdm):
spinner_cycle = itertools.cycle(['-', '/', '|', '\\'])
def __init__(
self,
total=None,
desc=None,
leave=True,
file=None,
ncols=None,
mininterval=0.2,
maxinterval=10.0,
miniters=None,
ascii=None,
disable=False,
unit='it',
unit_scale=False,
dynamic_ncols=True,
smoothing=0.3,
bar_format=None,
initial=0,
position=None,
postfix=None,
unit_divisor=1000,
write_bytes=None,
gui=False,
close_message: Iterable = None,
error_message: Iterable = None,
**kwargs,
):
"""This cannot work with iterables. Iterable use is considered
backward-compatibility in tqdm and inconsistent in Line.
Manually call ``update``.
"""
self._close_message = close_message
self._error_message = error_message
if total:
bar_format = '{desc}{percentage:.1f}% |{bar}| {n:1g}/{total:1g} {elapsed}<{remaining}'
super().__init__(
None,
desc,
total,
leave,
file,
ncols,
mininterval,
maxinterval,
miniters,
ascii,
disable,
unit,
unit_scale,
dynamic_ncols,
smoothing,
bar_format,
initial,
position,
postfix,
unit_divisor,
write_bytes,
gui,
**kwargs,
)
def write_at_line(self, *args):
self.clear()
with self._lock:
self.display(''.join(str(arg) for arg in args))
def close_message(self, *args):
self._close_message = args
def error_message(self, *args):
self._error_message = args
def close(self): # noqa: C901
"""
Cleanup and (if leave=False) close the progressbar.
"""
if self.disable:
return
# Prevent multiple closures
self.disable = True
# decrement instance pos and remove from internal set
pos = abs(self.pos)
self._decr_instances(self)
# GUI mode
if not hasattr(self, "sp"):
return
# annoyingly, _supports_unicode isn't good enough
def fp_write(s):
self.fp.write(_unicode(s))
try:
fp_write('')
except ValueError as e:
if 'closed' in str(e):
return
raise # pragma: no cover
with self._lock:
if self.leave:
if self._close_message:
self.display(
''.join(str(arg) for arg in self._close_message), pos=pos
)
elif self.last_print_n < self.n:
# stats for overall rate (no weighted average)
self.avg_time = None
self.display(pos=pos)
if not max(
[abs(getattr(i, "pos", 0)) for i in self._instances] + [pos]
):
# only if not nested (#477)
fp_write('\n')
else:
if self._close_message:
self.display(
''.join(str(arg) for arg in self._close_message), pos=pos
)
else:
self.display(msg='', pos=pos)
if not pos:
fp_write('\r')
@contextmanager
def spin(self, prefix: str):
self._stop_running = threading.Event()
spin_thread = threading.Thread(target=self._spin, args=[prefix])
spin_thread.start()
try:
yield
finally:
self._stop_running.set()
spin_thread.join()
def _spin(self, prefix: str):
while not self._stop_running.is_set():
self.write_at_line(prefix, next(self.spinner_cycle))
sleep(0.50)
@classmethod
@contextmanager
def reserve_lines(self, n):
try:
yield
finally:
self.move_down(n - 1)
@classmethod
def move_down(cls, n: int):
print('\n' * n)
def __exit__(self, *exc):
if exc[0]:
self._close_message = self._error_message
return super().__exit__(*exc)
def clear():
os.system('clear')
def title(text: Any, ljust=32) -> str:
# Note that is 38 px + 1 extra space = 39 min
return str(text).ljust(ljust) + ' '
def danger(text: Any) -> str:
return '{}{}{}'.format(Fore.RED, text, Fore.RESET)
def warning(text: Any) -> str:
return '{}{}{}'.format(Fore.YELLOW, text, Fore.RESET)
def done(text: Any = 'done.') -> str:
return '{}{}{}'.format(Fore.GREEN, text, Fore.RESET)

View File

@ -0,0 +1,148 @@
import subprocess
from contextlib import suppress
from typing import Any, Set
from ereuse_devicehub.ereuse_utils import text
def run(
*cmd: Any,
out=subprocess.PIPE,
err=subprocess.DEVNULL,
to_string=True,
check=True,
shell=False,
**kwargs,
) -> subprocess.CompletedProcess:
"""subprocess.run with a better API.
:param cmd: A list of commands to execute as parameters.
Parameters will be passed-in to ``str()`` so they
can be any object that can handle str().
:param out: As ``subprocess.run.stdout``.
:param err: As ``subprocess.run.stderr``.
:param to_string: As ``subprocess.run.universal_newlines``.
:param check: As ``subprocess.run.check``.
:param shell:
:param kwargs: Any other parameters that ``subprocess.run``
accepts.
:return: The result of executing ``subprocess.run``.
"""
cmds = tuple(str(c) for c in cmd)
return subprocess.run(
' '.join(cmds) if shell else cmds,
stdout=out,
stderr=err,
universal_newlines=to_string,
check=check,
shell=shell,
**kwargs,
)
class ProgressiveCmd:
"""Executes a cmd while interpreting its completion percentage.
The completion percentage of the cmd is stored in
:attr:`.percentage` and the user can obtain percentage
increments by executing :meth:`.increment`.
This class is useful to use within a child thread, so a main
thread can request from time to time the percentage / increment
status of the running command.
"""
READ_LINE = None
DECIMALS = {4, 5, 6}
DECIMAL_NUMBERS = 2
INT = {1, 2, 3}
def __init__(
self,
*cmd: Any,
stdout=subprocess.DEVNULL,
number_chars: Set[int] = INT,
decimal_numbers: int = None,
read: int = READ_LINE,
callback=None,
check=True,
):
"""
:param cmd: The command to execute.
:param stderr: the stderr passed-in to Popen.
:param stdout: the stdout passed-in to Popen
:param number_chars: The number of chars used to represent
the percentage. Normalized cases are
:attr:`.DECIMALS` and :attr:`.INT`.
:param read: For commands that do not print lines, how many
characters we should read between updates.
The percentage should be between those
characters.
:param callback: If passed in, this method is executed every time
run gets an update from the command, passing
in the increment from the last execution.
If not passed-in, you can get such increment
by executing manually the ``increment`` method.
:param check: Raise error if subprocess return code is non-zero.
"""
self.cmd = tuple(str(c) for c in cmd)
self.read = read
self.step = 0
self.check = check
self.number_chars = number_chars
self.decimal_numbers = decimal_numbers
# We call subprocess in the main thread so the main thread
# can react on ``CalledProcessError`` exceptions
self.conn = conn = subprocess.Popen(
self.cmd, universal_newlines=True, stderr=subprocess.PIPE, stdout=stdout
)
self.out = conn.stdout if stdout == subprocess.PIPE else conn.stderr
self._callback = callback
self.last_update_percentage = 0
self.percentage = 0
@property
def percentage(self):
return self._percentage
@percentage.setter
def percentage(self, v):
self._percentage = v
if self._callback and self._percentage > 0:
increment = self.increment()
if (
increment > 0
): # Do not bother calling if there has not been any increment
self._callback(increment, self._percentage)
def run(self) -> None:
"""Processes the output."""
while True:
out = self.out.read(self.read) if self.read else self.out.readline()
if out:
with suppress(StopIteration):
self.percentage = next(
text.positive_percentages(
out, self.number_chars, self.decimal_numbers
)
)
else: # No more output
break
return_code = self.conn.wait() # wait until cmd ends
if self.check and return_code != 0:
raise subprocess.CalledProcessError(
self.conn.returncode, self.conn.args, stderr=self.conn.stderr.read()
)
def increment(self):
"""Returns the increment of progression from
the last time this method is executed.
"""
# for cmd badblocks the increment can be negative at the
# beginning of the second step where last_percentage
# is 100 and percentage is 0. By using max we
# kind-of reset the increment and start counting for
# the second step
increment = max(self.percentage - self.last_update_percentage, 0)
self.last_update_percentage = self.percentage
return increment

View File

@ -0,0 +1,171 @@
"""Functions to get values from dictionaries and list encoded key-value
strings with meaningful indentations.
Values obtained from these functions are sanitized and automatically
(or explicitly set) casted. Sanitization includes removing unnecessary
whitespaces and removing useless keywords (in the context of
computer hardware) from the texts.
"""
import re
from itertools import chain
from typing import Any, Iterable, Set, Type, Union
from unittest.mock import DEFAULT
import boltons.iterutils
import yaml
from ereuse_devicehub.ereuse_utils.text import clean
def dict(
d: dict,
path: Union[str, tuple],
remove: Set[str] = set(),
default: Any = DEFAULT,
type: Type = None,
):
"""Gets a value from the dictionary and sanitizes it.
Values are patterned and compared against sets
of meaningless characters for device hardware.
:param d: A dictionary potentially containing the value.
:param path: The key or a tuple-path where the value should be.
:param remove: Remove these words if found.
:param default: A default value to return if not found. If not set,
an exception is raised.
:param type: Enforce a type on the value (like ``int``). By default
dict tries to guess the correct type.
"""
try:
v = boltons.iterutils.get_path(d, (path,) if isinstance(path, str) else path)
except KeyError:
return _default(path, default)
else:
return sanitize(v, remove, type=type)
def kv(
iterable: Iterable[str],
key: str,
default: Any = DEFAULT,
sep=':',
type: Type = None,
) -> Any:
"""Key-value. Gets a value from an iterable representing key values in the
form of a list of strings lines, for example an ``.ini`` or yaml file,
if they are opened with ``.splitlines()``.
:param iterable: An iterable of strings.
:param key: The key where the value should be.
:param default: A default value to return if not found. If not set,
an exception is raised.
:param sep: What separates the key from the value in the line.
Usually ``:`` or ``=``.
:param type: Enforce a type on the value (like ``int``). By default
dict tries to guess the correct type.
"""
for line in iterable:
try:
k, value, *_ = line.strip().split(sep)
except ValueError:
continue
else:
if key == k:
return sanitize(value, type=type)
return _default(key, default)
def indents(iterable: Iterable[str], keyword: str, indent=' '):
"""For a given iterable of strings, returns blocks of the same
left indentation.
For example:
foo1
bar1
bar2
foo2
foo2
For that text, this method would return ``[bar1, bar2]`` for passed-in
keyword ``foo1``.
:param iterable: A list of strings representing lines.
:param keyword: The title preceding the indentation.
:param indent: Which characters makes the indentation.
"""
section_pos = None
for i, line in enumerate(iterable):
if not line.startswith(indent):
if keyword in line:
section_pos = i
elif section_pos is not None:
yield iterable[section_pos:i]
section_pos = None
return
def _default(key, default):
if default is DEFAULT:
raise IndexError('Value {} not found.'.format(key))
else:
return default
"""Gets"""
TO_REMOVE = {'none', 'prod', 'o.e.m', 'oem', r'n/a', 'atapi', 'pc', 'unknown'}
"""Delete those *words* from the value"""
assert all(v.lower() == v for v in TO_REMOVE), 'All words need to be lower-case'
REMOVE_CHARS_BETWEEN = '(){}[]'
"""
Remove those *characters* from the value.
All chars inside those are removed. Ex: foo (bar) => foo
"""
CHARS_TO_REMOVE = '*'
"""Remove the characters.
'*' Needs to be removed or otherwise it is interpreted
as a glob expression by regexes.
"""
MEANINGLESS = {
'to be filled',
'system manufacturer',
'system product',
'sernum',
'xxxxx',
'system name',
'not specified',
'modulepartnumber',
'system serial',
'0001-067a-0000',
'partnum',
'manufacturer',
'0000000',
'fffff',
'jedec id:ad 00 00 00 00 00 00 00',
'012000',
'x.x',
'sku',
}
"""Discard a value if any of these values are inside it. """
assert all(v.lower() == v for v in MEANINGLESS), 'All values need to be lower-case'
def sanitize(value, remove=set(), type=None):
if value is None:
return None
remove = remove | TO_REMOVE
regex = r'({})\W'.format('|'.join(s for s in remove))
val = re.sub(regex, '', value, flags=re.IGNORECASE)
val = '' if val.lower() in remove else val # regex's `\W` != whole string
val = re.sub(r'\([^)]*\)', '', val) # Remove everything between
for char_to_remove in chain(REMOVE_CHARS_BETWEEN, CHARS_TO_REMOVE):
val = val.replace(char_to_remove, '')
val = clean(val)
if val and not any(meaningless in val.lower() for meaningless in MEANINGLESS):
return type(val) if type else yaml.load(val, Loader=yaml.SafeLoader)
else:
return None

View File

@ -0,0 +1,143 @@
from inflection import (
camelize,
dasherize,
parameterize,
pluralize,
singularize,
underscore,
)
HID_CONVERSION_DOC = """
The HID is the result of concatenating,
in the following order: the type of device (ex. Computer),
the manufacturer name, the model name, and the S/N. It is joined
with hyphens, and adapted to comply with the URI specification, so
it can be used in the URI identifying the device on the Internet.
The conversion is done as follows:
1. non-ASCII characters are converted to their ASCII equivalent or
removed.
2. Characterst that are not letters or numbers are converted to
underscores, in a way that there are no trailing underscores
and no underscores together, and they are set to lowercase.
Ex. ``laptop-acer-aod270-lusga_0d0242201212c7614``
"""
class Naming:
"""
In DeviceHub there are many ways to name the same resource (yay!), this is because of all the different
types of schemas we work with. But no worries, we offer easy ways to change between naming conventions.
- TypeCase (or resource-type) is the one represented with '@type' and follow PascalCase and always singular.
This is the standard preferred one.
- resource-case is the eve naming, using the standard URI conventions. This one is tricky, as although the types
are represented in singular, the URI convention is to be plural (Event vs events), however just few of them
follow this rule (Snapshot [type] to snapshot [resource]). You can set which ones you want to change their
number.
- python_case is the one used by python for its folders and modules. It is underscored and always singular.
"""
TYPE_PREFIX = ':'
RESOURCE_PREFIX = '_'
@staticmethod
def resource(string: str):
"""
:param string: String can be type, resource or python case
"""
try:
prefix, resulting_type = Naming.pop_prefix(string)
prefix += Naming.RESOURCE_PREFIX
except IndexError:
prefix = ''
resulting_type = string
resulting_type = dasherize(underscore(resulting_type))
return prefix + pluralize(resulting_type)
@staticmethod
def python(string: str):
"""
:param string: String can be type, resource or python case
"""
return underscore(singularize(string))
@staticmethod
def type(string: str):
try:
prefix, resulting_type = Naming.pop_prefix(string)
prefix += Naming.TYPE_PREFIX
except IndexError:
prefix = ''
resulting_type = string
resulting_type = singularize(resulting_type)
resulting_type = resulting_type.replace(
'-', '_'
) # camelize does not convert '-' but '_'
return prefix + camelize(resulting_type)
@staticmethod
def url_word(word: str):
"""
Normalizes a full word to be inserted to an url. If the word has spaces, etc, is used '_' and not '-'
"""
return parameterize(word, '_')
@staticmethod
def pop_prefix(string: str):
"""Erases the prefix and returns it.
:throws IndexError: There is no prefix.
:return A set with two elements: 1- the prefix, 2- the type without it.
"""
result = string.split(Naming.TYPE_PREFIX)
if len(result) == 1:
result = string.split(Naming.RESOURCE_PREFIX)
if len(result) == 1:
raise IndexError()
return result
@staticmethod
def new_type(type_name: str, prefix: str or None = None) -> str:
"""
Creates a resource type with optionally a prefix.
Using the rules of JSON-LD, we use prefixes to disambiguate between different types with the same name:
one can Accept a device or a project. In eReuse.org there are different events with the same names, in
linked-data terms they have different URI. In eReuse.org, we solve this with the following:
"@type": "devices:Accept" // the URI for these events is 'devices/events/accept'
"@type": "projects:Accept" // the URI for these events is 'projects/events/accept
...
Type is only used in events, when there are ambiguities. The rest of
"@type": "devices:Accept"
"@type": "Accept"
But these not:
"@type": "projects:Accept" // it is an event from a project
"@type": "Accept" // it is an event from a device
"""
if Naming.TYPE_PREFIX in type_name:
raise TypeError(
'Cannot create new type: type {} is already prefixed.'.format(type_name)
)
prefix = (prefix + Naming.TYPE_PREFIX) if prefix is not None else ''
return prefix + type_name
@staticmethod
def hid(type: str, manufacturer: str, model: str, serial_number: str) -> str:
(
"""Computes the HID for the given properties of a device.
The HID is suitable to use to an URI.
"""
+ HID_CONVERSION_DOC
)
return '{type}-{mn}-{ml}-{sn}'.format(
type=Naming.url_word(type),
mn=Naming.url_word(manufacturer),
ml=Naming.url_word(model),
sn=Naming.url_word(serial_number),
)

View File

@ -0,0 +1,85 @@
class NestedLookup:
@staticmethod
def __new__(cls, document, references, operation):
"""Lookup a key in a nested document, return a list of values
From https://github.com/russellballestrini/nested-lookup/ but in python 3
"""
return list(NestedLookup._nested_lookup(document, references, operation))
@staticmethod
def key_equality_factory(key_to_find):
def key_equality(key, _):
return key == key_to_find
return key_equality
@staticmethod
def is_sub_type_factory(type):
def _is_sub_type(_, value):
return is_sub_type(value, type)
return _is_sub_type
@staticmethod
def key_value_equality_factory(key_to_find, value_to_find):
def key_value_equality(key, value):
return key == key_to_find and value == value_to_find
return key_value_equality
@staticmethod
def key_value_containing_value_factory(key_to_find, value_to_find):
def key_value_containing_value(key, value):
return key == key_to_find and value_to_find in value
return key_value_containing_value
@staticmethod
def _nested_lookup(document, references, operation): # noqa: C901
"""Lookup a key in a nested document, yield a value"""
if isinstance(document, list):
for d in document:
for result in NestedLookup._nested_lookup(d, references, operation):
yield result
if isinstance(document, dict):
for k, v in document.items():
if operation(k, v):
references.append((document, k))
yield v
elif isinstance(v, dict):
for result in NestedLookup._nested_lookup(v, references, operation):
yield result
elif isinstance(v, list):
for d in v:
for result in NestedLookup._nested_lookup(
d, references, operation
):
yield result
def is_sub_type(value, resource_type):
try:
return issubclass(value, resource_type)
except TypeError:
return issubclass(value.__class__, resource_type)
def get_nested_dicts_with_key_value(parent_dict: dict, key, value):
"""Return all nested dictionaries that contain a key with a specific value. A sub-case of NestedLookup."""
references = []
NestedLookup(
parent_dict, references, NestedLookup.key_value_equality_factory(key, value)
)
return (document for document, _ in references)
def get_nested_dicts_with_key_containing_value(parent_dict: dict, key, value):
"""Return all nested dictionaries that contain a key with a specific value. A sub-case of NestedLookup."""
references = []
NestedLookup(
parent_dict,
references,
NestedLookup.key_value_containing_value_factory(key, value),
)
return (document for document, _ in references)

View File

@ -0,0 +1,285 @@
import base64
import json
from typing import Any, Dict, Iterable, Tuple, TypeVar, Union
import boltons.urlutils
from requests import Response
from requests_toolbelt.sessions import BaseUrlSession
from urllib3 import Retry
from ereuse_devicehub import ereuse_utils
# mypy
Query = Iterable[Tuple[str, Any]]
Status = Union[int]
try:
from typing import Protocol # Only py 3.6+
except ImportError:
pass
else:
class HasStatusProperty(Protocol):
def __init__(self, *args, **kwargs) -> None:
self.status = ... # type: int
Status = Union[int, HasStatusProperty]
JSON = 'application/json'
ANY = '*/*'
AUTH = 'Authorization'
BASIC = 'Basic {}'
URL = Union[str, boltons.urlutils.URL]
Data = Union[str, dict, ereuse_utils.Dumpeable]
Res = Tuple[Union[Dict[str, Any], str], Response]
# actual code
class Session(BaseUrlSession):
"""A BaseUrlSession that always raises for status and sets a
timeout for all requests by default.
"""
def __init__(self, base_url=None, timeout=15):
"""
:param base_url:
:param timeout: Time requests will wait to receive the first
response bytes (not the whole) from the server. In seconds.
"""
super().__init__(base_url)
self.timeout = timeout
self.hooks['response'] = lambda r, *args, **kwargs: r.raise_for_status()
def request(self, method, url, *args, **kwargs):
kwargs.setdefault('timeout', self.timeout)
return super().request(method, url, *args, **kwargs)
def __repr__(self):
return '<{} base={}>.'.format(self.__class__.__name__, self.base_url)
class DevicehubClient(Session):
"""A Session pre-configured to connect to Devicehub-like APIs."""
def __init__(self, base_url: URL = None,
token: str = None,
inventory: Union[str, bool] = False,
**kwargs):
"""Initializes a session pointing to a Devicehub endpoint.
Authentication can be passed-in as a token for endpoints
that require them, now at ini, after when executing the method,
or in between with ``set_auth``.
:param base_url: An url pointing to a endpoint.
:param token: A Base64 encoded token, as given by a devicehub.
You can encode tokens by executing `encode_token`.
:param inventory: If True, use the default inventory of the user.
If False, do not use inventories (single-inventory
database, this is the option by default).
If a string, always use the set inventory.
"""
if isinstance(base_url, boltons.urlutils.URL):
base_url = base_url.to_text()
else:
base_url = str(base_url)
super().__init__(base_url, **kwargs)
assert base_url[-1] != '/', 'Do not provide a final slash to the URL'
if token:
self.set_auth(token)
self.inventory = inventory
self.user = None # type: Dict[str, object]
def set_auth(self, token):
self.headers['Authorization'] = 'Basic {}'.format(token)
@classmethod
def encode_token(cls, token: str):
"""Encodes a token suitable for a Devicehub endpoint."""
return base64.b64encode(str.encode(str(token) + ':')).decode()
def login(self, email: str, password: str) -> Dict[str, Any]:
"""Performs login, authenticating future requests.
:return: The logged-in user.
"""
user, _ = self.post('/users/login/', {'email': email, 'password': password}, status=200)
self.set_auth(user['token'])
self.user = user
self.inventory = user['inventories'][0]['id']
return user
def get(self,
base_url: URL,
uri=None,
status: Status = 200,
query: Query = tuple(),
accept=JSON,
content_type=JSON,
headers: dict = None,
token=None,
**kwargs) -> Res:
return super().get(base_url,
uri=uri,
status=status,
query=query,
accept=accept,
content_type=content_type,
headers=headers,
token=token, **kwargs)
def post(self, base_url: URL,
data: Data,
uri=None,
status: Status = 201,
query: Query = tuple(),
accept=JSON,
content_type=JSON,
headers: dict = None,
token=None,
**kwargs) -> Res:
return super().post(base_url,
data=data,
uri=uri,
status=status,
query=query,
accept=accept,
content_type=content_type,
headers=headers,
token=token, **kwargs)
def delete(self,
base_url: URL,
uri=None,
status: Status = 204,
query: Query = tuple(),
accept=JSON,
content_type=JSON,
headers: dict = None,
token=None,
**kwargs) -> Res:
return super().delete(base_url,
uri=uri,
status=status,
query=query,
accept=accept,
content_type=content_type,
headers=headers,
token=token, **kwargs)
def patch(self, base_url: URL,
data: Data,
uri=None,
status: Status = 201,
query: Query = tuple(),
accept=JSON,
content_type=JSON,
headers: dict = None,
token=None,
**kwargs) -> Res:
return super().patch(base_url,
data=data,
uri=uri,
status=status,
query=query,
accept=accept,
content_type=content_type,
headers=headers,
token=token, **kwargs)
def request(self,
method,
base_url: URL,
uri=None,
status: Status = 200,
query: Query = tuple(),
accept=JSON,
content_type=JSON,
data=None,
headers: dict = None,
token=None,
**kw) -> Res:
assert not kw.get('json', None), 'Do not use json; use data.'
# We allow uris without slashes for item endpoints
uri = str(uri) if uri else None
headers = headers or {}
headers['Accept'] = accept
headers['Content-Type'] = content_type
if token:
headers['Authorization'] = 'Basic {}'.format(token)
if data and content_type == JSON:
data = json.dumps(data, cls=ereuse_utils.JSONEncoder, sort_keys=True)
url = base_url if not isinstance(base_url, boltons.urlutils.URL) else base_url.to_text()
assert url[-1] == '/', 'base_url should end with a slash'
if self.inventory and not isinstance(self.inventory, bool):
url = '{}/{}'.format(self.inventory, base_url)
assert url[-1] == '/', 'base_url should end with a slash'
if uri:
url = self.parse_uri(url, uri)
if query:
url = self.parse_query(url, query)
response = super().request(method, url, data=data, headers=headers, **kw)
if status:
_status = getattr(status, 'code', status)
if _status != response.status_code:
raise WrongStatus('Req to {} failed bc the status is {} but it should have been {}'
.format(url, response.status_code, _status))
data = response.content if not accept == JSON or not response.content else response.json()
return data, response
@staticmethod
def parse_uri(base_url, uri):
return boltons.urlutils.URL(base_url).navigate(uri).to_text()
@staticmethod
def parse_query(uri, query):
url = boltons.urlutils.URL(uri)
url.query_params = boltons.urlutils.QueryParamDict([
(k, json.dumps(v, cls=ereuse_utils.JSONEncoder) if isinstance(v, (list, dict)) else v)
for k, v in query
])
return url.to_text()
def __repr__(self):
return '<{} base={} inv={} user={}>.'.format(self.__class__.__name__, self.base_url,
self.inventory, self.user)
class WrongStatus(Exception):
pass
import requests
from requests.adapters import HTTPAdapter
T = TypeVar('T', bound=requests.Session)
def retry(session: T,
retries=3,
backoff_factor=1,
status_to_retry=(500, 502, 504)) -> T:
"""Configures requests from the given session to retry in
failed requests due to connection errors, HTTP response codes
with ``status_to_retry`` and 30X redirections.
Remember that you still need
"""
# From https://www.peterbe.com/plog/best-practice-with-retries-with-requests
# Doc in https://urllib3.readthedocs.io/en/latest/reference/urllib3.util.html#module-urllib3.util.retry
session = session or requests.Session()
retry = Retry(
total=retries,
read=retries,
connect=retries,
backoff_factor=backoff_factor,
status_forcelist=status_to_retry,
method_whitelist=False # Retry too in non-idempotent methods like POST
)
adapter = HTTPAdapter(max_retries=retry)
session.mount('http://', adapter)
session.mount('https://', adapter)
return session

View File

@ -0,0 +1,165 @@
from contextlib import suppress
from typing import Dict, Tuple, Union
from flask import json
from flask.testing import FlaskClient
from werkzeug.wrappers import Response
from ereuse_devicehub.ereuse_utils.session import ANY, AUTH, BASIC, DevicehubClient, JSON, Query, Status
ANY = ANY
AUTH = AUTH
BASIC = BASIC
Res = Tuple[Union[Dict[str, object], str], Response]
class Client(FlaskClient):
"""
A client for the REST servers of DeviceHub and WorkbenchServer.
- JSON first. By default it sends and expects receiving JSON files.
- Assert regular status responses, like 200 for GET.
- Auto-parses a nested dictionary of URL query params to the
URL version with nested properties to JSON.
- Meaningful headers format: a dictionary of name-values.
"""
def open(self,
uri: str,
status: Status = 200,
query: Query = tuple(),
accept=JSON,
content_type=JSON,
item=None,
headers: dict = None,
**kw) -> Res:
"""
:param uri: The URI without basename and query.
:param status: Assert the response for specified status. Set
None to avoid.
:param query: The query of the URL in the form of
[(key1, value1), (key2, value2), (key1, value3)].
If value is a list or a dict, they will be
converted to JSON.
Please, see :class:`boltons.urlutils`.
QueryParamDict` for more info.
:param accept: The Accept header. If 'application/json'
(default) then it will parse incoming JSON.
:param item: The last part of the path. Useful to do something
like ``get('db/accounts', item='24')``. If you
use ``item``, you can't set a final backslash into
``uri`` (or the parse will fail).
:param headers: A dictionary of headers, where keys are header
names and values their values.
Ex: {'Accept', 'application/json'}.
:param kw: Kwargs passed into parent ``open``.
:return: A tuple with: 1. response data, as a string or JSON
depending of Accept, and 2. the Response object.
"""
j_encoder = self.application.json_encoder
headers = headers or {}
headers['Accept'] = accept
headers['Content-Type'] = content_type
headers = [(k, v) for k, v in headers.items()]
if 'data' in kw and content_type == JSON:
kw['data'] = json.dumps(kw['data'], cls=j_encoder)
if item:
uri = DevicehubClient.parse_uri(uri, item)
if query:
uri = DevicehubClient.parse_query(uri, query)
response = super().open(uri, headers=headers, **kw)
if status:
_status = getattr(status, 'code', status)
assert response.status_code == _status, \
'Expected status code {} but got {}. Returned data is:\n' \
'{}'.format(_status, response.status_code, response.get_data().decode())
data = response.get_data()
with suppress(UnicodeDecodeError):
data = data.decode()
if accept == JSON:
data = json.loads(data) if data else {}
return data, response
def get(self,
uri: str,
query: Query = tuple(),
item: str = None,
status: Status = 200,
accept: str = JSON,
headers: dict = None,
**kw) -> Res:
"""
Performs a GET.
See the parameters in :meth:`ereuse_utils.test.Client.open`.
Moreover:
:param query: A dictionary of query params. If a parameter is a
dict or a list, it will be parsed to JSON, then
all params are encoded with ``urlencode``.
:param kw: Kwargs passed into parent ``open``.
"""
return super().get(uri, item=item, status=status, accept=accept, headers=headers,
query=query, **kw)
def post(self,
uri: str,
data: str or dict,
query: Query = tuple(),
status: Status = 201,
content_type: str = JSON,
accept: str = JSON,
headers: dict = None,
**kw) -> Res:
"""
Performs a POST.
See the parameters in :meth:`ereuse_utils.test.Client.open`.
"""
return super().post(uri, data=data, status=status, content_type=content_type,
accept=accept, headers=headers, query=query, **kw)
def patch(self,
uri: str,
data: str or dict,
query: Query = tuple(),
status: Status = 200,
content_type: str = JSON,
item: str = None,
accept: str = JSON,
headers: dict = None,
**kw) -> Res:
"""
Performs a PATCH.
See the parameters in :meth:`ereuse_utils.test.Client.open`.
"""
return super().patch(uri, item=item, data=data, status=status, content_type=content_type,
accept=accept, headers=headers, query=query, **kw)
def put(self,
uri: str,
data: str or dict,
query: Query = tuple(),
status: Status = 201,
content_type: str = JSON,
item: str = None,
accept: str = JSON,
headers: dict = None,
**kw) -> Res:
return super().put(uri, item=item, data=data, status=status, content_type=content_type,
accept=accept, headers=headers, query=query, **kw)
def delete(self,
uri: str,
query: Query = tuple(),
item: str = None,
status: Status = 204,
accept: str = JSON,
headers: dict = None,
**kw) -> Res:
return super().delete(uri, query=query, item=item, status=status, accept=accept,
headers=headers, **kw)

View File

@ -0,0 +1,72 @@
import ast
import re
from typing import Iterator, Set, Union
def grep(text: str, value: str):
"""An easy 'grep -i' that yields lines where value is found."""
for line in text.splitlines():
if value in line:
yield line
def between(text: str, begin='(', end=')'):
"""Dead easy text between two characters.
Not recursive or repetitions.
"""
return text.split(begin)[-1].split(end)[0]
def numbers(text: str) -> Iterator[Union[int, float]]:
"""Gets numbers in strings with other characters.
Integer Numbers: 1 2 3 987 +4 -8
Decimal Numbers: 0.1 2. .3 .987 +4.0 -0.8
Scientific Notation: 1e2 0.2e2 3.e2 .987e2 +4e-1 -8.e+2
Numbers with percentages: 49% 32.39%
This returns int or float.
"""
# From https://regexr.com/33jqd
for x in re.finditer(r'[+-]?(?=\.\d|\d)(?:\d+)?(?:\.?\d*)(?:[eE][+-]?\d+)?', text):
yield ast.literal_eval(x.group())
def positive_percentages(
text: str, lengths: Set[int] = None, decimal_numbers: int = None
) -> Iterator[Union[int, float]]:
"""Gets numbers postfixed with a '%' in strings with other characters.
1)100% 2)56.78% 3)56 78.90% 4)34.6789% some text
:param text: The text to search for.
:param lengths: A set of lengths that the percentage
number should have to be considered valid.
Ex. {5,6} would validate '90.32' and '100.00'
"""
# From https://regexr.com/3aumh
for x in re.finditer(r'[\d|\.]+%', text):
num = x.group()[:-1]
if lengths:
if not len(num) in lengths:
continue
if decimal_numbers:
try:
pos = num.rindex('.')
except ValueError:
continue
else:
if len(num) - pos - 1 != decimal_numbers:
continue
yield float(num)
def macs(text: str) -> Iterator[str]:
"""Find MACs in strings with other characters."""
for x in re.finditer('{0}:{0}:{0}:{0}:{0}:{0}'.format(r'[a-fA-F0-9.+_-]+'), text):
yield x.group()
def clean(text: str) -> str:
"""Trims the text and replaces multiple spaces with a single space."""
return ' '.join(text.split())

View File

@ -0,0 +1,80 @@
import usb.core
import usb.util
from usb import CLASS_MASS_STORAGE
from ereuse_devicehub.ereuse_utils.naming import Naming
def plugged_usbs(multiple=True) -> map or dict: # noqa: C901
"""
Gets the plugged-in USB Flash drives (pen-drives).
If multiple is true, it returns a map, and a dict otherwise.
If multiple is false, this method will raise a :class:`.NoUSBFound` if no USB is found.
"""
class FindPenDrives(object):
# From https://github.com/pyusb/pyusb/blob/master/docs/tutorial.rst
def __init__(self, class_):
self._class = class_
def __call__(self, device):
# first, let's check the device
if device.bDeviceClass == self._class:
return True
# ok, transverse all devices to find an
# interface that matches our class
for cfg in device:
# find_descriptor: what's it?
intf = usb.util.find_descriptor(cfg, bInterfaceClass=self._class)
# We don't want Card readers
if intf is not None:
try:
product = intf.device.product.lower()
except ValueError as e:
if 'langid' in str(e):
raise OSError(
'Cannot get "langid". Do you have permissions?'
)
else:
raise e
if 'crw' not in product and 'reader' not in product:
return True
return False
def get_pendrive(pen: usb.Device) -> dict:
if not pen.manufacturer or not pen.product or not pen.serial_number:
raise UsbDoesNotHaveHid()
manufacturer = pen.manufacturer.strip() or str(pen.idVendor)
model = pen.product.strip() or str(pen.idProduct)
serial_number = pen.serial_number.strip()
hid = Naming.hid('USBFlashDrive', manufacturer, model, serial_number)
return {
'id': hid, # Make live easier to DeviceHubClient by using _id
'hid': hid,
'type': 'USBFlashDrive',
'serialNumber': serial_number,
'model': model,
'manufacturer': manufacturer,
'vendorId': pen.idVendor,
'productId': pen.idProduct,
}
result = usb.core.find(
find_all=multiple, custom_match=FindPenDrives(CLASS_MASS_STORAGE)
)
if multiple:
return map(get_pendrive, result)
else:
if not result:
raise NoUSBFound()
return get_pendrive(result)
class NoUSBFound(Exception):
pass
class UsbDoesNotHaveHid(Exception):
pass

View File

@ -1,8 +1,19 @@
from boltons.urlutils import URL
from flask import current_app as app
from flask import g, session
from flask_wtf import FlaskForm from flask_wtf import FlaskForm
from werkzeug.security import generate_password_hash from werkzeug.security import generate_password_hash
from wtforms import BooleanField, EmailField, PasswordField, validators from wtforms import (
BooleanField,
EmailField,
PasswordField,
StringField,
URLField,
validators,
)
from ereuse_devicehub.resources.user.models import User from ereuse_devicehub.db import db
from ereuse_devicehub.resources.user.models import SanitizationEntity, User
class LoginForm(FlaskForm): class LoginForm(FlaskForm):
@ -58,4 +69,124 @@ class LoginForm(FlaskForm):
if not user.is_active: if not user.is_active:
self.form_errors.append(self.error_messages['inactive']) self.form_errors.append(self.error_messages['inactive'])
if 'dpp' in app.blueprints.keys():
dlt_keys = user.get_dlt_keys(
self.password.data
).get('data', {})
token_dlt = dlt_keys.get('api_token')
eth_pub_key = dlt_keys.get('eth_pub_key')
session['token_dlt'] = token_dlt
session['eth_pub_key'] = eth_pub_key
session['rols'] = user.get_rols()
return user.is_active return user.is_active
class PasswordForm(FlaskForm):
password = PasswordField(
'Current Password',
[validators.DataRequired()],
render_kw={'class': "form-control"},
)
newpassword = PasswordField(
'New Password',
[validators.DataRequired()],
render_kw={'class': "form-control"},
)
renewpassword = PasswordField(
'Re-enter New Password',
[validators.DataRequired()],
render_kw={'class': "form-control"},
)
def validate(self, extra_validators=None):
is_valid = super().validate(extra_validators)
if not is_valid:
return False
if not g.user.check_password(self.password.data):
return False
if self.newpassword.data != self.renewpassword.data:
return False
return True
def save(self, commit=True):
if 'dpp' in app.blueprints.keys():
keys_dlt = g.user.get_dlt_keys(self.password.data)
g.user.reset_dlt_keys(self.newpassword.data, keys_dlt)
token_dlt = (
g.user.get_dlt_keys(self.newpassword.data)
.get('data', {})
.get('api_token')
)
session['token_dlt'] = token_dlt
g.user.password = self.newpassword.data
db.session.add(g.user)
if commit:
db.session.commit()
return
class SanitizationEntityForm(FlaskForm):
logo = URLField(
'Logo',
[validators.Optional(), validators.URL()],
render_kw={
'class': "form-control",
"placeholder": "Url where is the logo - acceptd only .png, .jpg, .gif, svg",
},
)
company_name = StringField('Company Name', render_kw={'class': "form-control"})
location = StringField('Location', render_kw={'class': "form-control"})
responsable_person = StringField(
'Responsable person', render_kw={'class': "form-control"}
)
supervisor_person = StringField(
'Supervisor person', render_kw={'class': "form-control"}
)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if isinstance(self.logo.data, URL):
self.logo.data = self.logo.data.to_text()
def validate(self, extra_validators=None):
is_valid = super().validate(extra_validators)
if not is_valid:
return False
if not self.logo.data:
return True
extensions = ["jpg", "jpeg", "png", "gif", "svg"]
if self.logo.data.lower().split(".")[-1] not in extensions:
txt = "Error in Url field - accepted only .PNG, .JPG and .GIF. extensions"
self.logo.errors = [txt]
return False
return True
def save(self, commit=True):
if isinstance(self.logo.data, str):
self.logo.data = URL(self.logo.data)
sanitation_data = SanitizationEntity.query.filter_by(user_id=g.user.id).first()
if not sanitation_data:
sanitation_data = SanitizationEntity(user_id=g.user.id)
self.populate_obj(sanitation_data)
db.session.add(sanitation_data)
else:
self.populate_obj(sanitation_data)
if commit:
db.session.commit()
return

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,161 @@
from uuid import uuid4
from citext import CIText
from dateutil.tz import tzutc
from flask import g
from sortedcontainers import SortedSet
from sqlalchemy import BigInteger, Column, Integer
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import backref, relationship
from ereuse_devicehub.db import db
from ereuse_devicehub.resources.models import Thing
from ereuse_devicehub.resources.user.models import User
from ereuse_devicehub.teal.db import CASCADE_OWN, URL
class Transfer(Thing):
"""
The transfer is a transfer of possession of devices between
a user and a code (not system user)
"""
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid4)
code = Column(CIText(), default='', nullable=False)
date = Column(db.TIMESTAMP(timezone=True))
description = Column(CIText(), default='', nullable=True)
lot_id = db.Column(
UUID(as_uuid=True),
db.ForeignKey('lot.id', use_alter=True, name='lot_transfer'),
nullable=False,
)
lot = relationship(
'Lot',
backref=backref('transfer', lazy=True, uselist=False, cascade=CASCADE_OWN),
primaryjoin='Transfer.lot_id == Lot.id',
)
user_from_id = db.Column(UUID(as_uuid=True), db.ForeignKey(User.id), nullable=True)
user_from = db.relationship(User, primaryjoin=user_from_id == User.id)
user_to_id = db.Column(UUID(as_uuid=True), db.ForeignKey(User.id), nullable=True)
user_to = db.relationship(User, primaryjoin=user_to_id == User.id)
@property
def closed(self):
if self.date:
return True
return False
def type_transfer(self):
if self.user_from == g.user:
return 'Outgoing'
if self.user_to == g.user:
return 'Incoming'
return 'Temporary'
class DeliveryNote(Thing):
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid4)
number = Column(CIText(), default='', nullable=False)
date = Column(db.TIMESTAMP(timezone=True))
units = Column(Integer, default=0)
weight = Column(Integer, default=0)
transfer_id = db.Column(
UUID(as_uuid=True),
db.ForeignKey('transfer.id'),
nullable=False,
)
transfer = relationship(
'Transfer',
backref=backref('delivery_note', lazy=True, uselist=False, cascade=CASCADE_OWN),
primaryjoin='DeliveryNote.transfer_id == Transfer.id',
)
class ReceiverNote(Thing):
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid4)
number = Column(CIText(), default='', nullable=False)
date = Column(db.TIMESTAMP(timezone=True))
units = Column(Integer, default=0)
weight = Column(Integer, default=0)
transfer_id = db.Column(
UUID(as_uuid=True),
db.ForeignKey('transfer.id'),
nullable=False,
)
transfer = relationship(
'Transfer',
backref=backref('receiver_note', lazy=True, uselist=False, cascade=CASCADE_OWN),
primaryjoin='ReceiverNote.transfer_id == Transfer.id',
)
class TransferCustomerDetails(Thing):
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid4)
company_name = Column(CIText(), nullable=True)
location = Column(CIText(), nullable=True)
logo = Column(URL(), nullable=True)
transfer_id = db.Column(
UUID(as_uuid=True),
db.ForeignKey('transfer.id'),
nullable=False,
)
transfer = relationship(
'Transfer',
backref=backref(
'customer_details', lazy=True, uselist=False, cascade=CASCADE_OWN
),
primaryjoin='TransferCustomerDetails.transfer_id == Transfer.id',
)
_sorted_documents = {
'order_by': lambda: DeviceDocument.created,
'collection_class': SortedSet,
}
class DeviceDocument(Thing):
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid4)
type = Column(db.CIText(), nullable=True)
date = Column(db.DateTime, nullable=True)
id_document = Column(db.CIText(), nullable=True)
description = Column(db.CIText(), nullable=True)
owner_id = db.Column(
UUID(as_uuid=True),
db.ForeignKey(User.id),
nullable=False,
default=lambda: g.user.id,
)
owner = db.relationship(User, primaryjoin=owner_id == User.id)
device_id = db.Column(BigInteger, db.ForeignKey('device.id'), nullable=False)
device = db.relationship(
'Device',
primaryjoin='DeviceDocument.device_id == Device.id',
backref=backref(
'documents', lazy=True, cascade=CASCADE_OWN, **_sorted_documents
),
)
file_name = Column(db.CIText(), nullable=True)
file_hash = Column(db.CIText(), nullable=True)
url = db.Column(URL(), nullable=True)
# __table_args__ = (
# db.Index('document_id', id, postgresql_using='hash'),
# db.Index('type_doc', type, postgresql_using='hash')
# )
def get_url(self) -> str:
if self.url:
return self.url.to_text()
return ''
def __lt__(self, other):
return self.created.replace(tzinfo=tzutc()) < other.created.replace(
tzinfo=tzutc()
)

File diff suppressed because it is too large Load Diff

View File

@ -64,10 +64,7 @@ class PrintLabelsForm(FlaskForm):
.all() .all()
) )
# print only tags that are DHID if not self._devices:
dhids = [x.devicehub_id for x in self._devices] return False
self._tags = (
Tag.query.filter(Tag.owner_id == g.user.id).filter(Tag.id.in_(dhids)).all()
)
return is_valid return is_valid

View File

@ -8,7 +8,7 @@ from requests.exceptions import ConnectionError
from ereuse_devicehub import __version__, messages from ereuse_devicehub import __version__, messages
from ereuse_devicehub.labels.forms import PrintLabelsForm, TagForm, TagUnnamedForm from ereuse_devicehub.labels.forms import PrintLabelsForm, TagForm, TagUnnamedForm
from ereuse_devicehub.resources.lot.models import Lot from ereuse_devicehub.resources.lot.models import Lot, ShareLot
from ereuse_devicehub.resources.tag.model import Tag from ereuse_devicehub.resources.tag.model import Tag
labels = Blueprint('labels', __name__, url_prefix='/labels') labels = Blueprint('labels', __name__, url_prefix='/labels')
@ -23,12 +23,16 @@ class TagListView(View):
def dispatch_request(self): def dispatch_request(self):
lots = Lot.query.filter(Lot.owner_id == current_user.id) lots = Lot.query.filter(Lot.owner_id == current_user.id)
tags = Tag.query.filter(Tag.owner_id == current_user.id).order_by(Tag.id) share_lots = ShareLot.query.filter_by(user_to_id=current_user.id)
tags = Tag.query.filter(Tag.owner_id == current_user.id).order_by(
Tag.created.desc()
)
context = { context = {
'lots': lots, 'lots': lots,
'tags': tags, 'tags': tags,
'page_title': 'Tags Management', 'page_title': 'Unique Identifiers Management',
'version': __version__, 'version': __version__,
'share_lots': share_lots,
} }
return flask.render_template(self.template_name, **context) return flask.render_template(self.template_name, **context)
@ -40,7 +44,13 @@ class TagAddView(View):
def dispatch_request(self): def dispatch_request(self):
lots = Lot.query.filter(Lot.owner_id == current_user.id) lots = Lot.query.filter(Lot.owner_id == current_user.id)
context = {'page_title': 'New Tag', 'lots': lots, 'version': __version__} share_lots = ShareLot.query.filter_by(user_to_id=current_user.id)
context = {
'page_title': 'New Tag',
'lots': lots,
'version': __version__,
'share_lots': share_lots,
}
form = TagForm() form = TagForm()
if form.validate_on_submit(): if form.validate_on_submit():
form.save() form.save()
@ -57,10 +67,12 @@ class TagAddUnnamedView(View):
def dispatch_request(self): def dispatch_request(self):
lots = Lot.query.filter(Lot.owner_id == current_user.id) lots = Lot.query.filter(Lot.owner_id == current_user.id)
share_lots = ShareLot.query.filter_by(user_to_id=current_user.id)
context = { context = {
'page_title': 'New Unnamed Tag', 'page_title': 'New Unnamed Tag',
'lots': lots, 'lots': lots,
'version': __version__, 'version': __version__,
'share_lots': share_lots,
} }
form = TagUnnamedForm() form = TagUnnamedForm()
if form.validate_on_submit(): if form.validate_on_submit():
@ -92,17 +104,19 @@ class PrintLabelsView(View):
def dispatch_request(self): def dispatch_request(self):
lots = Lot.query.filter(Lot.owner_id == current_user.id) lots = Lot.query.filter(Lot.owner_id == current_user.id)
share_lots = ShareLot.query.filter_by(user_to_id=current_user.id)
context = { context = {
'lots': lots, 'lots': lots,
'page_title': self.title, 'page_title': self.title,
'version': __version__, 'version': __version__,
'referrer': request.referrer, 'referrer': request.referrer,
'share_lots': share_lots,
} }
form = PrintLabelsForm() form = PrintLabelsForm()
if form.validate_on_submit(): if form.validate_on_submit():
context['form'] = form context['form'] = form
context['tags'] = form._tags context['devices'] = form._devices
return flask.render_template(self.template_name, **context) return flask.render_template(self.template_name, **context)
else: else:
messages.error('Error you need select one or more devices') messages.error('Error you need select one or more devices')
@ -112,21 +126,37 @@ class PrintLabelsView(View):
class LabelDetailView(View): class LabelDetailView(View):
"""This View is used to print labels from multiple devices"""
methods = ['POST', 'GET']
decorators = [login_required] decorators = [login_required]
template_name = 'labels/label_detail.html' template_name = 'labels/print_labels.html'
title = 'Design and implementation of labels'
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)
share_lots = ShareLot.query.filter_by(user_to_id=current_user.id)
tag = ( tag = (
Tag.query.filter(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,
'tag': tag, 'page_title': self.title,
'page_title': '{} Tag'.format(tag.code),
'version': __version__, 'version': __version__,
'referrer': request.referrer,
'share_lots': share_lots,
} }
devices = []
if tag.device:
form = PrintLabelsForm(devices=str(tag.device.id))
devices = [tag.device]
else:
form = PrintLabelsForm()
form._devices = devices
context['form'] = form
context['devices'] = devices
return flask.render_template(self.template_name, **context) return flask.render_template(self.template_name, **context)

View File

View File

@ -0,0 +1,622 @@
# -*- coding: utf-8 -*-
"""
flaskext.mail
~~~~~~~~~~~~~
Flask extension for sending email.
:copyright: (c) 2010 by Dan Jacob.
:license: BSD, see LICENSE for more details.
"""
from __future__ import with_statement
__version__ = '0.9.1'
import re
import smtplib
import sys
import time
import unicodedata
from contextlib import contextmanager
from email import charset
from email.encoders import encode_base64
from email.header import Header
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.utils import formataddr, formatdate, make_msgid, parseaddr
import blinker
from flask import current_app
PY3 = sys.version_info[0] == 3
PY34 = PY3 and sys.version_info[1] >= 4
basestring = str
unicode = str
if PY3:
string_types = (str,)
text_type = str
from email import policy
message_policy = policy.SMTP
else:
string_types = (basestring,)
text_type = unicode
message_policy = None
charset.add_charset('utf-8', charset.SHORTEST, None, 'utf-8')
class FlaskMailUnicodeDecodeError(UnicodeDecodeError):
def __init__(self, obj, *args):
self.obj = obj
UnicodeDecodeError.__init__(self, *args)
def __str__(self):
original = UnicodeDecodeError.__str__(self)
return '%s. You passed in %r (%s)' % (original, self.obj, type(self.obj))
def force_text(s, encoding='utf-8', errors='strict'):
"""
Similar to smart_text, except that lazy instances are resolved to
strings, rather than kept as lazy objects.
If strings_only is True, don't convert (some) non-string-like objects.
"""
strings_only = True
if isinstance(s, text_type):
return s
try:
if not isinstance(s, string_types):
if PY3:
if isinstance(s, bytes):
s = text_type(s, encoding, errors)
else:
s = text_type(s)
elif hasattr(s, '__unicode__'):
s = s.__unicode__()
else:
s = text_type(bytes(s), encoding, errors)
else:
s = s.decode(encoding, errors)
except UnicodeDecodeError as e:
if not isinstance(s, Exception):
raise FlaskMailUnicodeDecodeError(s, *e.args)
else:
s = ' '.join([force_text(arg, encoding, strings_only, errors) for arg in s])
return s
def sanitize_subject(subject, encoding='utf-8'):
try:
subject.encode('ascii')
except UnicodeEncodeError:
try:
subject = Header(subject, encoding).encode()
except UnicodeEncodeError:
subject = Header(subject, 'utf-8').encode()
return subject
def sanitize_address(addr, encoding='utf-8'):
if isinstance(addr, string_types):
addr = parseaddr(force_text(addr))
nm, addr = addr
try:
nm = Header(nm, encoding).encode()
except UnicodeEncodeError:
nm = Header(nm, 'utf-8').encode()
try:
addr.encode('ascii')
except UnicodeEncodeError: # IDN
if '@' in addr:
localpart, domain = addr.split('@', 1)
localpart = str(Header(localpart, encoding))
domain = domain.encode('idna').decode('ascii')
addr = '@'.join([localpart, domain])
else:
addr = Header(addr, encoding).encode()
return formataddr((nm, addr))
def sanitize_addresses(addresses, encoding='utf-8'):
return map(lambda e: sanitize_address(e, encoding), addresses)
def _has_newline(line):
"""Used by has_bad_header to check for \\r or \\n"""
if line and ('\r' in line or '\n' in line):
return True
return False
class Connection(object):
"""Handles connection to host."""
def __init__(self, mail):
self.mail = mail
def __enter__(self):
if self.mail.suppress:
self.host = None
else:
self.host = self.configure_host()
self.num_emails = 0
return self
def __exit__(self, exc_type, exc_value, tb):
if self.host:
self.host.quit()
def configure_host(self):
if self.mail.use_ssl:
host = smtplib.SMTP_SSL(self.mail.server, self.mail.port)
else:
host = smtplib.SMTP(self.mail.server, self.mail.port)
host.set_debuglevel(int(self.mail.debug))
if self.mail.use_tls:
host.starttls()
if self.mail.username and self.mail.password:
host.login(self.mail.username, self.mail.password)
return host
def send(self, message, envelope_from=None):
"""Verifies and sends message.
:param message: Message instance.
:param envelope_from: Email address to be used in MAIL FROM command.
"""
assert message.send_to, "No recipients have been added"
assert message.sender, (
"The message does not specify a sender and a default sender "
"has not been configured"
)
if message.has_bad_headers():
raise BadHeaderError
if message.date is None:
message.date = time.time()
if self.host:
self.host.sendmail(
sanitize_address(envelope_from or message.sender),
list(sanitize_addresses(message.send_to)),
message.as_bytes() if PY3 else message.as_string(),
message.mail_options,
message.rcpt_options,
)
email_dispatched.send(message, app=current_app._get_current_object())
self.num_emails += 1
if self.num_emails == self.mail.max_emails:
self.num_emails = 0
if self.host:
self.host.quit()
self.host = self.configure_host()
def send_message(self, *args, **kwargs):
"""Shortcut for send(msg).
Takes same arguments as Message constructor.
:versionadded: 0.3.5
"""
self.send(Message(*args, **kwargs))
class BadHeaderError(Exception):
pass
class Attachment(object):
"""Encapsulates file attachment information.
:versionadded: 0.3.5
:param filename: filename of attachment
:param content_type: file mimetype
:param data: the raw file data
:param disposition: content-disposition (if any)
"""
def __init__(
self,
filename=None,
content_type=None,
data=None,
disposition=None,
headers=None,
):
self.filename = filename
self.content_type = content_type
self.data = data
self.disposition = disposition or 'attachment'
self.headers = headers or {}
class Message(object):
"""Encapsulates an email message.
:param subject: email subject header
:param recipients: list of email addresses
:param body: plain text message
:param html: HTML message
:param sender: email sender address, or **MAIL_DEFAULT_SENDER** by default
:param cc: CC list
:param bcc: BCC list
:param attachments: list of Attachment instances
:param reply_to: reply-to address
:param date: send date
:param charset: message character set
:param extra_headers: A dictionary of additional headers for the message
:param mail_options: A list of ESMTP options to be used in MAIL FROM command
:param rcpt_options: A list of ESMTP options to be used in RCPT commands
"""
def __init__(
self,
subject='',
recipients=None,
body=None,
html=None,
sender=None,
cc=None,
bcc=None,
attachments=None,
reply_to=None,
date=None,
charset=None,
extra_headers=None,
mail_options=None,
rcpt_options=None,
):
sender = sender or current_app.extensions['mail'].default_sender
if isinstance(sender, tuple):
sender = "%s <%s>" % sender
self.recipients = recipients or []
self.subject = subject
self.sender = sender
self.reply_to = reply_to
self.cc = cc or []
self.bcc = bcc or []
self.body = body
self.html = html
self.date = date
self.msgId = make_msgid()
self.charset = charset
self.extra_headers = extra_headers
self.mail_options = mail_options or []
self.rcpt_options = rcpt_options or []
self.attachments = attachments or []
@property
def send_to(self):
return set(self.recipients) | set(self.bcc or ()) | set(self.cc or ())
def _mimetext(self, text, subtype='plain'):
"""Creates a MIMEText object with the given subtype (default: 'plain')
If the text is unicode, the utf-8 charset is used.
"""
charset = self.charset or 'utf-8'
return MIMEText(text, _subtype=subtype, _charset=charset)
def _message(self): # noqa: C901
"""Creates the email"""
ascii_attachments = current_app.extensions['mail'].ascii_attachments
encoding = self.charset or 'utf-8'
attachments = self.attachments or []
if len(attachments) == 0 and not self.html:
# No html content and zero attachments means plain text
msg = self._mimetext(self.body)
elif len(attachments) > 0 and not self.html:
# No html and at least one attachment means multipart
msg = MIMEMultipart()
msg.attach(self._mimetext(self.body))
else:
# Anything else
msg = MIMEMultipart()
alternative = MIMEMultipart('alternative')
alternative.attach(self._mimetext(self.body, 'plain'))
alternative.attach(self._mimetext(self.html, 'html'))
msg.attach(alternative)
if self.subject:
msg['Subject'] = sanitize_subject(force_text(self.subject), encoding)
msg['From'] = sanitize_address(self.sender, encoding)
msg['To'] = ', '.join(list(set(sanitize_addresses(self.recipients, encoding))))
msg['Date'] = formatdate(self.date, localtime=True)
# see RFC 5322 section 3.6.4.
msg['Message-ID'] = self.msgId
if self.cc:
msg['Cc'] = ', '.join(list(set(sanitize_addresses(self.cc, encoding))))
if self.reply_to:
msg['Reply-To'] = sanitize_address(self.reply_to, encoding)
if self.extra_headers:
for k, v in self.extra_headers.items():
msg[k] = v
SPACES = re.compile(r'[\s]+', re.UNICODE)
for attachment in attachments:
f = MIMEBase(*attachment.content_type.split('/'))
f.set_payload(attachment.data)
encode_base64(f)
filename = attachment.filename
if filename and ascii_attachments:
# force filename to ascii
filename = unicodedata.normalize('NFKD', filename)
filename = filename.encode('ascii', 'ignore').decode('ascii')
filename = SPACES.sub(u' ', filename).strip()
try:
filename and filename.encode('ascii')
except UnicodeEncodeError:
if not PY3:
filename = filename.encode('utf8')
filename = ('UTF8', '', filename)
f.add_header(
'Content-Disposition', attachment.disposition, filename=filename
)
for key, value in attachment.headers:
f.add_header(key, value)
msg.attach(f)
if message_policy:
msg.policy = message_policy
return msg
def as_string(self):
return self._message().as_string()
def as_bytes(self):
# if PY34:
# return self._message().as_bytes()
# else: # fallback for old Python (3) versions
# return self._message().as_string().encode(self.charset or 'utf-8')
return self._message().as_string().encode(self.charset or 'utf-8')
def __str__(self):
return self.as_string()
def __bytes__(self):
return self.as_bytes()
def has_bad_headers(self):
"""Checks for bad headers i.e. newlines in subject, sender or recipients.
RFC5322: Allows multiline CRLF with trailing whitespace (FWS) in headers
"""
headers = [self.sender, self.reply_to] + self.recipients
for header in headers:
if _has_newline(header):
return True
if self.subject:
if _has_newline(self.subject):
for linenum, line in enumerate(self.subject.split('\r\n')):
if not line:
return True
if linenum > 0 and line[0] not in '\t ':
return True
if _has_newline(line):
return True
if len(line.strip()) == 0:
return True
return False
def is_bad_headers(self):
from warnings import warn
msg = (
'is_bad_headers is deprecated, use the new has_bad_headers method instead.'
)
warn(DeprecationWarning(msg), stacklevel=1)
return self.has_bad_headers()
def send(self, connection):
"""Verifies and sends the message."""
connection.send(self)
def add_recipient(self, recipient):
"""Adds another recipient to the message.
:param recipient: email address of recipient.
"""
self.recipients.append(recipient)
def attach(
self,
filename=None,
content_type=None,
data=None,
disposition=None,
headers=None,
):
"""Adds an attachment to the message.
:param filename: filename of attachment
:param content_type: file mimetype
:param data: the raw file data
:param disposition: content-disposition (if any)
"""
self.attachments.append(
Attachment(filename, content_type, data, disposition, headers)
)
class _MailMixin(object):
@contextmanager
def record_messages(self):
"""Records all messages. Use in unit tests for example::
with mail.record_messages() as outbox:
response = app.test_client.get("/email-sending-view/")
assert len(outbox) == 1
assert outbox[0].subject == "testing"
You must have blinker installed in order to use this feature.
:versionadded: 0.4
"""
if not email_dispatched:
raise RuntimeError("blinker must be installed")
outbox = []
def _record(message, app):
outbox.append(message)
email_dispatched.connect(_record)
try:
yield outbox
finally:
email_dispatched.disconnect(_record)
def send(self, message):
"""Sends a single message instance. If TESTING is True the message will
not actually be sent.
:param message: a Message instance.
"""
with self.connect() as connection:
message.send(connection)
def send_message(self, *args, **kwargs):
"""Shortcut for send(msg).
Takes same arguments as Message constructor.
:versionadded: 0.3.5
"""
self.send(Message(*args, **kwargs))
def connect(self):
"""Opens a connection to the mail host."""
app = getattr(self, "app", None) or current_app
try:
return Connection(app.extensions['mail'])
except KeyError:
raise RuntimeError(
"The curent application was not configured with Flask-Mail"
)
class _Mail(_MailMixin):
def __init__(
self,
server,
username,
password,
port,
use_tls,
use_ssl,
default_sender,
debug,
max_emails,
suppress,
ascii_attachments=False,
):
self.server = server
self.username = username
self.password = password
self.port = port
self.use_tls = use_tls
self.use_ssl = use_ssl
self.default_sender = default_sender
self.debug = debug
self.max_emails = max_emails
self.suppress = suppress
self.ascii_attachments = ascii_attachments
class Mail(_MailMixin):
"""Manages email messaging
:param app: Flask instance
"""
def __init__(self, app=None):
self.app = app
if app is not None:
self.state = self.init_app(app)
else:
self.state = None
def init_mail(self, config, debug=False, testing=False):
return _Mail(
config.get('MAIL_SERVER', '127.0.0.1'),
config.get('MAIL_USERNAME'),
config.get('MAIL_PASSWORD'),
config.get('MAIL_PORT', 25),
config.get('MAIL_USE_TLS', False),
config.get('MAIL_USE_SSL', False),
config.get('MAIL_DEFAULT_SENDER'),
int(config.get('MAIL_DEBUG', debug)),
config.get('MAIL_MAX_EMAILS'),
config.get('MAIL_SUPPRESS_SEND', testing),
config.get('MAIL_ASCII_ATTACHMENTS', False),
)
def init_app(self, app):
"""Initializes your mail settings from the application settings.
You can use this if you want to set up your Mail instance
at configuration time.
:param app: Flask application instance
"""
state = self.init_mail(app.config, app.debug, app.testing)
# register extension with app
app.extensions = getattr(app, 'extensions', {})
app.extensions['mail'] = state
return state
def __getattr__(self, name):
return getattr(self.state, name, None)
signals = blinker.Namespace()
email_dispatched = signals.signal(
"email-dispatched",
doc="""
Signal sent when an email is dispatched. This signal will also be sent
in testing mode, even though the email will not actually be sent.
""",
)

View File

@ -0,0 +1,31 @@
import logging
from smtplib import SMTPException
from threading import Thread
from flask import current_app as app
from ereuse_devicehub.mail.flask_mail import Message
logger = logging.getLogger(__name__)
def _send_async_email(app, msg):
with app.app_context():
try:
app.mail.send(msg)
except SMTPException:
logger.exception("An error occurred while sending the email")
def send_email(
subject, recipients, text_body, sender=None, cc=None, bcc=None, html_body=None
):
msg = Message(subject, sender=sender, recipients=recipients, cc=cc, bcc=bcc)
msg.body = text_body
if html_body:
msg.html = html_body
Thread(target=_send_async_email, args=(app._get_current_object(), msg)).start()

View File

@ -1,14 +1,33 @@
from marshmallow.fields import missing_ from marshmallow.fields import missing_
from teal.db import SQLAlchemy
from teal.marshmallow import NestedOn as TealNestedOn
from ereuse_devicehub.db import db from ereuse_devicehub.db import db
from ereuse_devicehub.teal.db import SQLAlchemy
from ereuse_devicehub.teal.marshmallow import NestedOn as TealNestedOn
class NestedOn(TealNestedOn): class NestedOn(TealNestedOn):
__doc__ = TealNestedOn.__doc__ __doc__ = TealNestedOn.__doc__
def __init__(self, nested, polymorphic_on='type', db: SQLAlchemy = db, collection_class=list, def __init__(
default=missing_, exclude=tuple(), only_query: str = None, only=None, **kwargs): self,
super().__init__(nested, polymorphic_on, db, collection_class, default, exclude, nested,
only_query, only, **kwargs) polymorphic_on='type',
db: SQLAlchemy = db,
collection_class=list,
default=missing_,
exclude=tuple(),
only_query: str = None,
only=None,
**kwargs,
):
super().__init__(
nested,
polymorphic_on,
db,
collection_class,
default,
exclude,
only_query,
only,
**kwargs,
)

View File

@ -9,7 +9,7 @@ from alembic import op
import sqlalchemy as sa import sqlalchemy as sa
import sqlalchemy_utils import sqlalchemy_utils
import citext import citext
import teal from ereuse_devicehub import teal
${imports if imports else ""} ${imports if imports else ""}
# revision identifiers, used by Alembic. # revision identifiers, used by Alembic.

View File

@ -0,0 +1,124 @@
"""transfer
Revision ID: 054a3aea9f08
Revises: 926865284103
Create Date: 2022-05-27 11:07:18.245322
"""
from uuid import uuid4
import citext
import sqlalchemy as sa
from alembic import context, op
from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic.
revision = '054a3aea9f08'
down_revision = '926865284103'
branch_labels = None
depends_on = None
def get_inv():
INV = context.get_x_argument(as_dictionary=True).get('inventory')
if not INV:
raise ValueError("Inventory value is not specified")
return INV
def upgrade_datas():
sql = f'select user_from_id, user_to_id, lot_id, code from {get_inv()}.trade where confirm=False'
con = op.get_bind()
sql_phantom = 'select id from common.user where phantom=True'
phantoms = [x[0] for x in con.execute(sql_phantom)]
for ac in con.execute(sql):
id = uuid4()
user_from = ac.user_from_id
user_to = ac.user_to_id
lot = ac.lot_id
code = ac.code
columns = '(id, user_from_id, user_to_id, lot_id, code)'
values = f'(\'{id}\', \'{user_from}\', \'{user_to}\', \'{lot}\', \'{code}\')'
if user_to not in phantoms:
columns = '(id, user_to_id, lot_id, code)'
values = f'(\'{id}\', \'{user_to}\', \'{lot}\', \'{code}\')'
if user_from not in phantoms:
columns = '(id, user_from_id, lot_id, code)'
values = f'(\'{id}\', \'{user_from}\', \'{lot}\', \'{code}\')'
new_transfer = f'insert into {get_inv()}.transfer {columns} values {values}'
op.execute(new_transfer)
def upgrade():
# creating transfer table
op.create_table(
'transfer',
sa.Column(
'updated',
sa.TIMESTAMP(timezone=True),
server_default=sa.text('CURRENT_TIMESTAMP'),
nullable=False,
),
sa.Column(
'created',
sa.TIMESTAMP(timezone=True),
server_default=sa.text('CURRENT_TIMESTAMP'),
nullable=False,
),
sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False),
sa.Column('code', citext.CIText(), nullable=False),
sa.Column(
'description',
citext.CIText(),
nullable=True,
comment='A comment about the action.',
),
sa.Column('date', sa.TIMESTAMP(timezone=True), nullable=True),
sa.Column('lot_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.Column('user_to_id', postgresql.UUID(as_uuid=True), nullable=True),
sa.Column('user_from_id', postgresql.UUID(as_uuid=True), nullable=True),
sa.ForeignKeyConstraint(['lot_id'], [f'{get_inv()}.lot.id']),
sa.ForeignKeyConstraint(['user_from_id'], ['common.user.id']),
sa.ForeignKeyConstraint(['user_to_id'], ['common.user.id']),
sa.PrimaryKeyConstraint('id'),
schema=f'{get_inv()}',
)
# creating index
op.create_index(
op.f('ix_transfer_created'),
'transfer',
['created'],
unique=False,
schema=f'{get_inv()}',
)
op.create_index(
op.f('ix_transfer_updated'),
'transfer',
['updated'],
unique=False,
schema=f'{get_inv()}',
)
op.create_index(
'ix_transfer_id',
'transfer',
['id'],
unique=False,
postgresql_using='hash',
schema=f'{get_inv()}',
)
upgrade_datas()
def downgrade():
op.drop_index(
op.f('ix_transfer_created'), table_name='transfer', schema=f'{get_inv()}'
)
op.drop_index(
op.f('ix_transfer_updated'), table_name='transfer', schema=f'{get_inv()}'
)
op.drop_index(op.f('ix_transfer_id'), table_name='transfer', schema=f'{get_inv()}')
op.drop_table('transfer', schema=f'{get_inv()}')

View File

@ -10,7 +10,7 @@ from alembic import op
import sqlalchemy as sa import sqlalchemy as sa
import sqlalchemy_utils import sqlalchemy_utils
import citext import citext
import teal from ereuse_devicehub import teal
# revision identifiers, used by Alembic. # revision identifiers, used by Alembic.
@ -26,11 +26,32 @@ def get_inv():
raise ValueError("Inventory value is not specified") raise ValueError("Inventory value is not specified")
return INV return INV
def upgrade(): def upgrade():
op.alter_column('test_data_storage', 'current_pending_sector_count', type_=sa.Integer(), schema=f'{get_inv()}') op.alter_column(
op.alter_column('test_data_storage', 'offline_uncorrectable', type_=sa.Integer(), schema=f'{get_inv()}') 'test_data_storage',
'current_pending_sector_count',
type_=sa.Integer(),
schema=f'{get_inv()}',
)
op.alter_column(
'test_data_storage',
'offline_uncorrectable',
type_=sa.Integer(),
schema=f'{get_inv()}',
)
def downgrade(): def downgrade():
op.alter_column('test_data_storage', 'current_pending_sector_count', type_=sa.SmallInteger(), schema=f'{get_inv()}') op.alter_column(
op.alter_column('test_data_storage', 'offline_uncorrectable', type_=sa.SmallInteger(), schema=f'{get_inv()}') 'test_data_storage',
'current_pending_sector_count',
type_=sa.SmallInteger(),
schema=f'{get_inv()}',
)
op.alter_column(
'test_data_storage',
'offline_uncorrectable',
type_=sa.SmallInteger(),
schema=f'{get_inv()}',
)

View File

@ -0,0 +1,42 @@
"""change firewire
Revision ID: 17288b2a7440
Revises: 8571fb32c912
Create Date: 2022-03-29 11:49:39.270791
"""
import citext
import sqlalchemy as sa
from alembic import context, op
from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic.
revision = '17288b2a7440'
down_revision = '8571fb32c912'
branch_labels = None
depends_on = None
def get_inv():
INV = context.get_x_argument(as_dictionary=True).get('inventory')
if not INV:
raise ValueError("Inventory value is not specified")
return INV
def upgrade():
op.add_column(
'computer',
sa.Column('uuid', postgresql.UUID(as_uuid=True), nullable=True),
schema=f'{get_inv()}',
)
op.add_column(
'snapshot',
sa.Column('wbid', citext.CIText(), nullable=True),
schema=f'{get_inv()}',
)
def downgrade():
op.drop_column('computer', 'uuid', schema=f'{get_inv()}')
op.drop_column('snapshot', 'wbid', schema=f'{get_inv()}')

View File

@ -11,7 +11,7 @@ from sqlalchemy.dialects import postgresql
import sqlalchemy as sa import sqlalchemy as sa
import sqlalchemy_utils import sqlalchemy_utils
import citext import citext
import teal from ereuse_devicehub import teal
from ereuse_devicehub.resources.enums import SessionType from ereuse_devicehub.resources.enums import SessionType

View File

@ -0,0 +1,56 @@
"""add snapshot errors
Revision ID: 23d9e7ebbd7d
Revises: 17288b2a7440
Create Date: 2022-04-04 19:27:48.675387
"""
import citext
import sqlalchemy as sa
from alembic import context, op
from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic.
revision = '23d9e7ebbd7d'
down_revision = '17288b2a7440'
branch_labels = None
depends_on = None
def get_inv():
INV = context.get_x_argument(as_dictionary=True).get('inventory')
if not INV:
raise ValueError("Inventory value is not specified")
return INV
def upgrade():
op.create_table(
'snapshot_errors',
sa.Column(
'updated',
sa.TIMESTAMP(timezone=True),
server_default=sa.text('CURRENT_TIMESTAMP'),
nullable=False,
comment='The last time Devicehub recorded a change for \n this thing.\n ',
),
sa.Column(
'created',
sa.TIMESTAMP(timezone=True),
server_default=sa.text('CURRENT_TIMESTAMP'),
nullable=False,
comment='When Devicehub created this.',
),
sa.Column('id', sa.BigInteger(), nullable=False),
sa.Column('description', citext.CIText(), nullable=False),
sa.Column('snapshot_uuid', postgresql.UUID(as_uuid=True), nullable=False),
sa.Column('severity', sa.SmallInteger(), nullable=False),
sa.PrimaryKeyConstraint('id'),
schema=f'{get_inv()}',
)
op.execute(f"CREATE SEQUENCE {get_inv()}.snapshot_errors_seq START 1;")
def downgrade():
op.drop_table('snapshot_errors', schema=f'{get_inv()}')
op.execute(f"DROP SEQUENCE {get_inv()}.snapshot_errors_seq;")

View File

@ -0,0 +1,78 @@
"""add owner to placeholder
Revision ID: d7ea9a3b2da1
Revises: 2b90b41a556a
Create Date: 2022-07-27 14:40:15.513820
"""
import citext
import sqlalchemy as sa
from alembic import context, op
from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic.
revision = '2b90b41a556a'
down_revision = '3e3a67f62972'
branch_labels = None
depends_on = None
def get_inv():
INV = context.get_x_argument(as_dictionary=True).get('inventory')
if not INV:
raise ValueError("Inventory value is not specified")
return INV
def upgrade_data():
con = op.get_bind()
sql = f"select {get_inv()}.placeholder.id, {get_inv()}.device.owner_id from {get_inv()}.placeholder"
sql += f" join {get_inv()}.device on {get_inv()}.device.id={get_inv()}.placeholder.device_id;"
for c in con.execute(sql):
id_placeholder = c.id
id_owner = c.owner_id
sql_update = f"update {get_inv()}.placeholder set owner_id='{id_owner}', is_abstract=False where id={id_placeholder};"
con.execute(sql_update)
def upgrade():
op.add_column(
'placeholder',
sa.Column('is_abstract', sa.Boolean(), nullable=True),
schema=f'{get_inv()}',
)
op.add_column(
'placeholder',
sa.Column('components', citext.CIText(), nullable=True),
schema=f'{get_inv()}',
)
op.add_column(
'placeholder',
sa.Column('owner_id', postgresql.UUID(), nullable=True),
schema=f'{get_inv()}',
)
op.create_foreign_key(
"fk_placeholder_owner_id_user_id",
"placeholder",
"user",
["owner_id"],
["id"],
ondelete="SET NULL",
source_schema=f'{get_inv()}',
referent_schema='common',
)
upgrade_data()
def downgrade():
op.drop_constraint(
"fk_placeholder_owner_id_user_id",
"placeholder",
type_="foreignkey",
schema=f'{get_inv()}',
)
op.drop_column('placeholder', 'owner_id', schema=f'{get_inv()}')
op.drop_column('placeholder', 'is_abstract', schema=f'{get_inv()}')
op.drop_column('placeholder', 'components', schema=f'{get_inv()}')

View File

@ -0,0 +1,52 @@
"""share lot
Revision ID: 2f2ef041483a
Revises: ac476b60d952
Create Date: 2023-04-26 16:04:21.560888
"""
import sqlalchemy as sa
from alembic import context, op
from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic.
revision = '2f2ef041483a'
down_revision = 'ac476b60d952'
branch_labels = None
depends_on = None
def get_inv():
INV = context.get_x_argument(as_dictionary=True).get('inventory')
if not INV:
raise ValueError("Inventory value is not specified")
return INV
def upgrade():
op.create_table(
'share_lot',
sa.Column(
'created',
sa.TIMESTAMP(timezone=True),
server_default=sa.text('CURRENT_TIMESTAMP'),
nullable=False,
),
sa.Column(
'updated',
sa.TIMESTAMP(timezone=True),
server_default=sa.text('CURRENT_TIMESTAMP'),
nullable=False,
),
sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False),
sa.Column('user_to_id', postgresql.UUID(as_uuid=True), nullable=True),
sa.Column('lot_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.ForeignKeyConstraint(['user_to_id'], ['common.user.id']),
sa.ForeignKeyConstraint(['lot_id'], [f'{get_inv()}.lot.id']),
sa.PrimaryKeyConstraint('id'),
schema=f'{get_inv()}',
)
def downgrade():
op.drop_table('share_lot', schema=f'{get_inv()}')

View File

@ -5,12 +5,12 @@ Revises: bf600ca861a4
Create Date: 2020-12-16 11:45:13.339624 Create Date: 2020-12-16 11:45:13.339624
""" """
from alembic import context import citext
from alembic import op
import sqlalchemy as sa import sqlalchemy as sa
import sqlalchemy_utils import sqlalchemy_utils
import citext from alembic import context
import teal from alembic import op
from ereuse_devicehub import teal
# revision identifiers, used by Alembic. # revision identifiers, used by Alembic.

View File

@ -5,15 +5,14 @@ Revises: 51439cf24be8
Create Date: 2021-06-15 14:38:59.931818 Create Date: 2021-06-15 14:38:59.931818
""" """
import teal
import citext import citext
import sqlalchemy as sa import sqlalchemy as sa
from ereuse_devicehub import teal
from alembic import op from alembic import op
from alembic import context from alembic import context
from sqlalchemy.dialects import postgresql from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic. # revision identifiers, used by Alembic.
revision = '3a3601ac8224' revision = '3a3601ac8224'
down_revision = '51439cf24be8' down_revision = '51439cf24be8'
@ -27,108 +26,143 @@ def get_inv():
raise ValueError("Inventory value is not specified") raise ValueError("Inventory value is not specified")
return INV return INV
def upgrade(): def upgrade():
op.create_table('trade_document', op.create_table(
sa.Column( 'trade_document',
'updated', sa.Column(
sa.TIMESTAMP(timezone=True), 'updated',
server_default=sa.text('CURRENT_TIMESTAMP'), sa.TIMESTAMP(timezone=True),
nullable=False, server_default=sa.text('CURRENT_TIMESTAMP'),
comment='The last time Devicehub recorded a change for \n this thing.\n ' nullable=False,
), comment='The last time Devicehub recorded a change for \n this thing.\n ',
sa.Column( ),
'created', sa.Column(
sa.TIMESTAMP(timezone=True), 'created',
server_default=sa.text('CURRENT_TIMESTAMP'), sa.TIMESTAMP(timezone=True),
nullable=False, server_default=sa.text('CURRENT_TIMESTAMP'),
comment='When Devicehub created this.' nullable=False,
), comment='When Devicehub created this.',
sa.Column( ),
'id', sa.Column(
sa.BigInteger(), 'id',
nullable=False, sa.BigInteger(),
comment='The identifier of the device for this database. Used only\n internally for software; users should not use this.\n ' nullable=False,
), comment='The identifier of the device for this database. Used only\n internally for software; users should not use this.\n ',
sa.Column( ),
'date', sa.Column(
sa.DateTime(), 'date',
nullable=True, sa.DateTime(),
comment='The date of document, some documents need to have one date\n ' nullable=True,
), comment='The date of document, some documents need to have one date\n ',
sa.Column( ),
'id_document', sa.Column(
citext.CIText(), 'id_document',
nullable=True, citext.CIText(),
comment='The id of one document like invoice so they can be linked.' nullable=True,
), comment='The id of one document like invoice so they can be linked.',
sa.Column( ),
'description', sa.Column(
citext.CIText(), 'description',
nullable=True, citext.CIText(),
comment='A description of document.' nullable=True,
), comment='A description of document.',
sa.Column( ),
'owner_id', sa.Column('owner_id', postgresql.UUID(as_uuid=True), nullable=False),
postgresql.UUID(as_uuid=True), sa.Column('lot_id', postgresql.UUID(as_uuid=True), nullable=False),
nullable=False sa.Column(
), 'file_name',
sa.Column( citext.CIText(),
'lot_id', nullable=True,
postgresql.UUID(as_uuid=True), comment='This is the name of the file when user up the document.',
nullable=False ),
), sa.Column(
sa.Column( 'file_hash',
'file_name', citext.CIText(),
citext.CIText(), nullable=True,
nullable=True, comment='This is the hash of the file produced from frontend.',
comment='This is the name of the file when user up the document.' ),
), sa.Column(
sa.Column( 'url',
'file_hash', citext.CIText(),
citext.CIText(), teal.db.URL(),
nullable=True, nullable=True,
comment='This is the hash of the file produced from frontend.' comment='This is the url where resides the document.',
), ),
sa.Column( sa.ForeignKeyConstraint(
'url', ['lot_id'],
citext.CIText(), [f'{get_inv()}.lot.id'],
teal.db.URL(), ),
nullable=True, sa.ForeignKeyConstraint(
comment='This is the url where resides the document.' ['owner_id'],
), ['common.user.id'],
sa.ForeignKeyConstraint(['lot_id'], [f'{get_inv()}.lot.id'],), ),
sa.ForeignKeyConstraint(['owner_id'], ['common.user.id'],), sa.PrimaryKeyConstraint('id'),
sa.PrimaryKeyConstraint('id'), schema=f'{get_inv()}',
schema=f'{get_inv()}'
) )
# Action document table # Action document table
op.create_table('action_trade_document', op.create_table(
sa.Column('document_id', sa.BigInteger(), nullable=False), 'action_trade_document',
sa.Column('action_id', postgresql.UUID(as_uuid=True), nullable=False), sa.Column('document_id', sa.BigInteger(), nullable=False),
sa.ForeignKeyConstraint(['action_id'], [f'{get_inv()}.action.id'], ), sa.Column('action_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.ForeignKeyConstraint(['document_id'], [f'{get_inv()}.trade_document.id'], ), sa.ForeignKeyConstraint(
sa.PrimaryKeyConstraint('document_id', 'action_id'), ['action_id'],
schema=f'{get_inv()}' [f'{get_inv()}.action.id'],
) ),
sa.ForeignKeyConstraint(
['document_id'],
[f'{get_inv()}.trade_document.id'],
),
sa.PrimaryKeyConstraint('document_id', 'action_id'),
schema=f'{get_inv()}',
)
op.create_index('document_id', 'trade_document', ['id'], unique=False, postgresql_using='hash', schema=f'{get_inv()}') op.create_index(
op.create_index(op.f('ix_trade_document_created'), 'trade_document', ['created'], unique=False, schema=f'{get_inv()}') 'document_id',
op.create_index(op.f('ix_trade_document_updated'), 'trade_document', ['updated'], unique=False, schema=f'{get_inv()}') 'trade_document',
['id'],
unique=False,
postgresql_using='hash',
schema=f'{get_inv()}',
)
op.create_index(
op.f('ix_trade_document_created'),
'trade_document',
['created'],
unique=False,
schema=f'{get_inv()}',
)
op.create_index(
op.f('ix_trade_document_updated'),
'trade_document',
['updated'],
unique=False,
schema=f'{get_inv()}',
)
op.create_table('confirm_document', op.create_table(
sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False), 'confirm_document',
sa.Column('user_id', postgresql.UUID(as_uuid=True), nullable=False), sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False),
sa.Column('action_id', postgresql.UUID(as_uuid=True), nullable=False), sa.Column('user_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.Column('action_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.ForeignKeyConstraint(
['id'],
[f'{get_inv()}.action.id'],
),
sa.ForeignKeyConstraint(
['action_id'],
[f'{get_inv()}.action.id'],
),
sa.ForeignKeyConstraint(
['user_id'],
['common.user.id'],
),
sa.PrimaryKeyConstraint('id'),
schema=f'{get_inv()}',
)
sa.ForeignKeyConstraint(['id'], [f'{get_inv()}.action.id'], ),
sa.ForeignKeyConstraint(['action_id'], [f'{get_inv()}.action.id'], ),
sa.ForeignKeyConstraint(['user_id'], ['common.user.id'], ),
sa.PrimaryKeyConstraint('id'),
schema=f'{get_inv()}'
)
def downgrade(): def downgrade():
op.drop_table('action_trade_document', schema=f'{get_inv()}') op.drop_table('action_trade_document', schema=f'{get_inv()}')
op.drop_table('confirm_document', schema=f'{get_inv()}') op.drop_table('confirm_document', schema=f'{get_inv()}')
op.drop_table('trade_document', schema=f'{get_inv()}') op.drop_table('trade_document', schema=f'{get_inv()}')

View File

@ -0,0 +1,66 @@
"""placeholder log
Revision ID: 3e3a67f62972
Revises: aeca9fb50cc6
Create Date: 2022-07-06 18:23:54.267003
"""
import citext
import sqlalchemy as sa
from alembic import context, op
from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic.
revision = '3e3a67f62972'
down_revision = 'aeca9fb50cc6'
branch_labels = None
depends_on = None
def get_inv():
INV = context.get_x_argument(as_dictionary=True).get('inventory')
if not INV:
raise ValueError("Inventory value is not specified")
return INV
def upgrade():
op.create_table(
'placeholders_log',
sa.Column(
'updated',
sa.TIMESTAMP(timezone=True),
server_default=sa.text('CURRENT_TIMESTAMP'),
nullable=False,
comment='The last time Devicehub recorded a change for \n this thing.\n ',
),
sa.Column(
'created',
sa.TIMESTAMP(timezone=True),
server_default=sa.text('CURRENT_TIMESTAMP'),
nullable=False,
comment='When Devicehub created this.',
),
sa.Column('id', sa.BigInteger(), nullable=False),
sa.Column('source', citext.CIText(), nullable=True),
sa.Column('type', citext.CIText(), nullable=True),
sa.Column('severity', sa.SmallInteger(), nullable=False),
sa.Column('placeholder_id', sa.BigInteger(), nullable=True),
sa.Column('owner_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.ForeignKeyConstraint(
['placeholder_id'],
[f'{get_inv()}.placeholder.id'],
),
sa.ForeignKeyConstraint(
['owner_id'],
['common.user.id'],
),
sa.PrimaryKeyConstraint('id'),
schema=f'{get_inv()}',
)
op.execute("CREATE SEQUENCE placeholders_log_seq START 1;")
def downgrade():
op.drop_table('placeholders_log', schema=f'{get_inv()}')
op.execute("DROP SEQUENCE placeholders_log_seq;")

View File

@ -0,0 +1,39 @@
"""device other
Revision ID: 410aadae7652
Revises: d65745749e34
Create Date: 2022-11-29 12:00:40.272121
"""
import sqlalchemy as sa
from alembic import context, op
# revision identifiers, used by Alembic.
revision = '410aadae7652'
down_revision = 'd65745749e34'
branch_labels = None
depends_on = None
def get_inv():
INV = context.get_x_argument(as_dictionary=True).get('inventory')
if not INV:
raise ValueError("Inventory value is not specified")
return INV
def upgrade():
op.create_table(
'other',
sa.Column('id', sa.BigInteger(), nullable=False),
sa.ForeignKeyConstraint(
['id'],
[f'{get_inv()}.device.id'],
),
sa.PrimaryKeyConstraint('id'),
schema=f'{get_inv()}',
)
def downgrade():
op.drop_table('other', schema=f'{get_inv()}')

View File

@ -0,0 +1,86 @@
"""sanitization
Revision ID: 4f33137586dd
Revises: 93daff872771
Create Date: 2023-02-13 18:01:00.092527
"""
import citext
import sqlalchemy as sa
from alembic import context, op
from sqlalchemy.dialects import postgresql
from ereuse_devicehub import teal
# revision identifiers, used by Alembic.
revision = '4f33137586dd'
down_revision = '93daff872771'
branch_labels = None
depends_on = None
def get_inv():
INV = context.get_x_argument(as_dictionary=True).get('inventory')
if not INV:
raise ValueError("Inventory value is not specified")
return INV
def upgrade():
op.create_table(
'sanitization_entity',
sa.Column('id', sa.BigInteger(), nullable=False),
sa.Column(
'updated',
sa.TIMESTAMP(timezone=True),
server_default=sa.text('CURRENT_TIMESTAMP'),
nullable=False,
),
sa.Column(
'created',
sa.TIMESTAMP(timezone=True),
server_default=sa.text('CURRENT_TIMESTAMP'),
nullable=False,
),
sa.Column('company_name', sa.String(), nullable=True),
sa.Column('logo', teal.db.URL(), nullable=True),
sa.Column('responsable_person', sa.String(), nullable=True),
sa.Column('supervisor_person', sa.String(), nullable=True),
sa.Column('location', sa.String(), nullable=True),
sa.Column('user_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.PrimaryKeyConstraint('id'),
sa.ForeignKeyConstraint(
['user_id'],
['common.user.id'],
),
schema=f'{get_inv()}',
)
op.create_table(
'transfer_customer_details',
sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False),
sa.Column(
'updated',
sa.TIMESTAMP(timezone=True),
server_default=sa.text('CURRENT_TIMESTAMP'),
nullable=False,
),
sa.Column(
'created',
sa.TIMESTAMP(timezone=True),
server_default=sa.text('CURRENT_TIMESTAMP'),
nullable=False,
),
sa.Column('company_name', citext.CIText(), nullable=True),
sa.Column('logo', teal.db.URL(), nullable=True),
sa.Column('location', citext.CIText(), nullable=True),
sa.Column('transfer_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.ForeignKeyConstraint(['transfer_id'], [f'{get_inv()}.transfer.id']),
sa.PrimaryKeyConstraint('id'),
schema=f'{get_inv()}',
)
def downgrade():
op.drop_table('sanitization_entity', schema=f'{get_inv()}')
op.drop_table('transfer_customer_details', schema=f'{get_inv()}')

View File

@ -5,14 +5,11 @@ Revises: eca457d8b2a4
Create Date: 2021-03-15 17:40:34.410408 Create Date: 2021-03-15 17:40:34.410408
""" """
import sqlalchemy as sa
import citext import citext
import teal import sqlalchemy as sa
from alembic import op from alembic import context, op
from alembic import context
from sqlalchemy.dialects import postgresql from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic. # revision identifiers, used by Alembic.
revision = '51439cf24be8' revision = '51439cf24be8'
down_revision = '21afd375a654' down_revision = '21afd375a654'
@ -36,59 +33,197 @@ def upgrade_data():
def upgrade(): def upgrade():
## Trade # Trade
currency = sa.Enum('AFN', 'ARS', 'AWG', 'AUD', 'AZN', 'BSD', 'BBD', 'BDT', 'BYR', 'BZD', 'BMD', currency = sa.Enum(
'BOB', 'BAM', 'BWP', 'BGN', 'BRL', 'BND', 'KHR', 'CAD', 'KYD', 'CLP', 'CNY', 'AFN',
'COP', 'CRC', 'HRK', 'CUP', 'CZK', 'DKK', 'DOP', 'XCD', 'EGP', 'SVC', 'EEK', 'ARS',
'EUR', 'FKP', 'FJD', 'GHC', 'GIP', 'GTQ', 'GGP', 'GYD', 'HNL', 'HKD', 'HUF', 'AWG',
'ISK', 'INR', 'IDR', 'IRR', 'IMP', 'ILS', 'JMD', 'JPY', 'JEP', 'KZT', 'KPW', 'AUD',
'KRW', 'KGS', 'LAK', 'LVL', 'LBP', 'LRD', 'LTL', 'MKD', 'MYR', 'MUR', 'MXN', 'AZN',
'MNT', 'MZN', 'NAD', 'NPR', 'ANG', 'NZD', 'NIO', 'NGN', 'NOK', 'OMR', 'PKR', 'BSD',
'PAB', 'PYG', 'PEN', 'PHP', 'PLN', 'QAR', 'RON', 'RUB', 'SHP', 'SAR', 'RSD', 'BBD',
'SCR', 'SGD', 'SBD', 'SOS', 'ZAR', 'LKR', 'SEK', 'CHF', 'SRD', 'SYP', 'TWD', 'BDT',
'THB', 'TTD', 'TRY', 'TRL', 'TVD', 'UAH', 'GBP', 'USD', 'UYU', 'UZS', 'VEF', name='currency', create_type=False, checkfirst=True, schema=f'{get_inv()}') 'BYR',
'BZD',
'BMD',
'BOB',
'BAM',
'BWP',
'BGN',
'BRL',
'BND',
'KHR',
'CAD',
'KYD',
'CLP',
'CNY',
'COP',
'CRC',
'HRK',
'CUP',
'CZK',
'DKK',
'DOP',
'XCD',
'EGP',
'SVC',
'EEK',
'EUR',
'FKP',
'FJD',
'GHC',
'GIP',
'GTQ',
'GGP',
'GYD',
'HNL',
'HKD',
'HUF',
'ISK',
'INR',
'IDR',
'IRR',
'IMP',
'ILS',
'JMD',
'JPY',
'JEP',
'KZT',
'KPW',
'KRW',
'KGS',
'LAK',
'LVL',
'LBP',
'LRD',
'LTL',
'MKD',
'MYR',
'MUR',
'MXN',
'MNT',
'MZN',
'NAD',
'NPR',
'ANG',
'NZD',
'NIO',
'NGN',
'NOK',
'OMR',
'PKR',
'PAB',
'PYG',
'PEN',
'PHP',
'PLN',
'QAR',
'RON',
'RUB',
'SHP',
'SAR',
'RSD',
'SCR',
'SGD',
'SBD',
'SOS',
'ZAR',
'LKR',
'SEK',
'CHF',
'SRD',
'SYP',
'TWD',
'THB',
'TTD',
'TRY',
'TRL',
'TVD',
'UAH',
'GBP',
'USD',
'UYU',
'UZS',
'VEF',
name='currency',
create_type=False,
checkfirst=True,
)
op.drop_table('trade', schema=f'{get_inv()}') op.drop_table('trade', schema=f'{get_inv()}')
op.create_table('trade', op.create_table(
sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False), 'trade',
sa.Column('price', sa.Float(decimal_return_scale=4), nullable=True), sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False),
sa.Column('lot_id', postgresql.UUID(as_uuid=True), nullable=True), sa.Column('price', sa.Float(decimal_return_scale=4), nullable=True),
sa.Column('date', sa.TIMESTAMP(timezone=True), nullable=True), sa.Column('lot_id', postgresql.UUID(as_uuid=True), nullable=True),
sa.Column('user_from_id', postgresql.UUID(as_uuid=True), nullable=False), sa.Column('date', sa.TIMESTAMP(timezone=True), nullable=True),
sa.Column('user_to_id', postgresql.UUID(as_uuid=True), nullable=False), sa.Column('user_from_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.Column('document_id', citext.CIText(), nullable=True), sa.Column('user_to_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.Column('confirm', sa.Boolean(), nullable=True), sa.Column('document_id', citext.CIText(), nullable=True),
sa.Column('code', citext.CIText(), default='', nullable=True, sa.Column('confirm', sa.Boolean(), nullable=True),
comment = "This code is used for traceability"), sa.Column(
sa.ForeignKeyConstraint(['id'], [f'{get_inv()}.action.id'], ), 'code',
sa.ForeignKeyConstraint(['user_from_id'], ['common.user.id'], ), citext.CIText(),
sa.ForeignKeyConstraint(['user_to_id'], ['common.user.id'], ), default='',
sa.ForeignKeyConstraint(['lot_id'], [f'{get_inv()}.lot.id'], ), nullable=True,
sa.PrimaryKeyConstraint('id'), comment="This code is used for traceability",
schema=f'{get_inv()}' ),
) sa.ForeignKeyConstraint(
['id'],
[f'{get_inv()}.action.id'],
),
sa.ForeignKeyConstraint(
['user_from_id'],
['common.user.id'],
),
sa.ForeignKeyConstraint(
['user_to_id'],
['common.user.id'],
),
sa.ForeignKeyConstraint(
['lot_id'],
[f'{get_inv()}.lot.id'],
),
sa.PrimaryKeyConstraint('id'),
schema=f'{get_inv()}',
)
op.add_column("trade", sa.Column("currency", currency, nullable=False), schema=f'{get_inv()}') op.add_column(
"trade", sa.Column("currency", currency, nullable=False), schema=f'{get_inv()}'
)
op.create_table(
'confirm',
sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False),
sa.Column('user_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.Column('action_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.ForeignKeyConstraint(
['id'],
[f'{get_inv()}.action.id'],
),
sa.ForeignKeyConstraint(
['action_id'],
[f'{get_inv()}.action.id'],
),
sa.ForeignKeyConstraint(
['user_id'],
['common.user.id'],
),
sa.PrimaryKeyConstraint('id'),
schema=f'{get_inv()}',
)
op.create_table('confirm', # User
sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False), op.add_column(
sa.Column('user_id', postgresql.UUID(as_uuid=True), nullable=False), 'user',
sa.Column('action_id', postgresql.UUID(as_uuid=True), nullable=False), sa.Column('active', sa.Boolean(), default=True, nullable=True),
schema='common',
sa.ForeignKeyConstraint(['id'], [f'{get_inv()}.action.id'], ), )
sa.ForeignKeyConstraint(['action_id'], [f'{get_inv()}.action.id'], ), op.add_column(
sa.ForeignKeyConstraint(['user_id'], ['common.user.id'], ), 'user',
sa.PrimaryKeyConstraint('id'), sa.Column('phantom', sa.Boolean(), default=False, nullable=True),
schema=f'{get_inv()}' schema='common',
) )
## User
op.add_column('user', sa.Column('active', sa.Boolean(), default=True, nullable=True),
schema='common')
op.add_column('user', sa.Column('phantom', sa.Boolean(), default=False, nullable=True),
schema='common')
upgrade_data() upgrade_data()
@ -99,28 +234,57 @@ def upgrade():
def downgrade(): def downgrade():
op.drop_table('confirm', schema=f'{get_inv()}') op.drop_table('confirm', schema=f'{get_inv()}')
op.drop_table('trade', schema=f'{get_inv()}') op.drop_table('trade', schema=f'{get_inv()}')
op.create_table('trade', op.create_table(
sa.Column('shipping_date', sa.TIMESTAMP(timezone=True), nullable=True, 'trade',
comment='When are the devices going to be ready \n \ sa.Column(
for shipping?\n '), 'shipping_date',
sa.Column('invoice_number', citext.CIText(), nullable=True, sa.TIMESTAMP(timezone=True),
comment='The id of the invoice so they can be linked.'), nullable=True,
sa.Column('price_id', postgresql.UUID(as_uuid=True), nullable=True, comment='When are the devices going to be ready \n \
comment='The price set for this trade. \n \ for shipping?\n ',
),
sa.Column(
'invoice_number',
citext.CIText(),
nullable=True,
comment='The id of the invoice so they can be linked.',
),
sa.Column(
'price_id',
postgresql.UUID(as_uuid=True),
nullable=True,
comment='The price set for this trade. \n \
If no price is set it is supposed that the trade was\n \ If no price is set it is supposed that the trade was\n \
not payed, usual in donations.\n '), not payed, usual in donations.\n ',
sa.Column('to_id', postgresql.UUID(as_uuid=True), nullable=False), ),
sa.Column('confirms_id', postgresql.UUID(as_uuid=True), nullable=True, sa.Column('to_id', postgresql.UUID(as_uuid=True), nullable=False),
comment='An organize action that this association confirms. \ sa.Column(
'confirms_id',
postgresql.UUID(as_uuid=True),
nullable=True,
comment='An organize action that this association confirms. \
\n \n For example, a ``Sell`` or ``Rent``\n \ \n \n For example, a ``Sell`` or ``Rent``\n \
can confirm a ``Reserve`` action.\n '), can confirm a ``Reserve`` action.\n ',
sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False), ),
sa.ForeignKeyConstraint(['confirms_id'], [f'{get_inv()}.organize.id'], ), sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False),
sa.ForeignKeyConstraint(['id'], [f'{get_inv()}.action.id'], ), sa.ForeignKeyConstraint(
sa.ForeignKeyConstraint(['price_id'], [f'{get_inv()}.price.id'], ), ['confirms_id'],
sa.ForeignKeyConstraint(['to_id'], [f'{get_inv()}.agent.id'], ), [f'{get_inv()}.organize.id'],
sa.PrimaryKeyConstraint('id'), ),
schema=f'{get_inv()}' sa.ForeignKeyConstraint(
) ['id'],
[f'{get_inv()}.action.id'],
),
sa.ForeignKeyConstraint(
['price_id'],
[f'{get_inv()}.price.id'],
),
sa.ForeignKeyConstraint(
['to_id'],
[f'{get_inv()}.agent.id'],
),
sa.PrimaryKeyConstraint('id'),
schema=f'{get_inv()}',
)
op.drop_column('user', 'active', schema='common') op.drop_column('user', 'active', schema='common')
op.drop_column('user', 'phantom', schema='common') op.drop_column('user', 'phantom', schema='common')

View File

@ -0,0 +1,45 @@
"""add new erase_data_wipe
Revision ID: 5169765e2653
Revises: 2f2ef041483a
Create Date: 2023-05-23 10:34:46.312074
"""
import sqlalchemy as sa
from alembic import context, op
from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic.
revision = '5169765e2653'
down_revision = 'a8a86dbd5f51'
branch_labels = None
depends_on = None
def get_inv():
INV = context.get_x_argument(as_dictionary=True).get('inventory')
if not INV:
raise ValueError("Inventory value is not specified")
return INV
def upgrade():
op.create_table(
'erase_data_wipe',
sa.Column('document_id', sa.BigInteger(), nullable=False),
sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False),
sa.ForeignKeyConstraint(
['document_id'],
[f'{get_inv()}.document.id'],
),
sa.ForeignKeyConstraint(
['id'],
[f'{get_inv()}.erase_basic.id'],
),
sa.PrimaryKeyConstraint('id'),
schema=f'{get_inv()}',
)
def downgrade():
op.drop_table('erase_data_wipe', schema=f'{get_inv()}')

View File

@ -0,0 +1,35 @@
"""add vendor family in device
Revision ID: 564952310b17
Revises: af038a8a388c
Create Date: 2022-11-14 13:12:22.916848
"""
import citext
import sqlalchemy as sa
from alembic import context, op
# revision identifiers, used by Alembic.
revision = '564952310b17'
down_revision = 'af038a8a388c'
branch_labels = None
depends_on = None
def get_inv():
INV = context.get_x_argument(as_dictionary=True).get('inventory')
if not INV:
raise ValueError("Inventory value is not specified")
return INV
def upgrade():
op.add_column(
'device',
sa.Column('family', citext.CIText(), nullable=True),
schema=f'{get_inv()}',
)
def downgrade():
op.drop_column('device', 'family', schema=f'{get_inv()}')

View File

@ -0,0 +1,59 @@
"""id internal in placeholder
Revision ID: 626c17026ca7
Revises: e919fe0611ff
Create Date: 2022-10-03 19:25:00.581699
"""
import sqlalchemy as sa
from alembic import context, op
# revision identifiers, used by Alembic.
revision = '626c17026ca7'
down_revision = 'e919fe0611ff'
branch_labels = None
depends_on = None
def get_inv():
INV = context.get_x_argument(as_dictionary=True).get('inventory')
if not INV:
raise ValueError("Inventory value is not specified")
return INV
def upgrade_datas():
con = op.get_bind()
sql = 'select id from common.user where phantom=false and active=true'
users = con.execute(sql)
for user in users:
phid = 1
user_id = user.id
sql = f"""
select id from {get_inv()}.placeholder where owner_id='{user_id}'
order by id
"""
placeholders = con.execute(sql)
for p in placeholders:
p_id = p.id
sql = f"""
update {get_inv()}.placeholder set phid='{phid}'
where id='{p_id}'
"""
con.execute(sql)
phid += 1
def upgrade():
op.add_column(
'placeholder',
sa.Column('id_device_internal', sa.Unicode(), nullable=True),
schema=f'{get_inv()}',
)
upgrade_datas()
def downgrade():
op.drop_column('placeholder', 'id_device_internal', schema=f'{get_inv()}')

View File

@ -0,0 +1,41 @@
"""backup dhid
Revision ID: 6b0880832b78
Revises: d7ea9a3b2da1
Create Date: 2022-09-07 12:53:25.827186
"""
import citext
import sqlalchemy as sa
from alembic import context, op
# revision identifiers, used by Alembic.
revision = '6b0880832b78'
down_revision = 'd7ea9a3b2da1'
branch_labels = None
depends_on = None
def get_inv():
INV = context.get_x_argument(as_dictionary=True).get('inventory')
if not INV:
raise ValueError("Inventory value is not specified")
return INV
def upgrade():
op.add_column(
'device',
sa.Column('dhid_bk', citext.CIText(), unique=False, nullable=True),
schema=f'{get_inv()}',
)
op.add_column(
'device',
sa.Column('phid_bk', citext.CIText(), unique=False, nullable=True),
schema=f'{get_inv()}',
)
def downgrade():
op.drop_column('device', 'dhid_bk', schema=f'{get_inv()}')
op.drop_column('device', 'phid_bk', schema=f'{get_inv()}')

View File

@ -0,0 +1,66 @@
"""change wbid for sid
Revision ID: 6f6771813f2e
Revises: 97bef94f7982
Create Date: 2022-04-25 10:52:11.767569
"""
import citext
import sqlalchemy as sa
from alembic import context, op
# revision identifiers, used by Alembic.
revision = '6f6771813f2e'
down_revision = '97bef94f7982'
branch_labels = None
depends_on = None
def get_inv():
INV = context.get_x_argument(as_dictionary=True).get('inventory')
if not INV:
raise ValueError("Inventory value is not specified")
return INV
def upgrade_datas():
con = op.get_bind()
sql = f"select * from {get_inv()}.snapshot;"
snapshots = con.execute(sql)
for snap in snapshots:
wbid = snap.wbid
if wbid:
sql = f"""update {get_inv()}.snapshot set sid='{wbid}'
where wbid='{wbid}';"""
con.execute(sql)
sql = f"select wbid from {get_inv()}.snapshot_errors;"
snapshots = con.execute(sql)
for snap in snapshots:
wbid = snap.wbid
if wbid:
sql = f"""update {get_inv()}.snapshot set sid='{wbid}'
where wbid='{wbid}';"""
con.execute(sql)
def upgrade():
op.add_column(
'snapshot',
sa.Column('sid', citext.CIText(), nullable=True),
schema=f'{get_inv()}',
)
op.add_column(
'snapshot_errors',
sa.Column('sid', citext.CIText(), nullable=True),
schema=f'{get_inv()}',
)
upgrade_datas()
op.drop_column('snapshot', 'wbid', schema=f'{get_inv()}')
op.drop_column('snapshot_errors', 'wbid', schema=f'{get_inv()}')
def downgrade():
op.drop_column('snapshot', 'sid', schema=f'{get_inv()}')
op.drop_column('snapshot_errors', 'sid', schema=f'{get_inv()}')

Some files were not shown because too many files have changed in this diff Show More