From 85219cdc1d2a1357652672bb0bf6858e9f8d8d41 Mon Sep 17 00:00:00 2001 From: Anders Jensen-Urstad Date: Tue, 25 Oct 2022 15:26:03 +0200 Subject: [PATCH 01/18] Bump DATA_UPLOAD_MAX_NUMBER_FIELDS to allow for large exports in admin interface; update README --- README.md | 3 +++ bibstat/settings.py | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/README.md b/README.md index 22f59f2..54caad3 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,9 @@ Nedan är ett exempel på en minimal installation i Linux. # Installera MongoDB 5.0.x: # https://www.mongodb.com/docs/v5.0/installation/ + # Installera MongoDB Database Tools: + # https://www.mongodb.com/try/download/database-tools + # (inkluderar mongorestore & co, som ej längre är del av MongoDB-disten sen 4.4) # Klona projektet git clone git@github.com:libris/bibstat diff --git a/bibstat/settings.py b/bibstat/settings.py index 5cd5c95..647a6f9 100644 --- a/bibstat/settings.py +++ b/bibstat/settings.py @@ -55,6 +55,10 @@ LOG_LEVEL = "WARNING" +# The following is necessary because when you select all surveys in the admin +# interface and click Export, the request is quite large. +DATA_UPLOAD_MAX_NUMBER_FIELDS = 10000 + # Override above with local settings if present try: from .settings_local import * From d3c7bcb271de81ab8d84c6afdcfdf461a3e76eef Mon Sep 17 00:00:00 2001 From: Anders Jensen-Urstad Date: Tue, 25 Oct 2022 15:27:29 +0200 Subject: [PATCH 02/18] Bump version number to 1.20.1 --- bibstat/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bibstat/settings.py b/bibstat/settings.py index 647a6f9..5715f78 100644 --- a/bibstat/settings.py +++ b/bibstat/settings.py @@ -17,7 +17,7 @@ BASE_DIR = Path(__file__).resolve().parent.parent # Bibstat version number - update this when making a new release -RELEASE_VERSION = "1.20.0" +RELEASE_VERSION = "1.20.1" """ ---------------------------------------------------------- From 38c900f6854ba476bcc2379be0a52a50b19ab941 Mon Sep 17 00:00:00 2001 From: Anders Jensen-Urstad Date: Wed, 2 Nov 2022 12:17:15 +0100 Subject: [PATCH 03/18] Make bulk survey removal work again (Python 2 cruft) --- libstat/services/clean_data.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/libstat/services/clean_data.py b/libstat/services/clean_data.py index 326b8a7..edfb5ae 100644 --- a/libstat/services/clean_data.py +++ b/libstat/services/clean_data.py @@ -3,7 +3,7 @@ from bibstat import settings from xlrd import open_workbook from xlrd import XLRDError -import os, logging, codecs +import os, logging logger = logging.getLogger(__name__) @@ -61,12 +61,11 @@ def match_libraries_and_replace_sigel(sample_year): count = 0 matched = 0 - f = codecs.open( + f = open( os.path.join( settings.CLEAN_DATA_LOG_PATH, "match_libraries_log_%d" % sample_year ), - "wt", - "utf-8", + "w" ) logfile = File(f) @@ -174,12 +173,11 @@ def remove_empty_surveys(sample_year, mode): elif mode == "not_viewed": remove_surveys = _get_surveys_with_status_not_viewed(sample_year) - f = codecs.open( + f = open( os.path.join( settings.CLEAN_DATA_LOG_PATH, "remove_surveys_log_%d" % sample_year ), - "wt", - "utf-8", + "w" ) logfile = File(f) logfile.write("Mode: %s\n" % mode) From 9e75e4c60af5436ef2adf9be00c6f7afdeb489b0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Nov 2022 09:42:44 +0000 Subject: [PATCH 04/18] Bump django from 3.2.15 to 3.2.16 Bumps [django](https://github.com/django/django) from 3.2.15 to 3.2.16. - [Release notes](https://github.com/django/django/releases) - [Commits](https://github.com/django/django/compare/3.2.15...3.2.16) --- updated-dependencies: - dependency-name: django dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 1573d21..6a1dd9a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,7 @@ blinker==1.5 django-excel-response==1.0 git+https://github.com/ierror/django-js-reverse@7cab78c#egg=django-js-reverse django-mongoengine==0.5.4 -Django==3.2.15 +Django==3.2.16 pymongo==3.12 mongoengine==0.24.2 openpyxl==3.0.10 From 07d605bc57cc3d404a7293ee109c422e010193b6 Mon Sep 17 00:00:00 2001 From: Anders Jensen-Urstad Date: Tue, 8 Nov 2022 16:44:29 +0100 Subject: [PATCH 05/18] Adjust sentence, fix two broken (KB!) links --- libstat/templates/libstat/base/index.html | 2 +- libstat/templates/libstat/index.html | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libstat/templates/libstat/base/index.html b/libstat/templates/libstat/base/index.html index f3243b7..4093c71 100644 --- a/libstat/templates/libstat/base/index.html +++ b/libstat/templates/libstat/base/index.html @@ -34,7 +34,7 @@
From 5d1b7b8ec319855c3ff33b6f19d70d29733e9146 Mon Sep 17 00:00:00 2001 From: Anders Jensen-Urstad Date: Thu, 17 Nov 2022 15:45:44 +0100 Subject: [PATCH 06/18] Bump version number to 1.20.2 --- bibstat/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bibstat/settings.py b/bibstat/settings.py index 5715f78..75278fb 100644 --- a/bibstat/settings.py +++ b/bibstat/settings.py @@ -17,7 +17,7 @@ BASE_DIR = Path(__file__).resolve().parent.parent # Bibstat version number - update this when making a new release -RELEASE_VERSION = "1.20.1" +RELEASE_VERSION = "1.20.2" """ ---------------------------------------------------------- From fa6a8860c04055493431c98537756c7e93a540bc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 9 Dec 2022 07:21:32 +0000 Subject: [PATCH 07/18] Bump certifi from 2022.6.15 to 2022.12.7 Bumps [certifi](https://github.com/certifi/python-certifi) from 2022.6.15 to 2022.12.7. - [Release notes](https://github.com/certifi/python-certifi/releases) - [Commits](https://github.com/certifi/python-certifi/compare/2022.06.15...2022.12.07) --- updated-dependencies: - dependency-name: certifi dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 6a1dd9a..af708d1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,6 +12,6 @@ requests==2.27.1 xlrd==1.2.0 xlwt==1.3.0 urllib3==1.26.11 -certifi==2022.6.15 +certifi==2022.12.7 black==22.6.0 gunicorn==20.1.0 From 4f80e213076ed8454e3cea8fd65f0a10ee8a528a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Feb 2023 22:23:50 +0000 Subject: [PATCH 08/18] Bump django from 3.2.16 to 3.2.17 Bumps [django](https://github.com/django/django) from 3.2.16 to 3.2.17. - [Release notes](https://github.com/django/django/releases) - [Commits](https://github.com/django/django/compare/3.2.16...3.2.17) --- updated-dependencies: - dependency-name: django dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 6a1dd9a..d888d8d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,7 @@ blinker==1.5 django-excel-response==1.0 git+https://github.com/ierror/django-js-reverse@7cab78c#egg=django-js-reverse django-mongoengine==0.5.4 -Django==3.2.16 +Django==3.2.17 pymongo==3.12 mongoengine==0.24.2 openpyxl==3.0.10 From 388c21cc43e581b527f0fe007cd330076050688b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Feb 2023 19:43:55 +0000 Subject: [PATCH 09/18] Bump django from 3.2.17 to 3.2.18 Bumps [django](https://github.com/django/django) from 3.2.17 to 3.2.18. - [Release notes](https://github.com/django/django/releases) - [Commits](https://github.com/django/django/compare/3.2.17...3.2.18) --- updated-dependencies: - dependency-name: django dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index d888d8d..6a9c142 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,7 @@ blinker==1.5 django-excel-response==1.0 git+https://github.com/ierror/django-js-reverse@7cab78c#egg=django-js-reverse django-mongoengine==0.5.4 -Django==3.2.17 +Django==3.2.18 pymongo==3.12 mongoengine==0.24.2 openpyxl==3.0.10 From f593f22bd31ddca4dc1e81d5027d8d6e38ac6bfc Mon Sep 17 00:00:00 2001 From: Anders Jensen-Urstad Date: Wed, 5 Apr 2023 16:53:37 +0200 Subject: [PATCH 10/18] Update logo for Sveriges officiella statistik --- libstat/templates/libstat/index.html | 2 +- static/img/logo-statistics.jpg | Bin 2058 -> 0 bytes static/img/logo-statistics.png | Bin 0 -> 14848 bytes 3 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 static/img/logo-statistics.jpg create mode 100644 static/img/logo-statistics.png diff --git a/libstat/templates/libstat/index.html b/libstat/templates/libstat/index.html index 9597f80..2232665 100644 --- a/libstat/templates/libstat/index.html +++ b/libstat/templates/libstat/index.html @@ -79,7 +79,7 @@

