ci: merge main to release
This commit is contained in:
commit
df3366b789
22
.pnp.cjs
generated
22
.pnp.cjs
generated
|
@ -65,7 +65,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
|||
["eslint-plugin-promise", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:6.1.1"],\
|
||||
["eslint-plugin-vue", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:9.14.1"],\
|
||||
["file-saver", "npm:2.0.5"],\
|
||||
["highcharts", "npm:11.0.1"],\
|
||||
["highcharts", "npm:11.1.0"],\
|
||||
["html-validate", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:7.18.1"],\
|
||||
["ical.js", "npm:1.5.0"],\
|
||||
["jquery", "npm:3.7.0"],\
|
||||
|
@ -84,7 +84,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
|||
["pinia", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.1.3"],\
|
||||
["pinia-plugin-persist", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:1.0.0"],\
|
||||
["pug", "npm:3.0.2"],\
|
||||
["sass", "npm:1.62.1"],\
|
||||
["sass", "npm:1.63.4"],\
|
||||
["seedrandom", "npm:3.0.5"],\
|
||||
["select2", "npm:4.1.0-rc.0"],\
|
||||
["select2-bootstrap-5-theme", "npm:1.3.0"],\
|
||||
|
@ -5487,10 +5487,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
|||
}]\
|
||||
]],\
|
||||
["highcharts", [\
|
||||
["npm:11.0.1", {\
|
||||
"packageLocation": "./.yarn/cache/highcharts-npm-11.0.1-05a14e3887-773a7b8765.zip/node_modules/highcharts/",\
|
||||
["npm:11.1.0", {\
|
||||
"packageLocation": "./.yarn/cache/highcharts-npm-11.1.0-0d42a04430-f9b8cdc38b.zip/node_modules/highcharts/",\
|
||||
"packageDependencies": [\
|
||||
["highcharts", "npm:11.0.1"]\
|
||||
["highcharts", "npm:11.1.0"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
|
@ -7895,7 +7895,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
|||
["eslint-plugin-promise", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:6.1.1"],\
|
||||
["eslint-plugin-vue", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:9.14.1"],\
|
||||
["file-saver", "npm:2.0.5"],\
|
||||
["highcharts", "npm:11.0.1"],\
|
||||
["highcharts", "npm:11.1.0"],\
|
||||
["html-validate", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:7.18.1"],\
|
||||
["ical.js", "npm:1.5.0"],\
|
||||
["jquery", "npm:3.7.0"],\
|
||||
|
@ -7914,7 +7914,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
|||
["pinia", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.1.3"],\
|
||||
["pinia-plugin-persist", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:1.0.0"],\
|
||||
["pug", "npm:3.0.2"],\
|
||||
["sass", "npm:1.62.1"],\
|
||||
["sass", "npm:1.63.4"],\
|
||||
["seedrandom", "npm:3.0.5"],\
|
||||
["select2", "npm:4.1.0-rc.0"],\
|
||||
["select2-bootstrap-5-theme", "npm:1.3.0"],\
|
||||
|
@ -7998,10 +7998,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
|||
],\
|
||||
"linkType": "HARD"\
|
||||
}],\
|
||||
["npm:1.62.1", {\
|
||||
"packageLocation": "./.yarn/cache/sass-npm-1.62.1-c16d65fd28-1b1b3584b3.zip/node_modules/sass/",\
|
||||
["npm:1.63.4", {\
|
||||
"packageLocation": "./.yarn/cache/sass-npm-1.63.4-bf5f3496c2-12bde5beff.zip/node_modules/sass/",\
|
||||
"packageDependencies": [\
|
||||
["sass", "npm:1.62.1"],\
|
||||
["sass", "npm:1.63.4"],\
|
||||
["chokidar", "npm:3.5.3"],\
|
||||
["immutable", "npm:4.0.0"],\
|
||||
["source-map-js", "npm:1.0.2"]\
|
||||
|
@ -8716,7 +8716,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
|||
["less", null],\
|
||||
["postcss", "npm:8.4.23"],\
|
||||
["rollup", "npm:3.21.6"],\
|
||||
["sass", "npm:1.62.1"],\
|
||||
["sass", "npm:1.63.4"],\
|
||||
["stylus", null],\
|
||||
["sugarss", null],\
|
||||
["terser", null]\
|
||||
|
|
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/sass-npm-1.63.4-bf5f3496c2-12bde5beff.zip
vendored
Normal file
BIN
.yarn/cache/sass-npm-1.63.4-bf5f3496c2-12bde5beff.zip
vendored
Normal file
Binary file not shown.
65
dev/coverage-action/package-lock.json
generated
65
dev/coverage-action/package-lock.json
generated
|
@ -17,8 +17,8 @@
|
|||
"luxon": "3.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "8.41.0",
|
||||
"eslint-config-standard": "17.0.0",
|
||||
"eslint": "8.42.0",
|
||||
"eslint-config-standard": "17.1.0",
|
||||
"eslint-plugin-import": "2.27.5",
|
||||
"eslint-plugin-node": "11.1.0",
|
||||
"eslint-plugin-promise": "6.1.1",
|
||||
|
@ -111,9 +111,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@eslint/js": {
|
||||
"version": "8.41.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.41.0.tgz",
|
||||
"integrity": "sha512-LxcyMGxwmTh2lY9FwHPGWOHmYFCZvbrFCBZL4FzSSsxsRPuhrYUg/49/0KDfW8tnIEaEHtfmn6+NPN+1DqaNmA==",
|
||||
"version": "8.42.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.42.0.tgz",
|
||||
"integrity": "sha512-6SWlXpWU5AvId8Ac7zjzmIOqMOba/JWY8XZ4A7q7Gn1Vlfg/SFFIlrtHXt9nPn4op9ZPAkl91Jao+QQv3r/ukw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
|
@ -126,9 +126,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/@humanwhocodes/config-array": {
|
||||
"version": "0.11.8",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz",
|
||||
"integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==",
|
||||
"version": "0.11.10",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz",
|
||||
"integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@humanwhocodes/object-schema": "^1.2.1",
|
||||
|
@ -1718,16 +1718,16 @@
|
|||
}
|
||||
},
|
||||
"node_modules/eslint": {
|
||||
"version": "8.41.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.41.0.tgz",
|
||||
"integrity": "sha512-WQDQpzGBOP5IrXPo4Hc0814r4/v2rrIsB0rhT7jtunIalgg6gYXWhRMOejVO8yH21T/FGaxjmFjBMNqcIlmH1Q==",
|
||||
"version": "8.42.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.42.0.tgz",
|
||||
"integrity": "sha512-ulg9Ms6E1WPf67PHaEY4/6E2tEn5/f7FXGzr3t9cBMugOmf1INYvuUwwh1aXQN4MfJ6a5K2iNwP3w4AColvI9A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.2.0",
|
||||
"@eslint-community/regexpp": "^4.4.0",
|
||||
"@eslint/eslintrc": "^2.0.3",
|
||||
"@eslint/js": "8.41.0",
|
||||
"@humanwhocodes/config-array": "^0.11.8",
|
||||
"@eslint/js": "8.42.0",
|
||||
"@humanwhocodes/config-array": "^0.11.10",
|
||||
"@humanwhocodes/module-importer": "^1.0.1",
|
||||
"@nodelib/fs.walk": "^1.2.8",
|
||||
"ajv": "^6.10.0",
|
||||
|
@ -1774,9 +1774,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/eslint-config-standard": {
|
||||
"version": "17.0.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.0.0.tgz",
|
||||
"integrity": "sha512-/2ks1GKyqSOkH7JFvXJicu0iMpoojkwB+f5Du/1SC0PtBL+s8v30k9njRZ21pm2drKYm2342jFnGWzttxPmZVg==",
|
||||
"version": "17.1.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.1.0.tgz",
|
||||
"integrity": "sha512-IwHwmaBNtDK4zDHQukFDW5u/aTb8+meQWZvNFWkiGmbWjD6bqyuSSBxxXKkCftCUzc1zwCH2m/baCNDLGmuO5Q==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
|
@ -1792,10 +1792,13 @@
|
|||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^8.0.1",
|
||||
"eslint-plugin-import": "^2.25.2",
|
||||
"eslint-plugin-n": "^15.0.0",
|
||||
"eslint-plugin-n": "^15.0.0 || ^16.0.0 ",
|
||||
"eslint-plugin-promise": "^6.0.0"
|
||||
}
|
||||
},
|
||||
|
@ -6326,9 +6329,9 @@
|
|||
}
|
||||
},
|
||||
"@eslint/js": {
|
||||
"version": "8.41.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.41.0.tgz",
|
||||
"integrity": "sha512-LxcyMGxwmTh2lY9FwHPGWOHmYFCZvbrFCBZL4FzSSsxsRPuhrYUg/49/0KDfW8tnIEaEHtfmn6+NPN+1DqaNmA==",
|
||||
"version": "8.42.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.42.0.tgz",
|
||||
"integrity": "sha512-6SWlXpWU5AvId8Ac7zjzmIOqMOba/JWY8XZ4A7q7Gn1Vlfg/SFFIlrtHXt9nPn4op9ZPAkl91Jao+QQv3r/ukw==",
|
||||
"dev": true
|
||||
},
|
||||
"@gar/promisify": {
|
||||
|
@ -6338,9 +6341,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"@humanwhocodes/config-array": {
|
||||
"version": "0.11.8",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz",
|
||||
"integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==",
|
||||
"version": "0.11.10",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz",
|
||||
"integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@humanwhocodes/object-schema": "^1.2.1",
|
||||
|
@ -7531,16 +7534,16 @@
|
|||
"dev": true
|
||||
},
|
||||
"eslint": {
|
||||
"version": "8.41.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.41.0.tgz",
|
||||
"integrity": "sha512-WQDQpzGBOP5IrXPo4Hc0814r4/v2rrIsB0rhT7jtunIalgg6gYXWhRMOejVO8yH21T/FGaxjmFjBMNqcIlmH1Q==",
|
||||
"version": "8.42.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.42.0.tgz",
|
||||
"integrity": "sha512-ulg9Ms6E1WPf67PHaEY4/6E2tEn5/f7FXGzr3t9cBMugOmf1INYvuUwwh1aXQN4MfJ6a5K2iNwP3w4AColvI9A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@eslint-community/eslint-utils": "^4.2.0",
|
||||
"@eslint-community/regexpp": "^4.4.0",
|
||||
"@eslint/eslintrc": "^2.0.3",
|
||||
"@eslint/js": "8.41.0",
|
||||
"@humanwhocodes/config-array": "^0.11.8",
|
||||
"@eslint/js": "8.42.0",
|
||||
"@humanwhocodes/config-array": "^0.11.10",
|
||||
"@humanwhocodes/module-importer": "^1.0.1",
|
||||
"@nodelib/fs.walk": "^1.2.8",
|
||||
"ajv": "^6.10.0",
|
||||
|
@ -7589,9 +7592,9 @@
|
|||
}
|
||||
},
|
||||
"eslint-config-standard": {
|
||||
"version": "17.0.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.0.0.tgz",
|
||||
"integrity": "sha512-/2ks1GKyqSOkH7JFvXJicu0iMpoojkwB+f5Du/1SC0PtBL+s8v30k9njRZ21pm2drKYm2342jFnGWzttxPmZVg==",
|
||||
"version": "17.1.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.1.0.tgz",
|
||||
"integrity": "sha512-IwHwmaBNtDK4zDHQukFDW5u/aTb8+meQWZvNFWkiGmbWjD6bqyuSSBxxXKkCftCUzc1zwCH2m/baCNDLGmuO5Q==",
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
"luxon": "3.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "8.41.0",
|
||||
"eslint-config-standard": "17.0.0",
|
||||
"eslint": "8.42.0",
|
||||
"eslint-config-standard": "17.1.0",
|
||||
"eslint-plugin-import": "2.27.5",
|
||||
"eslint-plugin-node": "11.1.0",
|
||||
"eslint-plugin-promise": "6.1.1",
|
||||
|
|
14
dev/del-old-packages/package-lock.json
generated
14
dev/del-old-packages/package-lock.json
generated
|
@ -9,7 +9,7 @@
|
|||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@octokit/core": "^4.2.1",
|
||||
"@octokit/core": "^4.2.4",
|
||||
"luxon": "^3.3.0"
|
||||
}
|
||||
},
|
||||
|
@ -25,9 +25,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@octokit/core": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.1.tgz",
|
||||
"integrity": "sha512-tEDxFx8E38zF3gT7sSMDrT1tGumDgsw5yPG6BBh/X+5ClIQfMH/Yqocxz1PnHx6CHyF6pxmovUTOfZAUvQ0Lvw==",
|
||||
"version": "4.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.4.tgz",
|
||||
"integrity": "sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ==",
|
||||
"dependencies": {
|
||||
"@octokit/auth-token": "^3.0.0",
|
||||
"@octokit/graphql": "^5.0.0",
|
||||
|
@ -215,9 +215,9 @@
|
|||
}
|
||||
},
|
||||
"@octokit/core": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.1.tgz",
|
||||
"integrity": "sha512-tEDxFx8E38zF3gT7sSMDrT1tGumDgsw5yPG6BBh/X+5ClIQfMH/Yqocxz1PnHx6CHyF6pxmovUTOfZAUvQ0Lvw==",
|
||||
"version": "4.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.4.tgz",
|
||||
"integrity": "sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ==",
|
||||
"requires": {
|
||||
"@octokit/auth-token": "^3.0.0",
|
||||
"@octokit/graphql": "^5.0.0",
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@octokit/core": "^4.2.1",
|
||||
"@octokit/core": "^4.2.4",
|
||||
"luxon": "^3.3.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
server {
|
||||
listen 8000 default_server;
|
||||
listen [::]:8000 default_server;
|
||||
|
||||
proxy_read_timeout 1d;
|
||||
proxy_send_timeout 1d;
|
||||
|
||||
root /var/www/html;
|
||||
index index.html index.htm index.nginx-debian.html;
|
||||
|
|
|
@ -22,7 +22,6 @@ echo "Fix chromedriver /dev/shm permissions..."
|
|||
sudo chmod 1777 /dev/shm
|
||||
|
||||
# Run nginx
|
||||
|
||||
echo "Starting nginx..."
|
||||
sudo nginx
|
||||
|
||||
|
@ -30,6 +29,9 @@ sudo nginx
|
|||
echo "Compiling native node packages..."
|
||||
yarn rebuild
|
||||
|
||||
# Silence Browserlist warnings
|
||||
export BROWSERSLIST_IGNORE_OLD_DATA=1
|
||||
|
||||
# Generate static assets
|
||||
echo "Building static assets... (this could take a minute or two)"
|
||||
yarn build
|
||||
|
|
|
@ -12,12 +12,11 @@ from django.core.exceptions import ObjectDoesNotExist
|
|||
|
||||
import debug # pyflakes:ignore
|
||||
|
||||
import tastypie
|
||||
import tastypie.resources
|
||||
import tastypie.serializers
|
||||
from tastypie.api import Api
|
||||
from tastypie.bundle import Bundle
|
||||
from tastypie.exceptions import ApiFieldError
|
||||
from tastypie.serializers import Serializer # pyflakes:ignore (we're re-exporting this)
|
||||
from tastypie.fields import ApiField
|
||||
|
||||
_api_list = []
|
||||
|
@ -152,3 +151,8 @@ class ToOneField(tastypie.fields.ToOneField):
|
|||
dehydrated = self.dehydrate_related(fk_bundle, fk_resource, for_list=for_list)
|
||||
fk_resource._meta.cache.set(cache_key, dehydrated)
|
||||
return dehydrated
|
||||
|
||||
|
||||
class Serializer(tastypie.serializers.Serializer):
|
||||
def format_datetime(self, data):
|
||||
return data.astimezone(datetime.timezone.utc).replace(tzinfo=None).isoformat(timespec="seconds") + "Z"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# Copyright The IETF Trust 2007-2020, All Rights Reserved
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import debug # pyflakes:ignore
|
||||
|
||||
import datetime
|
||||
import unicodedata
|
||||
|
@ -8,8 +9,12 @@ import unicodedata
|
|||
from django.contrib.syndication.views import Feed, FeedDoesNotExist
|
||||
from django.utils.feedgenerator import Atom1Feed, Rss201rev2Feed
|
||||
from django.urls import reverse as urlreverse
|
||||
from django.template.defaultfilters import truncatewords, truncatewords_html, date as datefilter
|
||||
from django.template.defaultfilters import linebreaks # type: ignore
|
||||
from django.template.defaultfilters import (
|
||||
truncatewords,
|
||||
truncatewords_html,
|
||||
date as datefilter,
|
||||
)
|
||||
from django.template.defaultfilters import linebreaks # type: ignore
|
||||
from django.utils import timezone
|
||||
from django.utils.html import strip_tags
|
||||
|
||||
|
@ -21,12 +26,12 @@ from ietf.utils.timezone import RPC_TZINFO
|
|||
|
||||
def strip_control_characters(s):
|
||||
"""Remove Unicode control / non-printing characters from a string"""
|
||||
replacement_char = unicodedata.lookup('REPLACEMENT CHARACTER')
|
||||
return ''.join(
|
||||
replacement_char if unicodedata.category(c)[0] == 'C' else c
|
||||
for c in s
|
||||
replacement_char = unicodedata.lookup("REPLACEMENT CHARACTER")
|
||||
return "".join(
|
||||
replacement_char if unicodedata.category(c)[0] == "C" else c for c in s
|
||||
)
|
||||
|
||||
|
||||
class DocumentChangesFeed(Feed):
|
||||
feed_type = Atom1Feed
|
||||
|
||||
|
@ -39,25 +44,37 @@ class DocumentChangesFeed(Feed):
|
|||
def link(self, obj):
|
||||
if obj is None:
|
||||
raise FeedDoesNotExist
|
||||
return urlreverse('ietf.doc.views_doc.document_history', kwargs=dict(name=obj.canonical_name()))
|
||||
return urlreverse(
|
||||
"ietf.doc.views_doc.document_history",
|
||||
kwargs=dict(name=obj.canonical_name()),
|
||||
)
|
||||
|
||||
def subtitle(self, obj):
|
||||
return "History of change entries for %s." % obj.display_name()
|
||||
|
||||
def items(self, obj):
|
||||
events = obj.docevent_set.all().order_by("-time","-id").select_related("by", "newrevisiondocevent", "submissiondocevent")
|
||||
events = (
|
||||
obj.docevent_set.all()
|
||||
.order_by("-time", "-id")
|
||||
.select_related("by", "newrevisiondocevent", "submissiondocevent")
|
||||
)
|
||||
augment_events_with_revision(obj, events)
|
||||
return events
|
||||
|
||||
def item_title(self, item):
|
||||
return strip_control_characters("[%s] %s [rev. %s]" % (
|
||||
item.by,
|
||||
truncatewords(strip_tags(item.desc), 15),
|
||||
item.rev,
|
||||
))
|
||||
return strip_control_characters(
|
||||
"[%s] %s [rev. %s]"
|
||||
% (
|
||||
item.by,
|
||||
truncatewords(strip_tags(item.desc), 15),
|
||||
item.rev,
|
||||
)
|
||||
)
|
||||
|
||||
def item_description(self, item):
|
||||
return strip_control_characters(truncatewords_html(format_textarea(item.desc), 20))
|
||||
return strip_control_characters(
|
||||
truncatewords_html(format_textarea(item.desc), 20)
|
||||
)
|
||||
|
||||
def item_pubdate(self, item):
|
||||
return item.time
|
||||
|
@ -66,17 +83,28 @@ class DocumentChangesFeed(Feed):
|
|||
return str(item.by)
|
||||
|
||||
def item_link(self, item):
|
||||
return urlreverse('ietf.doc.views_doc.document_history', kwargs=dict(name=item.doc.canonical_name())) + "#history-%s" % item.pk
|
||||
return (
|
||||
urlreverse(
|
||||
"ietf.doc.views_doc.document_history",
|
||||
kwargs=dict(name=item.doc.canonical_name()),
|
||||
)
|
||||
+ "#history-%s" % item.pk
|
||||
)
|
||||
|
||||
|
||||
class InLastCallFeed(Feed):
|
||||
title = "Documents in Last Call"
|
||||
subtitle = "Announcements for documents in last call."
|
||||
feed_type = Atom1Feed
|
||||
author_name = 'IESG Secretary'
|
||||
author_name = "IESG Secretary"
|
||||
link = "/doc/iesg/last-call/"
|
||||
|
||||
def items(self):
|
||||
docs = list(Document.objects.filter(type="draft", states=State.objects.get(type="draft-iesg", slug="lc")))
|
||||
docs = list(
|
||||
Document.objects.filter(
|
||||
type="draft", states=State.objects.get(type="draft-iesg", slug="lc")
|
||||
)
|
||||
)
|
||||
for d in docs:
|
||||
d.lc_event = d.latest_event(LastCallDocEvent, type="sent_last_call")
|
||||
|
||||
|
@ -86,9 +114,11 @@ class InLastCallFeed(Feed):
|
|||
return docs
|
||||
|
||||
def item_title(self, item):
|
||||
return "%s (%s - %s)" % (item.name,
|
||||
datefilter(item.lc_event.time, "F j"),
|
||||
datefilter(item.lc_event.expires, "F j, Y"))
|
||||
return "%s (%s - %s)" % (
|
||||
item.name,
|
||||
datefilter(item.lc_event.time, "F j"),
|
||||
datefilter(item.lc_event.expires, "F j, Y"),
|
||||
)
|
||||
|
||||
def item_description(self, item):
|
||||
return strip_control_characters(linebreaks(item.lc_event.desc))
|
||||
|
@ -96,33 +126,55 @@ class InLastCallFeed(Feed):
|
|||
def item_pubdate(self, item):
|
||||
return item.lc_event.time
|
||||
|
||||
|
||||
class Rss201WithNamespacesFeed(Rss201rev2Feed):
|
||||
def root_attributes(self):
|
||||
attrs = super(Rss201WithNamespacesFeed, self).root_attributes()
|
||||
attrs['xmlns:dcterms'] = 'http://purl.org/dc/terms/'
|
||||
attrs['xmlns:media'] = 'http://search.yahoo.com/mrss/'
|
||||
attrs['xmlns:xsi'] = 'http://www.w3.org/2001/XMLSchema-instance'
|
||||
attrs["xmlns:dcterms"] = "http://purl.org/dc/terms/"
|
||||
attrs["xmlns:media"] = "http://search.yahoo.com/mrss/"
|
||||
attrs["xmlns:xsi"] = "http://www.w3.org/2001/XMLSchema-instance"
|
||||
return attrs
|
||||
|
||||
def add_item_elements(self, handler, item):
|
||||
super(Rss201WithNamespacesFeed, self).add_item_elements(handler, item)
|
||||
|
||||
for element_name in ['abstract','accessRights', 'format', 'publisher',]:
|
||||
dc_item_name = 'dcterms_%s' % element_name
|
||||
dc_element_name = 'dcterms:%s' % element_name
|
||||
attrs= {'xsi:type':'dcterms:local'} if element_name == 'publisher' else {}
|
||||
for element_name in [
|
||||
"abstract",
|
||||
"accessRights",
|
||||
"format",
|
||||
"publisher",
|
||||
]:
|
||||
dc_item_name = "dcterms_%s" % element_name
|
||||
dc_element_name = "dcterms:%s" % element_name
|
||||
attrs = {"xsi:type": "dcterms:local"} if element_name == "publisher" else {}
|
||||
if dc_item_name in item and item[dc_item_name] is not None:
|
||||
handler.addQuickElement(dc_element_name,item[dc_item_name],attrs)
|
||||
handler.addQuickElement(dc_element_name, item[dc_item_name], attrs)
|
||||
|
||||
if 'doi' in item and item['doi'] is not None:
|
||||
handler.addQuickElement('dcterms:identifier',item['doi'],{'xsi:type':'dcterms:doi'})
|
||||
if 'doiuri' in item and item['doiuri'] is not None:
|
||||
handler.addQuickElement('dcterms:identifier',item['doiuri'],{'xsi:type':'dcterms:uri'})
|
||||
if "doi" in item and item["doi"] is not None:
|
||||
handler.addQuickElement(
|
||||
"dcterms:identifier", item["doi"], {"xsi:type": "dcterms:doi"}
|
||||
)
|
||||
if "doiuri" in item and item["doiuri"] is not None:
|
||||
handler.addQuickElement(
|
||||
"dcterms:identifier", item["doiuri"], {"xsi:type": "dcterms:uri"}
|
||||
)
|
||||
|
||||
# TODO: consider using media:group
|
||||
if "media_contents" in item and item["media_contents"] is not None:
|
||||
for media_content in item["media_contents"]:
|
||||
handler.startElement(
|
||||
"media:content",
|
||||
{
|
||||
"url": media_content["url"],
|
||||
"type": media_content["media_type"],
|
||||
},
|
||||
)
|
||||
if "is_format_of" in media_content:
|
||||
handler.addQuickElement(
|
||||
"dcterms:isFormatOf", media_content["is_format_of"]
|
||||
)
|
||||
handler.endElement("media:content")
|
||||
|
||||
if 'media_content' in item and item['media_content'] is not None:
|
||||
handler.startElement('media:content',{'url':item['media_content']['url'],'type':'text/plain'})
|
||||
handler.addQuickElement('dcterms:isFormatOf',item['media_content']['link_url'])
|
||||
handler.endElement('media:content')
|
||||
|
||||
class RfcFeed(Feed):
|
||||
feed_type = Rss201WithNamespacesFeed
|
||||
|
@ -130,55 +182,96 @@ class RfcFeed(Feed):
|
|||
author_name = "RFC Editor"
|
||||
link = "https://www.rfc-editor.org/rfc-index2.html"
|
||||
|
||||
def get_object(self,request,year=None):
|
||||
def get_object(self, request, year=None):
|
||||
self.year = year
|
||||
|
||||
|
||||
def items(self):
|
||||
if self.year:
|
||||
# Find published RFCs based on their official publication year
|
||||
start_of_year = datetime.datetime(int(self.year), 1, 1, tzinfo=RPC_TZINFO)
|
||||
start_of_next_year = datetime.datetime(int(self.year) + 1, 1, 1, tzinfo=RPC_TZINFO)
|
||||
start_of_next_year = datetime.datetime(
|
||||
int(self.year) + 1, 1, 1, tzinfo=RPC_TZINFO
|
||||
)
|
||||
rfc_events = DocEvent.objects.filter(
|
||||
type='published_rfc',
|
||||
type="published_rfc",
|
||||
time__gte=start_of_year,
|
||||
time__lt=start_of_next_year,
|
||||
).order_by('-time')
|
||||
).order_by("-time")
|
||||
else:
|
||||
cutoff = timezone.now() - datetime.timedelta(days=8)
|
||||
rfc_events = DocEvent.objects.filter(type='published_rfc',time__gte=cutoff).order_by('-time')
|
||||
rfc_events = DocEvent.objects.filter(
|
||||
type="published_rfc", time__gte=cutoff
|
||||
).order_by("-time")
|
||||
results = [(e.doc, e.time) for e in rfc_events]
|
||||
for doc,time in results:
|
||||
for doc, time in results:
|
||||
doc.publication_time = time
|
||||
return [doc for doc,time in results]
|
||||
|
||||
return [doc for doc, time in results]
|
||||
|
||||
def item_title(self, item):
|
||||
return "%s : %s" % (item.canonical_name(),item.title)
|
||||
return "%s : %s" % (item.canonical_name(), item.title)
|
||||
|
||||
def item_description(self, item):
|
||||
return item.abstract
|
||||
|
||||
def item_link(self, item):
|
||||
return "https://rfc-editor.org/info/%s"%item.canonical_name()
|
||||
return "https://rfc-editor.org/info/%s" % item.canonical_name()
|
||||
|
||||
def item_pubdate(self, item):
|
||||
return item.publication_time
|
||||
|
||||
def item_extra_kwargs(self, item):
|
||||
extra = super(RfcFeed, self).item_extra_kwargs(item)
|
||||
extra.update({'dcterms_accessRights': 'gratis'})
|
||||
extra.update({'dcterms_format': 'text/html'})
|
||||
extra.update({'media_content': {'url': 'https://rfc-editor.org/rfc/%s.txt' % item.canonical_name(),
|
||||
'link_url': self.item_link(item)
|
||||
}
|
||||
})
|
||||
extra.update({'doi':'10.17487/%s' % item.canonical_name().upper()})
|
||||
extra.update({'doiuri':'http://dx.doi.org/10.17487/%s' % item.canonical_name().upper()})
|
||||
extra.update({"dcterms_accessRights": "gratis"})
|
||||
extra.update({"dcterms_format": "text/html"})
|
||||
media_contents = []
|
||||
if int(item.rfc_number()) < 8650:
|
||||
if int(item.rfc_number()) not in [8, 9, 51, 418, 500, 530, 589]:
|
||||
for fmt, media_type in [("txt", "text/plain"), ("html", "text/html")]:
|
||||
media_contents.append(
|
||||
{
|
||||
"url": f"https://rfc-editor.org/rfc/{item.canonical_name()}.{fmt}",
|
||||
"media_type": media_type,
|
||||
"is_format_of": self.item_link(item),
|
||||
}
|
||||
)
|
||||
if int(item.rfc_number()) not in [571, 587]:
|
||||
media_contents.append(
|
||||
{
|
||||
"url": f"https://www.rfc-editor.org/rfc/pdfrfc/{item.canonical_name()}.txt.pdf",
|
||||
"media_type": "application/pdf",
|
||||
"is_format_of": self.item_link(item),
|
||||
}
|
||||
)
|
||||
else:
|
||||
media_contents.append(
|
||||
{
|
||||
"url": f"https://www.rfc-editor.org/rfc/{item.canonical_name()}.xml",
|
||||
"media_type": "application/rfc+xml",
|
||||
}
|
||||
)
|
||||
for fmt, media_type in [
|
||||
("txt", "text/plain"),
|
||||
("html", "text/html"),
|
||||
("pdf", "application/pdf"),
|
||||
]:
|
||||
media_contents.append(
|
||||
{
|
||||
"url": f"https://rfc-editor.org/rfc/{item.canonical_name()}.{fmt}",
|
||||
"media_type": media_type,
|
||||
"is_format_of": f"https://www.rfc-editor.org/rfc/{item.canonical_name()}.xml",
|
||||
}
|
||||
)
|
||||
extra.update({"media_contents": media_contents})
|
||||
|
||||
extra.update({"doi": "10.17487/%s" % item.canonical_name().upper()})
|
||||
extra.update(
|
||||
{"doiuri": "http://dx.doi.org/10.17487/%s" % item.canonical_name().upper()}
|
||||
)
|
||||
|
||||
#TODO
|
||||
# R104 Publisher (Mandatory - but we need a string from them first)
|
||||
extra.update({'dcterms_publisher':'rfc-editor.org'})
|
||||
extra.update({"dcterms_publisher": "rfc-editor.org"})
|
||||
|
||||
#TODO MAYBE (Optional stuff)
|
||||
# TODO MAYBE (Optional stuff)
|
||||
# R108 License
|
||||
# R115 Creator/Contributor (which would we use?)
|
||||
# F305 Checksum (do they use it?) (or should we put the our digital signature in here somewhere?)
|
||||
|
@ -188,4 +281,3 @@ class RfcFeed(Feed):
|
|||
# R118 Keyword
|
||||
|
||||
return extra
|
||||
|
||||
|
|
|
@ -1911,11 +1911,31 @@ class DocTestCase(TestCase):
|
|||
self.assertContains(r, doc.name)
|
||||
|
||||
def test_rfc_feed(self):
|
||||
WgRfcFactory()
|
||||
rfc = WgRfcFactory(alias2__name="rfc9000")
|
||||
DocEventFactory(doc=rfc, type="published_rfc")
|
||||
r = self.client.get("/feed/rfc/")
|
||||
self.assertTrue(r.status_code, 200)
|
||||
q = PyQuery(r.content[39:]) # Strip off the xml declaration
|
||||
self.assertEqual(len(q("item")), 1)
|
||||
item = q("item")[0]
|
||||
media_content = item.findall("{http://search.yahoo.com/mrss/}content")
|
||||
self.assertEqual(len(media_content),4)
|
||||
types = set([m.attrib["type"] for m in media_content])
|
||||
self.assertEqual(types, set(["application/rfc+xml", "text/plain", "text/html", "application/pdf"]))
|
||||
rfcs_2016 = WgRfcFactory.create_batch(3) # rfc numbers will be well below v3
|
||||
for rfc in rfcs_2016:
|
||||
e = DocEventFactory(doc=rfc, type="published_rfc")
|
||||
e.time = e.time.replace(year=2016)
|
||||
e.save()
|
||||
r = self.client.get("/feed/rfc/2016")
|
||||
self.assertTrue(r.status_code, 200)
|
||||
q = PyQuery(r.content[39:])
|
||||
self.assertEqual(len(q("item")), 3)
|
||||
item = q("item")[0]
|
||||
media_content = item.findall("{http://search.yahoo.com/mrss/}content")
|
||||
self.assertEqual(len(media_content), 3)
|
||||
types = set([m.attrib["type"] for m in media_content])
|
||||
self.assertEqual(types, set(["text/plain", "text/html", "application/pdf"]))
|
||||
|
||||
def test_state_help(self):
|
||||
url = urlreverse('ietf.doc.views_help.state_help', kwargs=dict(type="draft-iesg"))
|
||||
|
|
|
@ -140,17 +140,36 @@ def fill_in_document_table_attributes(docs, have_telechat_date=False):
|
|||
d.obsoleted_by_list = []
|
||||
d.updated_by_list = []
|
||||
|
||||
xed_by = RelatedDocument.objects.filter(target__name__in=list(rfc_aliases.values()),
|
||||
relationship__in=("obs", "updates")).select_related('target')
|
||||
rel_rfc_aliases = dict([ (a.document.id, re.sub(r"rfc(\d+)", r"RFC \1", a.name, flags=re.IGNORECASE)) for a in DocAlias.objects.filter(name__startswith="rfc", docs__id__in=[rel.source_id for rel in xed_by]) ])
|
||||
# Revisit this block after RFCs become first-class Document objects
|
||||
xed_by = list(
|
||||
RelatedDocument.objects.filter(
|
||||
target__name__in=list(rfc_aliases.values()),
|
||||
relationship__in=("obs", "updates"),
|
||||
).select_related("target")
|
||||
)
|
||||
rel_rfc_aliases = {
|
||||
a.document.id: re.sub(r"rfc(\d+)", r"RFC \1", a.name, flags=re.IGNORECASE)
|
||||
for a in DocAlias.objects.filter(
|
||||
name__startswith="rfc", docs__id__in=[rel.source_id for rel in xed_by]
|
||||
)
|
||||
}
|
||||
xed_by.sort(
|
||||
key=lambda rel: int(
|
||||
re.sub(
|
||||
r"rfc\s*(\d+)",
|
||||
r"\1",
|
||||
rel_rfc_aliases[rel.source_id],
|
||||
flags=re.IGNORECASE,
|
||||
)
|
||||
)
|
||||
)
|
||||
for rel in xed_by:
|
||||
d = doc_dict[rel.target.document.id]
|
||||
s = rel_rfc_aliases[rel.source_id]
|
||||
if rel.relationship_id == "obs":
|
||||
l = d.obsoleted_by_list
|
||||
d.obsoleted_by_list.append(s)
|
||||
elif rel.relationship_id == "updates":
|
||||
l = d.updated_by_list
|
||||
l.append(rel_rfc_aliases[rel.source_id])
|
||||
l.sort()
|
||||
d.updated_by_list.append(s)
|
||||
|
||||
def augment_docs_with_related_docs_info(docs):
|
||||
"""Augment all documents with related documents information.
|
||||
|
|
|
@ -114,13 +114,46 @@ def render_document_top(request, doc, tab, name):
|
|||
rsab_ballot,
|
||||
None if rsab_ballot else "RSAB Evaluation Ballot has not been created yet"
|
||||
))
|
||||
if doc.type_id in ("draft","conflrev", "statchg"):
|
||||
tabs.append(("IESG Evaluation Record", "ballot", urlreverse("ietf.doc.views_doc.document_ballot", kwargs=dict(name=name)), iesg_ballot, None if iesg_ballot else "IESG Evaluation Ballot has not been created yet"))
|
||||
elif doc.type_id == "charter" and doc.group.type_id == "wg":
|
||||
tabs.append(("IESG Review", "ballot", urlreverse("ietf.doc.views_doc.document_ballot", kwargs=dict(name=name)), iesg_ballot, None if iesg_ballot else "IESG Review Ballot has not been created yet"))
|
||||
|
||||
if doc.type_id == "draft" or (doc.type_id == "charter" and doc.group.type_id == "wg"):
|
||||
tabs.append(("IESG Writeups", "writeup", urlreverse('ietf.doc.views_doc.document_writeup', kwargs=dict(name=name)), True, None))
|
||||
|
||||
if iesg_ballot or (doc.group and doc.group.type_id == "wg"):
|
||||
if doc.type_id in ("draft", "conflrev", "statchg"):
|
||||
tabs.append(
|
||||
(
|
||||
"IESG Evaluation Record",
|
||||
"ballot",
|
||||
urlreverse(
|
||||
"ietf.doc.views_doc.document_ballot", kwargs=dict(name=name)
|
||||
),
|
||||
iesg_ballot,
|
||||
None,
|
||||
)
|
||||
)
|
||||
elif doc.type_id == "charter" and doc.group and doc.group.type_id == "wg":
|
||||
tabs.append(
|
||||
(
|
||||
"IESG Review",
|
||||
"ballot",
|
||||
urlreverse(
|
||||
"ietf.doc.views_doc.document_ballot", kwargs=dict(name=name)
|
||||
),
|
||||
iesg_ballot,
|
||||
None,
|
||||
)
|
||||
)
|
||||
if doc.type_id == "draft" or (
|
||||
doc.type_id == "charter" and doc.group and doc.group.type_id == "wg"
|
||||
):
|
||||
tabs.append(
|
||||
(
|
||||
"IESG Writeups",
|
||||
"writeup",
|
||||
urlreverse(
|
||||
"ietf.doc.views_doc.document_writeup", kwargs=dict(name=name)
|
||||
),
|
||||
True,
|
||||
None,
|
||||
)
|
||||
)
|
||||
|
||||
tabs.append(("Email expansions","email",urlreverse('ietf.doc.views_doc.document_email', kwargs=dict(name=name)), True, None))
|
||||
tabs.append(("History", "history", urlreverse('ietf.doc.views_doc.document_history', kwargs=dict(name=name)), True, None))
|
||||
|
@ -151,6 +184,7 @@ def interesting_doc_relations(doc):
|
|||
|
||||
that_doc_relationships = ('replaces', 'possibly_replaces', 'updates', 'obs')
|
||||
|
||||
# TODO: This returns the relationships in database order, which may not be the order we want to display them in.
|
||||
interesting_relations_that = cls.objects.filter(target__docs=target, relationship__in=that_relationships).select_related('source')
|
||||
interesting_relations_that_doc = cls.objects.filter(source=doc, relationship__in=that_doc_relationships).prefetch_related('target__docs')
|
||||
|
||||
|
|
|
@ -343,7 +343,7 @@ class NominateForm(forms.ModelForm):
|
|||
'year': self.nomcom.year(),
|
||||
}
|
||||
path = nomcom_template_path + NOMINATION_RECEIPT_TEMPLATE
|
||||
send_mail(None, to_email, from_email, subject, path, context, cc=cc)
|
||||
send_mail(None, to_email, from_email, subject, path, context, cc=cc, copy=False, save=False)
|
||||
|
||||
return nomination
|
||||
|
||||
|
@ -458,7 +458,7 @@ class NominateNewPersonForm(forms.ModelForm):
|
|||
'year': self.nomcom.year(),
|
||||
}
|
||||
path = nomcom_template_path + NOMINATION_RECEIPT_TEMPLATE
|
||||
send_mail(None, to_email, from_email, subject, path, context, cc=cc)
|
||||
send_mail(None, to_email, from_email, subject, path, context, cc=cc, copy=False, save=False)
|
||||
|
||||
return nomination
|
||||
|
||||
|
@ -551,7 +551,7 @@ class FeedbackForm(forms.ModelForm):
|
|||
}
|
||||
path = nomcom_template_path + FEEDBACK_RECEIPT_TEMPLATE
|
||||
# TODO - make the thing above more generic
|
||||
send_mail(None, to_email, from_email, subject, path, context, cc=cc, copy=False)
|
||||
send_mail(None, to_email, from_email, subject, path, context, cc=cc, copy=False, save=False)
|
||||
|
||||
class Meta:
|
||||
model = Feedback
|
||||
|
|
|
@ -122,7 +122,7 @@ class NomcomViewsTest(TestCase):
|
|||
self.check_url_status(url, 200)
|
||||
self.client.logout()
|
||||
login_testing_unauthorized(self, MEMBER_USER, url)
|
||||
return self.check_url_status(url, 200)
|
||||
self.check_url_status(url, 200)
|
||||
|
||||
def access_chair_url(self, url):
|
||||
login_testing_unauthorized(self, COMMUNITY_USER, url)
|
||||
|
@ -134,7 +134,7 @@ class NomcomViewsTest(TestCase):
|
|||
login_testing_unauthorized(self, COMMUNITY_USER, url)
|
||||
login_testing_unauthorized(self, CHAIR_USER, url)
|
||||
login_testing_unauthorized(self, SECRETARIAT_USER, url)
|
||||
return self.check_url_status(url, 200)
|
||||
self.check_url_status(url, 200)
|
||||
|
||||
def test_private_index_view(self):
|
||||
"""Verify private home view"""
|
||||
|
@ -599,6 +599,8 @@ class NomcomViewsTest(TestCase):
|
|||
self.nominate_view(public=True,confirmation=True)
|
||||
|
||||
self.assertEqual(len(outbox), messages_before + 3)
|
||||
self.assertEqual(Message.objects.count(), 2)
|
||||
self.assertFalse(Message.objects.filter(subject="Nomination receipt").exists())
|
||||
|
||||
self.assertEqual('IETF Nomination Information', outbox[-3]['Subject'])
|
||||
self.assertEqual(self.email_from, outbox[-3]['From'])
|
||||
|
@ -625,8 +627,7 @@ class NomcomViewsTest(TestCase):
|
|||
|
||||
def test_private_nominate(self):
|
||||
self.access_member_url(self.private_nominate_url)
|
||||
return self.nominate_view(public=False)
|
||||
self.client.logout()
|
||||
self.nominate_view(public=False)
|
||||
|
||||
def test_public_nominate_newperson(self):
|
||||
login_testing_unauthorized(self, COMMUNITY_USER, self.public_nominate_url)
|
||||
|
@ -666,13 +667,13 @@ class NomcomViewsTest(TestCase):
|
|||
|
||||
def test_private_nominate_newperson(self):
|
||||
self.access_member_url(self.private_nominate_url)
|
||||
return self.nominate_newperson_view(public=False)
|
||||
self.client.logout()
|
||||
self.nominate_newperson_view(public=False, confirmation=True)
|
||||
self.assertFalse(Message.objects.filter(subject="Nomination receipt").exists())
|
||||
|
||||
def test_private_nominate_newperson_who_already_exists(self):
|
||||
EmailFactory(address='nominee@example.com')
|
||||
self.access_member_url(self.private_nominate_newperson_url)
|
||||
return self.nominate_newperson_view(public=False)
|
||||
self.nominate_newperson_view(public=False)
|
||||
|
||||
def test_public_nominate_with_automatic_questionnaire(self):
|
||||
nomcom = get_nomcom_by_year(self.year)
|
||||
|
@ -844,8 +845,7 @@ class NomcomViewsTest(TestCase):
|
|||
|
||||
def test_add_questionnaire(self):
|
||||
self.access_chair_url(self.add_questionnaire_url)
|
||||
return self.add_questionnaire()
|
||||
self.client.logout()
|
||||
self.add_questionnaire()
|
||||
|
||||
def add_questionnaire(self, *args, **kwargs):
|
||||
public = kwargs.pop('public', False)
|
||||
|
@ -906,6 +906,8 @@ class NomcomViewsTest(TestCase):
|
|||
# We're interested in the confirmation receipt here
|
||||
self.assertEqual(len(outbox),3)
|
||||
self.assertEqual('NomCom comment confirmation', outbox[2]['Subject'])
|
||||
self.assertEqual(Message.objects.count(), 2)
|
||||
self.assertFalse(Message.objects.filter(subject="NomCom comment confirmation").exists())
|
||||
email_body = get_payload_text(outbox[2])
|
||||
self.assertIn(position, email_body)
|
||||
self.assertNotIn('$', email_body)
|
||||
|
@ -920,7 +922,7 @@ class NomcomViewsTest(TestCase):
|
|||
|
||||
def test_private_feedback(self):
|
||||
self.access_member_url(self.private_feedback_url)
|
||||
return self.feedback_view(public=False)
|
||||
self.feedback_view(public=False)
|
||||
|
||||
def feedback_view(self, *args, **kwargs):
|
||||
public = kwargs.pop('public', True)
|
||||
|
|
|
@ -9,13 +9,20 @@
|
|||
<p id="instructions" class="alert alert-info my-3">
|
||||
{% if nomcom.group.state_id == 'conclude' %}
|
||||
Feedback to this NomCom is closed.
|
||||
{% elif positions|length != 0 and topics|length != 0 %}
|
||||
Select a nominee or topic from the list on the right to obtain a new feedback form.
|
||||
{% elif positions|length != 0 %}
|
||||
Select a nominee from the list on the right to obtain a new feedback form.
|
||||
{% elif topics|length != 0 %}
|
||||
Select a topic from the list on the right to obtain a new feedback form.
|
||||
{% else %}
|
||||
Select a nominee from the list of nominees on the right to obtain a new feedback form.
|
||||
This NomCom is not accepting feedback at this time.
|
||||
{% endif %}
|
||||
</p>
|
||||
{% if nomcom|has_publickey %}
|
||||
<div class="row">
|
||||
<div id="nominees" class="col-sm-2 order-last">
|
||||
{% if positions|length != 0 %}
|
||||
<h2 class="navskip mt-4">Nominees</h2>
|
||||
<p>
|
||||
A number after a name indicates
|
||||
|
@ -43,6 +50,8 @@
|
|||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if topics|length != 0 %}
|
||||
<h2 class="navskip mt-4">Topics</h2>
|
||||
<div class="d-grid gap-3">
|
||||
{% for t in topics %}
|
||||
|
@ -58,6 +67,7 @@
|
|||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="col-sm-10">
|
||||
{% if form %}
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
"caniuse-lite": "1.0.30001495",
|
||||
"d3": "7.8.5",
|
||||
"file-saver": "2.0.5",
|
||||
"highcharts": "11.0.1",
|
||||
"highcharts": "11.1.0",
|
||||
"ical.js": "1.5.0",
|
||||
"jquery": "3.7.0",
|
||||
"js-cookie": "3.0.5",
|
||||
|
@ -70,7 +70,7 @@
|
|||
"jquery-migrate": "3.4.1",
|
||||
"parcel": "2.9.1",
|
||||
"pug": "3.0.2",
|
||||
"sass": "1.62.1",
|
||||
"sass": "1.63.4",
|
||||
"seedrandom": "3.0.5",
|
||||
"vite": "4.3.9"
|
||||
},
|
||||
|
|
20
yarn.lock
20
yarn.lock
|
@ -4429,10 +4429,10 @@ browserlist@latest:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"highcharts@npm:11.0.1":
|
||||
version: 11.0.1
|
||||
resolution: "highcharts@npm:11.0.1"
|
||||
checksum: 773a7b876502d616b7c5f522610b061cc714233a6ecdd7f7d073151fdf53bc597c01a758fbda5bba9069a0ee487e7defddfbdb1de73a78db6267a9257250137c
|
||||
"highcharts@npm:11.1.0":
|
||||
version: 11.1.0
|
||||
resolution: "highcharts@npm:11.1.0"
|
||||
checksum: f9b8cdc38b3b41bcc4c3a2331d9b1c769400639e2d0094484a0f5274aaba619551b95b442a69f7f4e47c2c8445681e3651f6036207fe1928a1a982f5278ae85e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -6651,7 +6651,7 @@ browserlist@latest:
|
|||
eslint-plugin-promise: 6.1.1
|
||||
eslint-plugin-vue: 9.14.1
|
||||
file-saver: 2.0.5
|
||||
highcharts: 11.0.1
|
||||
highcharts: 11.1.0
|
||||
html-validate: 7.18.1
|
||||
ical.js: 1.5.0
|
||||
jquery: 3.7.0
|
||||
|
@ -6670,7 +6670,7 @@ browserlist@latest:
|
|||
pinia: 2.1.3
|
||||
pinia-plugin-persist: 1.0.0
|
||||
pug: 3.0.2
|
||||
sass: 1.62.1
|
||||
sass: 1.63.4
|
||||
seedrandom: 3.0.5
|
||||
select2: 4.1.0-rc.0
|
||||
select2-bootstrap-5-theme: 1.3.0
|
||||
|
@ -6734,16 +6734,16 @@ browserlist@latest:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"sass@npm:1.62.1":
|
||||
version: 1.62.1
|
||||
resolution: "sass@npm:1.62.1"
|
||||
"sass@npm:1.63.4":
|
||||
version: 1.63.4
|
||||
resolution: "sass@npm:1.63.4"
|
||||
dependencies:
|
||||
chokidar: ">=3.0.0 <4.0.0"
|
||||
immutable: ^4.0.0
|
||||
source-map-js: ">=0.6.2 <2.0.0"
|
||||
bin:
|
||||
sass: sass.js
|
||||
checksum: 1b1b3584b38a63dd94156b65f13b90e3f84b170a38c3d5e3fa578b7a32a37aeb349b4926b0eaf9448d48e955e86b1ee01b13993f19611dad8068af07a607c13b
|
||||
checksum: 12bde5beff85a7018157d90c8b9d5aec8b56832f89fcfeca146f10936eecf97e669d22fd41f812b3407ed259bbb114d69c9ecbfc7ee9b15308211fb910cdf5eb
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
|
Loading…
Reference in a new issue