diff --git a/.gitignore b/.gitignore index 8b3b73ff..6dbdf64c 100644 --- a/.gitignore +++ b/.gitignore @@ -77,3 +77,5 @@ http_locations.conf https_locations.conf venv/ +#test docker-compose +docker-compose.yml \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index ac84fa0a..5af64802 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,15 +1,16 @@ language: python python: - - "3.6" + - "3.8" services: - docker + - postgresql install: - pip install -r deploy/requirements.txt - echo `cat /dev/urandom | head -1 | md5sum | head -c 32` > data/config/secret.key - ./init_db.sh script: - docker ps -a - - flake8 . + - flake8 --config=./.flake8 . - coverage run --include="$PWD/*" manage.py test - coverage report notifications: diff --git a/Dockerfile b/Dockerfile index f66305b3..a43e4d6a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,11 @@ -FROM python:3.7-alpine3.9 +FROM python:3.8-alpine3.14 ENV OJ_ENV production ADD . /app WORKDIR /app -HEALTHCHECK --interval=5s --retries=3 CMD python2 /app/deploy/health_check.py +HEALTHCHECK --interval=5s --retries=3 CMD python3 /app/deploy/health_check.py RUN apk add --update --no-cache build-base nginx openssl curl unzip supervisor jpeg-dev zlib-dev postgresql-dev freetype-dev && \ pip install --no-cache-dir -r /app/deploy/requirements.txt && \ diff --git a/account/views/admin.py b/account/views/admin.py index 77b305ae..b207db92 100644 --- a/account/views/admin.py +++ b/account/views/admin.py @@ -151,7 +151,7 @@ class GenerateUserAPI(APIView): raw_data = f.read() os.remove(file_path) response = HttpResponse(raw_data) - response["Content-Disposition"] = f"attachment; filename=users.xlsx" + response["Content-Disposition"] = "attachment; filename=users.xlsx" response["Content-Type"] = "application/xlsx" return response diff --git a/account/views/oj.py b/account/views/oj.py index 2d26e484..2a3c2e09 100644 --- a/account/views/oj.py +++ b/account/views/oj.py @@ -305,7 +305,7 @@ class ApplyResetPasswordAPI(APIView): send_email_async.send(from_name=SysOptions.website_name_shortcut, to_email=user.email, to_name=user.username, - subject=f"Reset your password", + subject="Reset your password", content=email_html) return self.success("Succeeded") diff --git a/conf/tests.py b/conf/tests.py index dce80c68..fbb4022e 100644 --- a/conf/tests.py +++ b/conf/tests.py @@ -71,7 +71,7 @@ class WebsiteConfigAPITest(APITestCase): "allow_register": True, "submission_list_show_all": False} resp = self.client.post(url, data=data) self.assertSuccess(resp) - self.assertEqual(SysOptions.website_footer, "") + self.assertEqual(SysOptions.website_footer, '') def test_get_website_config(self): # do not need to login diff --git a/deploy/health_check.py b/deploy/health_check.py index f5065a25..472d9e84 100644 --- a/deploy/health_check.py +++ b/deploy/health_check.py @@ -1,11 +1,11 @@ -import xmlrpclib +import xmlrpc.client if __name__ == "__main__": try: - server = xmlrpclib.Server("http://localhost:9005/RPC2") - info = server.supervisor.getAllProcessInfo() - error_states = list(filter(lambda x: x["state"] != 20, info)) - exit(len(error_states)) + with xmlrpc.client.ServerProxy("http://localhost:9005/RPC2") as server: + info = server.supervisor.getAllProcessInfo() + error_states = list(filter(lambda x: x["state"] != 20, info)) + exit(len(error_states)) except Exception as e: print(e.with_traceback()) exit(1) diff --git a/deploy/requirements.txt b/deploy/requirements.txt index b0c6fe9b..ed9a9337 100644 --- a/deploy/requirements.txt +++ b/deploy/requirements.txt @@ -1,32 +1,33 @@ certifi==2019.3.9 chardet==3.0.4 -coverage==4.5.3 -Django==2.1.7 -django-redis==4.10.0 -djangorestframework==3.8.2 +coverage==6.1.2 +Django==3.2.9 +django-redis==5.0.0 +djangorestframework==3.12.4 entrypoints==0.3 Envelopes==0.4 -flake8==3.7.7 -flake8-coding==1.3.1 -flake8-quotes==1.0.0 -gunicorn==19.9.0 -idna==2.8 -jsonfield==2.0.2 +flake8==4.0.1 +flake8-coding==1.3.2 +flake8-quotes==3.3.1 +gunicorn==20.1.0 +idna==3.3 +jsonfield==3.1.0 mccabe==0.6.1 otpauth==1.0.1 -Pillow==5.4.1 -psycopg2-binary==2.7.7 -pycodestyle==2.5.0 -pyflakes==2.1.1 -python-dateutil==2.8.0 -pytz==2018.9 -qrcode==6.1 +Pillow==8.4.0 +psycopg2==2.9.2 +pycodestyle==2.8.0 +pyflakes==2.4.0 +python-dateutil==2.8.2 +pytz==2021.3 +qrcode==7.3.1 raven==6.10.0 -redis==3.2.0 -requests==2.21.0 -six==1.12.0 -urllib3==1.24.1 -XlsxWriter==1.1.5 -django-dramatiq==0.5.0 -dramatiq==1.3.0 +redis==3.5.3 +requests==2.26.0 +six==1.16.0 +urllib3==1.26.7 +XlsxWriter==3.0.2 +django-dramatiq==0.10.0 +dramatiq==1.12.0 django-dbconn-retry==0.1.5 +django-cas-ng==4.2.1 diff --git a/docs/data.json b/docs/data.json index 37edcd52..a80acac1 100644 --- a/docs/data.json +++ b/docs/data.json @@ -1,5 +1,16 @@ { "update": [ + { + "version": "2021-11-20", + "level": "Important", + "title": "2021-11-20", + "details": [ + "django2.x即将停止支持,更新django到3.x LTS,相应地更新了全部相关依赖", + "合并底包版本到python3.8-alpine3.14,为移除python2做准备", + "按上游包的生产环境规范,修改依赖psycopg2_binary为psycopg2", + "TODO:本地开发环境搭建文档应做相应修改和提交。" + ] + }, { "version": "2021-09-28", "level": "Recommend", diff --git a/oj/settings.py b/oj/settings.py index c1141a02..74c559bc 100644 --- a/oj/settings.py +++ b/oj/settings.py @@ -244,3 +244,5 @@ RAVEN_CONFIG = { } IP_HEADER = "HTTP_X_REAL_IP" + +DEFAULT_AUTO_FIELD='django.db.models.AutoField' \ No newline at end of file diff --git a/problem/views/admin.py b/problem/views/admin.py index 280e4fa1..5ce9413b 100644 --- a/problem/views/admin.py +++ b/problem/views/admin.py @@ -542,7 +542,7 @@ class ExportProblemAPI(APIView): delete_files.send_with_options(args=(path,), delay=300_000) resp = FileResponse(open(path, "rb")) resp["Content-Type"] = "application/zip" - resp["Content-Disposition"] = f"attachment;filename=problem-export.zip" + resp["Content-Disposition"] = "attachment;filename=problem-export.zip" return resp diff --git a/run_test.py b/run_test.py index cb4c6300..a6c714f6 100644 --- a/run_test.py +++ b/run_test.py @@ -21,7 +21,7 @@ print("running flake8...") if os.system("flake8 --statistics ."): exit() -ret = os.system("coverage run --include=\"$PWD/*\" manage.py test {module} --settings={setting}".format(module=test_module, setting=setting)) +ret = os.system('coverage run --include="$PWD/*" manage.py test {module} --settings={setting}'.format(module=test_module, setting=setting)) if not ret and is_coverage: os.system("coverage html && open htmlcov/index.html") diff --git a/utils/management/commands/inituser.py b/utils/management/commands/inituser.py index a1ca73c8..e7769367 100644 --- a/utils/management/commands/inituser.py +++ b/utils/management/commands/inituser.py @@ -36,7 +36,7 @@ class Command(BaseCommand): user = User.objects.get(username=username) user.set_password(password) user.save() - self.stdout.write(self.style.SUCCESS(f"Password is rested")) + self.stdout.write(self.style.SUCCESS("Password is rested")) except User.DoesNotExist: self.stdout.write(self.style.ERROR(f"User {username} doesnot exist, operation ignored")) exit(1) diff --git a/utils/models.py b/utils/models.py index 9a1cd0ba..7577f1fa 100644 --- a/utils/models.py +++ b/utils/models.py @@ -1,4 +1,4 @@ -from django.contrib.postgres.fields import JSONField # NOQA +from django.db.models import JSONField # NOQA from django.db import models from utils.xss_filter import XSSHtml