mirror of
https://github.com/QingdaoU/OpenVJ.git
synced 2025-01-16 01:13:36 +00:00
增加部分django和celery设置,同时实验获取题目详情
This commit is contained in:
parent
44749dd94c
commit
960d060109
@ -0,0 +1,3 @@
|
||||
# coding=utf-8
|
||||
from __future__ import absolute_import
|
||||
from .celery import app as celery_app
|
19
openvj/celery.py
Normal file
19
openvj/celery.py
Normal file
@ -0,0 +1,19 @@
|
||||
# coding=utf-8
|
||||
from __future__ import absolute_import
|
||||
import os
|
||||
|
||||
from celery import Celery
|
||||
|
||||
# set the default Django settings module for the 'celery' program.
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'openvj.settings')
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
app = Celery('openvj')
|
||||
|
||||
# Using a string here means the worker will not have to
|
||||
# pickle the object when using Windows.
|
||||
app.config_from_object('django.conf:settings')
|
||||
|
||||
# load task modules from all registered Django app configs.
|
||||
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
|
@ -19,3 +19,18 @@ DATABASES = {
|
||||
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
REDIS = {
|
||||
"HOST": "127.0.0.1",
|
||||
"PORT": 6379,
|
||||
"PASSWORD": "123456"
|
||||
}
|
||||
|
||||
|
||||
# celery配置
|
||||
BROKER_URL = "redis://{host}:{port}/{db}".format(host=REDIS["HOST"], port=REDIS["PORT"], db=0)
|
||||
CELERY_RESULT_BACKEND = "redis"
|
||||
CELERY_REDIS_HOST = REDIS["HOST"]
|
||||
CELERY_REDIS_PORT = REDIS["PORT"]
|
||||
CELERY_REDIS_DB = 0
|
@ -19,3 +19,5 @@ DATABASES = {
|
||||
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
|
||||
}
|
||||
}
|
||||
|
||||
BROKER_URL = 'amqp://guest:guest@localhost//'
|
@ -44,7 +44,9 @@ INSTALLED_APPS = [
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
|
||||
'rest_framework',
|
||||
'server',
|
||||
|
||||
]
|
||||
|
||||
MIDDLEWARE_CLASSES = [
|
||||
@ -103,7 +105,7 @@ AUTH_PASSWORD_VALIDATORS = [
|
||||
|
||||
LANGUAGE_CODE = 'zh-hans'
|
||||
|
||||
TIME_ZONE = 'UTC'
|
||||
TIME_ZONE = 'Asia/Shanghai'
|
||||
|
||||
USE_I18N = True
|
||||
|
||||
|
@ -16,6 +16,9 @@ Including another URLconf
|
||||
from django.conf.urls import url
|
||||
from django.contrib import admin
|
||||
|
||||
from server.views import ProblemAPIView
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^admin/', admin.site.urls),
|
||||
url(r'^problem/$', ProblemAPIView.as_view()),
|
||||
]
|
||||
|
@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.9.4 on 2016-03-08 08:20
|
||||
# Generated by Django 1.9.4 on 2016-03-09 06:08
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
@ -32,6 +32,7 @@ class Migration(migrations.Migration):
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=30)),
|
||||
('robot', models.CharField(max_length=50)),
|
||||
('is_valid', models.BooleanField(default=True)),
|
||||
],
|
||||
options={
|
||||
@ -43,18 +44,18 @@ class Migration(migrations.Migration):
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('url', models.URLField()),
|
||||
('submit_url', models.URLField()),
|
||||
('title', models.CharField(max_length=100)),
|
||||
('description', models.TextField()),
|
||||
('time_limit', models.IntegerField()),
|
||||
('memory_limit', models.IntegerField()),
|
||||
('input_description', models.TextField()),
|
||||
('output_description', models.TextField()),
|
||||
('samples', models.TextField()),
|
||||
('spj', models.BooleanField()),
|
||||
('hint', models.TextField()),
|
||||
('submit_url', models.URLField(blank=True, null=True)),
|
||||
('title', models.CharField(blank=True, max_length=100, null=True)),
|
||||
('description', models.TextField(blank=True, null=True)),
|
||||
('time_limit', models.IntegerField(blank=True, null=True)),
|
||||
('memory_limit', models.IntegerField(blank=True, null=True)),
|
||||
('input_description', models.TextField(blank=True, null=True)),
|
||||
('output_description', models.TextField(blank=True, null=True)),
|
||||
('samples', models.TextField(blank=True, null=True)),
|
||||
('spj', models.BooleanField(default=False)),
|
||||
('hint', models.TextField(blank=True, null=True)),
|
||||
('is_valid', models.BooleanField(default=True)),
|
||||
('status', models.IntegerField()),
|
||||
('status', models.IntegerField(choices=[(0, 'Done'), (1, 'Crawling'), (2, 'Failed')])),
|
||||
('task_id', models.CharField(max_length=40)),
|
||||
('oj', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='server.OJ')),
|
||||
],
|
||||
@ -62,6 +63,12 @@ class Migration(migrations.Migration):
|
||||
'db_table': 'problem',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ProblemStatus',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='RobotStatusInfo',
|
||||
fields=[
|
||||
@ -81,7 +88,7 @@ class Migration(migrations.Migration):
|
||||
('password', models.CharField(max_length=30)),
|
||||
('is_valid', models.BooleanField(default=True)),
|
||||
('last_login_time', models.DateTimeField()),
|
||||
('status', models.IntegerField(choices=[('Occupied', 1), ('free', 0)])),
|
||||
('status', models.IntegerField(choices=[(1, 'Occupied'), (0, 'Free')])),
|
||||
('oj', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='server.OJ')),
|
||||
],
|
||||
options={
|
||||
|
@ -6,11 +6,15 @@ from django.db import models
|
||||
|
||||
class OJ(models.Model):
|
||||
name = models.CharField(max_length=30)
|
||||
robot = models.CharField(max_length=50)
|
||||
is_valid = models.BooleanField(default=True)
|
||||
|
||||
class Meta:
|
||||
db_table = "oj"
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
class APIKey(models.Model):
|
||||
api_key = models.CharField(max_length=40)
|
||||
@ -21,6 +25,9 @@ class APIKey(models.Model):
|
||||
class Meta:
|
||||
db_table = "api_key"
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
class RobotUserStatus(object):
|
||||
occupied = 1
|
||||
@ -39,6 +46,9 @@ class RobotUser(models.Model):
|
||||
db_table = "robot_user"
|
||||
unique_together = (("oj", "username"), )
|
||||
|
||||
def __str__(self):
|
||||
return self.oj.name + " - " + self.username
|
||||
|
||||
|
||||
class RobotStatusInfo(models.Model):
|
||||
status_info = models.TextField()
|
||||
@ -48,6 +58,9 @@ class RobotStatusInfo(models.Model):
|
||||
class Meta:
|
||||
db_table = "robot_status_info"
|
||||
|
||||
def __str__(self):
|
||||
return self.robot_user.username + self.status_info
|
||||
|
||||
|
||||
class ProblemStatus(models.Model):
|
||||
done = 0
|
||||
@ -58,16 +71,16 @@ class ProblemStatus(models.Model):
|
||||
class Problem(models.Model):
|
||||
oj = models.ForeignKey(OJ)
|
||||
url = models.URLField()
|
||||
submit_url = models.URLField()
|
||||
title = models.CharField(max_length=100)
|
||||
description = models.TextField()
|
||||
time_limit = models.IntegerField()
|
||||
memory_limit = models.IntegerField()
|
||||
input_description = models.TextField()
|
||||
output_description = models.TextField()
|
||||
samples = models.TextField()
|
||||
spj = models.BooleanField()
|
||||
hint = models.TextField()
|
||||
submit_url = models.URLField(blank=True, null=True)
|
||||
title = models.CharField(max_length=100, blank=True, null=True)
|
||||
description = models.TextField(blank=True, null=True)
|
||||
time_limit = models.IntegerField(blank=True, null=True)
|
||||
memory_limit = models.IntegerField(blank=True, null=True)
|
||||
input_description = models.TextField(blank=True, null=True)
|
||||
output_description = models.TextField(blank=True, null=True)
|
||||
samples = models.TextField(blank=True, null=True)
|
||||
spj = models.BooleanField(default=False)
|
||||
hint = models.TextField(blank=True, null=True)
|
||||
is_valid = models.BooleanField(default=True)
|
||||
status = models.IntegerField(choices=((ProblemStatus.done, "Done"),
|
||||
(ProblemStatus.crawling, "Crawling"),
|
||||
@ -77,6 +90,12 @@ class Problem(models.Model):
|
||||
class Meta:
|
||||
db_table = "problem"
|
||||
|
||||
def __str__(self):
|
||||
if not self.title:
|
||||
return self.oj.name + " Problem Status: " + str(self.status)
|
||||
else:
|
||||
return self.oj.name + " - " + self.title
|
||||
|
||||
|
||||
class Submission(models.Model):
|
||||
problem = models.ForeignKey(Problem)
|
||||
|
9
server/serializers.py
Normal file
9
server/serializers.py
Normal file
@ -0,0 +1,9 @@
|
||||
# coding=utf-8
|
||||
from rest_framework import serializers
|
||||
|
||||
from .models import Problem
|
||||
|
||||
|
||||
class ProblemSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Problem
|
8
server/tasks.py
Normal file
8
server/tasks.py
Normal file
@ -0,0 +1,8 @@
|
||||
# coding=utf-8
|
||||
from __future__ import absolute_import
|
||||
from celery import shared_task
|
||||
|
||||
|
||||
@shared_task
|
||||
def get_problem(robot, url):
|
||||
return robot.get_problem(url)
|
@ -1,3 +1,80 @@
|
||||
from django.shortcuts import render
|
||||
# coding=utf-8
|
||||
import json
|
||||
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework.response import Response
|
||||
from celery import states
|
||||
|
||||
|
||||
from .serializers import ProblemSerializer
|
||||
from .models import OJ, Problem, RobotUser, RobotStatusInfo, ProblemStatus
|
||||
from .tasks import get_problem
|
||||
|
||||
|
||||
def error_response(error_reason):
|
||||
return Response(data={"code": 1, "data": error_reason})
|
||||
|
||||
|
||||
def serializer_invalid_response(serializer):
|
||||
for k, v in serializer.errors.iteritems():
|
||||
return error_response(k + " : " + v[0])
|
||||
|
||||
|
||||
def success_response(data):
|
||||
return Response(data={"code": 0, "data": data})
|
||||
|
||||
|
||||
def import_class(cl):
|
||||
d = cl.rfind(".")
|
||||
class_name = cl[d+1:len(cl)]
|
||||
m = __import__(cl[0:d], globals(), locals(), [class_name])
|
||||
return getattr(m, class_name)
|
||||
|
||||
|
||||
class ProblemAPIView(APIView):
|
||||
def get(self, request):
|
||||
oj = request.GET.get("oj")
|
||||
url = request.GET.get("url")
|
||||
if not (oj and url):
|
||||
return error_response("参数错误")
|
||||
try:
|
||||
problem = Problem.objects.get(url=url, is_valid=True)
|
||||
if problem.status == ProblemStatus.done:
|
||||
return success_response(ProblemSerializer(problem).data)
|
||||
elif problem.status == ProblemStatus.crawling:
|
||||
task = get_problem.AsyncResult(problem.task_id)
|
||||
if task.state == states.SUCCESS:
|
||||
result = task.get()
|
||||
problem.title = result["title"]
|
||||
problem.submit_url = result["submit_url"]
|
||||
problem.description = result["description"]
|
||||
problem.time_limit = result["time_limit"]
|
||||
problem.memory_limit = result["memory_limit"]
|
||||
problem.input_description = result["input_description"]
|
||||
problem.output_description = result["output_description"]
|
||||
problem.samples = json.dumps(result["samples"])
|
||||
problem.status = ProblemStatus.done
|
||||
problem.save()
|
||||
return success_response(ProblemSerializer(problem).data)
|
||||
elif task.state == states.FAILURE:
|
||||
problem.status = ProblemStatus.failed
|
||||
problem.save()
|
||||
return success_response({"status": ProblemStatus.failed})
|
||||
elif problem.status == ProblemStatus.failed:
|
||||
return success_response({"status": ProblemStatus.failed})
|
||||
except Problem.DoesNotExist:
|
||||
pass
|
||||
try:
|
||||
oj = OJ.objects.get(name=oj, is_valid=True)
|
||||
except OJ.DoesNotExist:
|
||||
return error_response("不存在该oj")
|
||||
robot_status = RobotStatusInfo.objects.filter(robot_user__oj=oj).first()
|
||||
if not robot_status:
|
||||
return error_response("登录信息错误")
|
||||
robot = import_class(oj.robot)(**json.loads(robot_status.status_info))
|
||||
if not robot.check_url(url):
|
||||
return error_response("url格式错误")
|
||||
task_id = get_problem.delay(robot, url).id
|
||||
Problem.objects.create(oj=oj, url=url, status=ProblemStatus.crawling, task_id=task_id)
|
||||
return success_response({"status": ProblemStatus.crawling})
|
||||
|
||||
# Create your views here.
|
||||
|
Loading…
x
Reference in New Issue
Block a user