Sveriges officiella statistik regleras av Lagen om den officiella statistiken (SFS 2001:99) och Förordningen om den officiella statistiken (SFS 2001:100). En förändring av Lagen om den officiella statistiken trädde i kraft 2013. Myndigheter som har ansvar för Sveriges officiella statistik har bland annat ansvar för att

§ statistiken är objektiv
§ statistiken dokumenteras
§ statistiken kvalitetsdeklareras

Den officiella statistiken ska utan avgift finnas tillgänglig i elektronisk form. All officiell statistik ska ha beteckningen officiell statistik eller märkas med symbolen

- Sveriges officiella statistik logotyp + Sveriges officiella statistik logotyp

Observera att beteckningen eller symbolen inte får användas vid vidarebearbetningar av den officiella statistiken.

Produktionen av officiell statistik följer ett särskilt regelverk som verkar för statistiken kvalitet och generaliserbarhet. Eftersom många delar av Sveriges officiella statistik ingår i EUs statistiksystem följer också den officiella statistiken ”European statistics code of practice”.

Biblioteksstatistiken har under åren publicerats på olika sätt, här finns en länk om du vill nå lite äldre statistik.

diff --git a/static/img/logo-statistics.jpg b/static/img/logo-statistics.jpg deleted file mode 100644 index 1d8491357a0e524726c563fcf123b927df55bf81..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2058 zcmbW!XH?S(5&-ajNFV`{)6l^n5aLopNg~YvB2pDGN|9m^5S1o~g1|1YBA|rcC5kA5 zbTASKK_k+|9!eyHRU*xxDBS{>gS&fs@7<@}n|bqT=FOYm8{vp>9N6w?>tG9jKp^16 zW&%PUU=6^;#GqoLFenr%E)J7`%OK#Al5j;S>1{H~N-8^*l~5>EjGl%nT2~!~(lpl6 zH83O)2r3$;<|a6z9-e^PS^^Rm7l%v26%YsooEl0E_qRj%7(l`RRiGRULIWa55Euy( zb^|H^021B2cI)8(1V{u75fy{N#3dv*2b#A7A|NnW1OgTng+Ml^<2L&M1Su+|W@sfQ zP4b1J&&l8}<=lp;@1u3d9%0X8@O}}A;u3Q53W`d*e$mj>(kARSGBzV`a2A#hU8Feu_CiZeta>|vfsg&Hj{DQ)wYsJ*EJLMI3E32w& z?l;k!TNtg(w$85Zp5DGE{Z9u5hlV+CM!2K=_Y;#-(=#6gvkQw$%PXs2zkUC)9Cs*`09xAD===AH$1p^_3A<4omHII9#p3CEJV%ytO5 zui^l1F&ECRL0jcSf#H@w8hlsh{wvSYQ^G>85O^ zZ0%BL`AP8P*xAF8{v(t*HfO)PExZl~`(P7c981o4?*s8Z=4pjGTw}Oj^0M^G3%_p% zdhT=AjqbIU5P3PKP3fkOpO`3`w>By@$nCy0V{4RKKwaVf{Kt%own?ByWboKBRY&jL zvD8q7S)6s~c^PuZLduhjh`pxE@AIS6?C}oUc>E=Gr_XqHT=2`)-FgFQr`Fk@1KHl| z7TCdt6*bxVDSAt-q=W8*t2$X>j?MC^%O3T2TeC>XWmk6ki^O{`*AyzzFQ%;}Rmu-> z%9`Z6%?>oT)h{1>12zQZwYubf^b9e}6%3H~GtS~@(*0GdyY3plgz01(B!NrgqZ_V}7Hl$-^NZUUYeBs4opSz}#gnVDY@!$%p=B50dS(yz z`jDGvFlPt9C3kk$!$LLHq@7H~x)PmU(!1k!sQEhN?%FYW()?|2{gt|j+M- zq#@G96~du&39sg49$w`NfmbKuJzr+^{P1pjGa|)@EfT-rq10>q*{7>%gXfq%k!BJ) zC2b3Zd2nh%K_rSzKIHqhoNq7FvJ*QvP0RGEt&N_}el#-S#|3gq2deoxRZ9`=vqE4} zKTvXX#@gnb&wObIHpw`uU%Hk@uUGU#ZRdxZGaG8UNQ@yg7E<%+nv|&NX!mIu*G^7( zqsfT+5gfPhLm6d8cS!~IoM^tF)2)OO(86wb^B7gi&`BqU31@`B0>fYq)2}BpIJ)xgy0oZj^JSTHcft4&8@z<5u`po zXM%6O6{vrgxuiwqi6W5N-S3K*G?13NFjrA$Q zH&}8s1(!Iq5c(fSyLDpX5X@vgli`bscE+Dj{oPsdYon*Cf$Hy8O!3O8GeF)$516l;1}_cYIj3bhW^1$s^&=#?w_~a~A%=dV)^e8q~DmGv1dpgL4kHvancv%atNE8qE&#o&|! zS5Hyj+ED^d7Q6aIrt7O$cPO)hvewZz)l%!pnli9Cs+Ma2@aQChu_(scN0AHkFfUp+ zes0kyojSO_=e&GUn66%(0=)=}3GXw2-@1{wqf$2Wk@A9fxZ|4Kf#SI&v^Dxmy4VNj z2-}#(LuL8rwP~T;Jr9I{XU6L^+KgMg!Z5ZnQE*|(^~%w;y$oFS9*I!m^7!zt&Jw{< zW&OA424tu&p))|!Pp>bKykY0KJgOxGg4{l}t5{kZ#*sA&`^PsTjvKvv?$MhO8i1u` zJ6iaigcz)Y8Xk1ShW^aDqipn3<|sHjPyO@@=#A3&;Q2oj NNoba}BC>?se*)z5u228~ diff --git a/static/img/logo-statistics.png b/static/img/logo-statistics.png new file mode 100644 index 0000000000000000000000000000000000000000..78eb98216906c4f47c9362c72d12128dbcb1806c GIT binary patch literal 14848 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 literal 0 HcmV?d00001 From 9142d867f46a6083658abf5142212cc64a61fa48 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 May 2023 22:17:19 +0000 Subject: [PATCH 11/18] Bump django from 3.2.18 to 3.2.19 Bumps [django](https://github.com/django/django) from 3.2.18 to 3.2.19. - [Commits](https://github.com/django/django/compare/3.2.18...3.2.19) --- updated-dependencies: - dependency-name: django dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index f14f8d2..41356a6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,7 @@ blinker==1.5 django-excel-response==1.0 git+https://github.com/ierror/django-js-reverse@7cab78c#egg=django-js-reverse django-mongoengine==0.5.4 -Django==3.2.18 +Django==3.2.19 pymongo==3.12 mongoengine==0.24.2 openpyxl==3.0.10 From 03de5103339fc41812295c0a7c263d3cb1aef1c8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 May 2023 03:53:41 +0000 Subject: [PATCH 12/18] Bump requests from 2.27.1 to 2.31.0 Bumps [requests](https://github.com/psf/requests) from 2.27.1 to 2.31.0. - [Release notes](https://github.com/psf/requests/releases) - [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md) - [Commits](https://github.com/psf/requests/compare/v2.27.1...v2.31.0) --- updated-dependencies: - dependency-name: requests dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index f14f8d2..ed2cf15 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,7 +8,7 @@ pymongo==3.12 mongoengine==0.24.2 openpyxl==3.0.10 pytz==2022.1 -requests==2.27.1 +requests==2.31.0 xlrd==1.2.0 xlwt==1.3.0 urllib3==1.26.11 From f0d7b98ef69b600ab602f1bbecd78e0f7193021f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Jul 2023 23:28:15 +0000 Subject: [PATCH 13/18] Bump django from 3.2.19 to 3.2.20 Bumps [django](https://github.com/django/django) from 3.2.19 to 3.2.20. - [Commits](https://github.com/django/django/compare/3.2.19...3.2.20) --- updated-dependencies: - dependency-name: django dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index f1f48ba..291b7af 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,7 @@ blinker==1.5 django-excel-response==1.0 git+https://github.com/ierror/django-js-reverse@7cab78c#egg=django-js-reverse django-mongoengine==0.5.4 -Django==3.2.19 +Django==3.2.20 pymongo==3.12 mongoengine==0.24.2 openpyxl==3.0.10 From 5ed857cf3a616f375a0d601e7b602dcf9ea83ca7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Jul 2023 21:17:12 +0000 Subject: [PATCH 14/18] Bump certifi from 2022.12.7 to 2023.7.22 Bumps [certifi](https://github.com/certifi/python-certifi) from 2022.12.7 to 2023.7.22. - [Commits](https://github.com/certifi/python-certifi/compare/2022.12.07...2023.07.22) --- updated-dependencies: - dependency-name: certifi dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 291b7af..6ebb6af 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,6 +12,6 @@ requests==2.31.0 xlrd==1.2.0 xlwt==1.3.0 urllib3==1.26.11 -certifi==2022.12.7 +certifi==2023.7.22 black==22.6.0 gunicorn==20.1.0 From e986180eb8c1b9b2a7b07da98fbcbc0ad8acc01d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Oct 2023 01:43:40 +0000 Subject: [PATCH 15/18] Bump urllib3 from 1.26.11 to 1.26.17 Bumps [urllib3](https://github.com/urllib3/urllib3) from 1.26.11 to 1.26.17. - [Release notes](https://github.com/urllib3/urllib3/releases) - [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst) - [Commits](https://github.com/urllib3/urllib3/compare/1.26.11...1.26.17) --- updated-dependencies: - dependency-name: urllib3 dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 6ebb6af..b85bd14 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,7 +11,7 @@ pytz==2022.1 requests==2.31.0 xlrd==1.2.0 xlwt==1.3.0 -urllib3==1.26.11 +urllib3==1.26.17 certifi==2023.7.22 black==22.6.0 gunicorn==20.1.0 From 7ad03051677770a7ee77ceea26b0043545ab7552 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Oct 2023 01:16:46 +0000 Subject: [PATCH 16/18] Bump urllib3 from 1.26.17 to 1.26.18 Bumps [urllib3](https://github.com/urllib3/urllib3) from 1.26.17 to 1.26.18. - [Release notes](https://github.com/urllib3/urllib3/releases) - [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst) - [Commits](https://github.com/urllib3/urllib3/compare/1.26.17...1.26.18) --- updated-dependencies: - dependency-name: urllib3 dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index b85bd14..29afa48 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,7 +11,7 @@ pytz==2022.1 requests==2.31.0 xlrd==1.2.0 xlwt==1.3.0 -urllib3==1.26.17 +urllib3==1.26.18 certifi==2023.7.22 black==22.6.0 gunicorn==20.1.0 From cb2bc0ddb8765ae1144378bafcb616b03c9bad92 Mon Sep 17 00:00:00 2001 From: Anders Jensen-Urstad Date: Wed, 25 Oct 2023 18:09:41 +0200 Subject: [PATCH 17/18] Add more logging --- libstat/forms/survey.py | 8 ++++---- libstat/models.py | 12 +++++++++++- libstat/utils.py | 25 ++++++++++++++++++++++++- libstat/views/dispatches.py | 4 ++++ libstat/views/survey.py | 25 ++++++++++++++++++++----- libstat/views/surveys.py | 9 +++++++++ requirements.txt | 1 + 7 files changed, 73 insertions(+), 11 deletions(-) diff --git a/libstat/forms/survey.py b/libstat/forms/survey.py index 26aa687..00d5c05 100644 --- a/libstat/forms/survey.py +++ b/libstat/forms/survey.py @@ -187,10 +187,10 @@ def _cell_to_input_field(self, cell, observation, authenticated, variable_type): if isinstance(field.initial, str): field.initial = field.initial.strip() - if cell.variable_key == "Besok01": - logger.debug("attrs:") - for attr, value in list(attrs.items()): - logger.debug(attr) + #if cell.variable_key == "Besok01": + # logger.debug("attrs:") + # for attr, value in list(attrs.items()): + # logger.debug(attr) return field diff --git a/libstat/models.py b/libstat/models.py index 4dbec54..772f6a4 100644 --- a/libstat/models.py +++ b/libstat/models.py @@ -546,7 +546,17 @@ def is_published(self): @property def latest_version_published(self): - return self.published_at is not None and self.published_at >= self.date_modified + # It can happen that self.modified_at is a timezone-unaware datetime object + # causing an error when compared with self.published_at ("can't compare offset-naive + # and offset-aware datetimes"). datetime.utcnow() is used in various places and does + # *not* set tzinfo. We shouldn't have these kinds of problems, but I'd rather not + # start poking at date/time handling given the state of the code, so let's just work + # around it here. + modified_at_with_tz = self.date_modified + if self.published_at is not None and self.published_at.tzinfo: + if not self.date_modified.tzinfo: + modified_at_with_tz = modified_at_with_tz.replace(tzinfo=self.published_at.tzinfo) + return self.published_at is not None and self.published_at >= modified_at_with_tz def target_group__desc(self): return targetGroups[self.target_group] diff --git a/libstat/utils.py b/libstat/utils.py index 27c7d53..d8be74e 100644 --- a/libstat/utils.py +++ b/libstat/utils.py @@ -1,6 +1,7 @@ -# -*- coding: UTF-8 -*- import datetime +from ipware import IpWare + ALL_TARGET_GROUPS_label = "Samtliga bibliotek" SURVEY_TARGET_GROUPS = ( ("natbib", "Nationalbibliotek"), @@ -68,6 +69,8 @@ ISO8601_utc_format = "%Y-%m-%dT%H:%M:%S.%fZ" +ipw = IpWare() + def parse_datetime_from_isodate_str(date_str): # Note: Timezone designator not supported ("+01:00"). @@ -95,3 +98,23 @@ def parse_datetime(date_str, date_format): return datetime.datetime.strptime(date_str, date_format) except ValueError: return None + + +def get_ip_for_logging(request): + # We use ipware (ipw) tp easily get the "real" client IP. + # Might need some adjustments depending on the environment, e.g. specifying + # trusted proxies. + # This is *ONLY* for logging purposes. + ip, trusted_route = ipw.get_client_ip(request.META) + return ip + + +def get_log_prefix(request, survey_id=None, survey_title=None): + log_prefix = f"[IP: {get_ip_for_logging(request)}]" + if request.user.is_superuser: + log_prefix = f"{log_prefix} [ADMIN]" + if survey_id: + log_prefix = f"{log_prefix} [survey: {survey_id}]" + if survey_title: + log_prefix = f"{log_prefix} [{survey_title}]" + return log_prefix diff --git a/libstat/views/dispatches.py b/libstat/views/dispatches.py index 79c49fb..1b9fa7a 100644 --- a/libstat/views/dispatches.py +++ b/libstat/views/dispatches.py @@ -8,6 +8,7 @@ from bibstat import settings from libstat.models import Dispatch, Survey +from libstat.utils import get_log_prefix logger = logging.getLogger(__name__) @@ -35,6 +36,7 @@ def _rendered_template(template, survey): def dispatches(request): if request.method == "POST": survey_ids = request.POST.getlist("survey-response-ids", []) + logger.info(f"{get_log_prefix(request)} Creating dispatches for {survey_ids}") surveys = list(Survey.objects.filter(id__in=survey_ids).exclude("observations")) dispatches = [ @@ -67,6 +69,7 @@ def dispatches(request): def dispatches_delete(request): if request.method == "POST": dispatch_ids = request.POST.getlist("dispatch-ids", []) + logger.info(f"{get_log_prefix(request)} Deleting dispatches {dispatch_ids}") Dispatch.objects.filter(id__in=dispatch_ids).delete() message = "" @@ -83,6 +86,7 @@ def dispatches_delete(request): def dispatches_send(request): if request.method == "POST": dispatch_ids = request.POST.getlist("dispatch-ids", []) + logger.info(f"{get_log_prefix(request)} Sending dispatches {dispatch_ids}") dispatches = Dispatch.objects.filter(id__in=dispatch_ids) dispatches_with_email = [ dispatch for dispatch in dispatches if dispatch.library_email diff --git a/libstat/views/survey.py b/libstat/views/survey.py index 13e30cf..db2c90f 100644 --- a/libstat/views/survey.py +++ b/libstat/views/survey.py @@ -23,6 +23,7 @@ ) from libstat.forms.survey import SurveyForm from libstat.survey_templates import survey_template +from libstat.utils import get_log_prefix logger = logging.getLogger(__name__) @@ -68,7 +69,7 @@ def sigel_survey(request, sigel): return HttpResponseNotFound() -def _save_survey_response_from_form(survey, form): +def _save_survey_response_from_form(survey, form, log_prefix): # Note: all syntax/format validation is done on client side w Bootstrap validator. # All fields are handled as CharFields in the form and casted based on variable.type before saving. # More types can be added when needed. @@ -108,9 +109,13 @@ def _save_survey_response_from_form(survey, form): _f for _f in form.cleaned_data["selected_libraries"].split(" ") if _f ] + logger.info(f"{log_prefix} Saving form; submit_action={submit_action}, survey_status={survey.status}") if submit_action == "submit" and survey.status in ("not_viewed", "initiated"): if not survey.has_conflicts(): + logger.info(f"{log_prefix} submit_action was 'submit' and survey.status {survey.status}; changing status to submitted") survey.status = "submitted" + else: + logger.info(f"{log_prefix} submit_action was 'submit' and survey.status {survey.status}; however status NOT changed to submitted due to conflicts") survey.save(validate=False) @@ -147,8 +152,10 @@ def can_view_survey(survey): return HttpResponseNotFound() survey = survey[0] + log_prefix = get_log_prefix(request, survey_id, survey) if not survey.is_active and not request.user.is_authenticated: + logger.info(f"{log_prefix} tried to {request.method} but survey is not active and user is not authenticated") return HttpResponseForbidden() context = { @@ -164,6 +171,7 @@ def can_view_survey(survey): if can_view_survey(survey): if not request.user.is_authenticated and survey.status == "not_viewed": + logger.info(f"{log_prefix} User not authenticated and survey.status was not_viewed; setting survey.status to initiated and saving") survey.status = "initiated" survey.save(validate=False) @@ -174,7 +182,7 @@ def can_view_survey(survey): and not request.user.is_superuser ): logger.error( - f"Refusing to save because survey has status submitted (or higher), library {survey.library.sigel}" + f"{log_prefix} Refusing to save because survey has status submitted (or higher), library {survey.library.sigel}" ) return HttpResponse( json.dumps({"error": "Survey already submitted"}), @@ -182,12 +190,15 @@ def can_view_survey(survey): content_type="application/json", ) else: + logger.info(f"{log_prefix} POSTing survey") form = SurveyForm(request.POST, survey=survey) errors = _save_survey_response_from_form( - survey, form + survey, form, log_prefix ) # Errors returned as separate json - logger.debug("ERRORS: ") - logger.debug(json.dumps(errors)) + if errors: + logger.info(f"{log_prefix} Errors when saving survey: {json.dumps(errors)}") + else: + logger.info(f"{log_prefix} Survey saved") return HttpResponse(json.dumps(errors), content_type="application/json") else: @@ -232,6 +243,8 @@ def release_survey_lock(request, survey_id): def survey_status(request, survey_id): if request.method == "POST": survey = Survey.objects.get(pk=survey_id) + log_prefix = f"{get_log_prefix(request, survey_id, survey)}" + logger.info(f"{log_prefix} Changing selected_status from {survey.status} to {request.POST['selected_status']}") survey.status = request.POST["selected_status"] survey.save() @@ -242,6 +255,8 @@ def survey_status(request, survey_id): def survey_notes(request, survey_id): if request.method == "POST": survey = Survey.objects.get(pk=survey_id) + log_prefix = f"{get_log_prefix(request, survey_id, survey)}" + logger.info(f"{log_prefix} Adding notes to survey") survey.notes = request.POST["notes"] survey.save() diff --git a/libstat/views/surveys.py b/libstat/views/surveys.py index e59af88..f668ad3 100644 --- a/libstat/views/surveys.py +++ b/libstat/views/surveys.py @@ -33,6 +33,7 @@ ) from libstat.survey_templates import survey_template from data.municipalities import municipalities +from libstat.utils import get_log_prefix logger = logging.getLogger(__name__) @@ -147,6 +148,7 @@ def surveys(request, *args, **kwargs): def surveys_activate(request): if request.method == "POST": survey_ids = request.POST.getlist("survey-response-ids", []) + logger.info(f"{get_log_prefix(request)} Activating surveys {survey_ids}") Survey.objects.filter(pk__in=survey_ids).update(set__is_active=True) request.session["message"] = "Aktiverade {} stycken enkäter.".format( len(survey_ids) @@ -158,6 +160,7 @@ def surveys_activate(request): def surveys_inactivate(request): if request.method == "POST": survey_ids = request.POST.getlist("survey-response-ids", []) + logger.info(f"{get_log_prefix(request)} Inactivating surveys {survey_ids}") Survey.objects.filter(pk__in=survey_ids).update(set__is_active=False) request.session["message"] = "Inaktiverade {} stycken enkäter.".format( len(survey_ids) @@ -318,8 +321,10 @@ def surveys_overview(request, sample_year): @permission_required("is_superuser", login_url="index") def surveys_statuses(request): + log_prefix = f"{get_log_prefix(request)}" status = request.POST.get("new_status", "") survey_response_ids = request.POST.getlist("survey-response-ids", []) + logger.info(f"{log_prefix} Changing status for {survey_response_ids}") if status == "published": num_successful_published = 0 for survey in Survey.objects.filter(id__in=survey_response_ids): @@ -333,6 +338,9 @@ def surveys_statuses(request): "de svarar för några bibliotek eller för att flera enkäter svarar för " "samma bibliotek. Alternativt saknar biblioteken kommunkod eller huvudman." ).format(message, len(survey_response_ids) - num_successful_published) + logger.info(f"{log_prefix} Published {num_successful_published} survey(s); failed publishing {len(survey_response_ids) - num_successful_published} survey(s)") + else: + logger.info(f"{log_prefix} Published {num_successful_published} survey(s)") else: surveys = Survey.objects.filter(id__in=survey_response_ids) for survey in surveys.filter(_status="published"): @@ -343,6 +351,7 @@ def surveys_statuses(request): message = "Ändrade status på {} stycken enkäter.".format( len(survey_response_ids) ) + logger.info(f"{log_prefix} Changed survey.status to {status} for {len(survey_response_ids)} surveys") request.session["message"] = message return _surveys_redirect(request) diff --git a/requirements.txt b/requirements.txt index 29afa48..8b129f2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,3 +15,4 @@ urllib3==1.26.18 certifi==2023.7.22 black==22.6.0 gunicorn==20.1.0 +python-ipware==1.0.5 From b2b301b5386626b1a0ae73b0c8c5e7addf652870 Mon Sep 17 00:00:00 2001 From: Anders Jensen-Urstad Date: Fri, 27 Oct 2023 11:28:11 +0200 Subject: [PATCH 18/18] Bump version number --- bibstat/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bibstat/settings.py b/bibstat/settings.py index 75278fb..e36183c 100644 --- a/bibstat/settings.py +++ b/bibstat/settings.py @@ -17,7 +17,7 @@ BASE_DIR = Path(__file__).resolve().parent.parent # Bibstat version number - update this when making a new release -RELEASE_VERSION = "1.20.2" +RELEASE_VERSION = "1.20.3" """ ----------------------------------------------------------