Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
8f35e873a2
|
@ -90,7 +90,7 @@ CHANNEL_LAYERS = {
|
||||||
'BACKEND': 'channels_redis.core.RedisChannelLayer',
|
'BACKEND': 'channels_redis.core.RedisChannelLayer',
|
||||||
'CONFIG': {
|
'CONFIG': {
|
||||||
"hosts": ["redis://:newmedia2020@210.72.82.249:6379/0"],
|
"hosts": ["redis://:newmedia2020@210.72.82.249:6379/0"],
|
||||||
"symmetric_encryption_keys": [SECRET_KEY],
|
# "symmetric_encryption_keys": [SECRET_KEY],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,6 +108,7 @@ class Userprofile(models.Model):
|
||||||
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||||
name = models.CharField('姓名', null=True, blank=True, max_length=256)
|
name = models.CharField('姓名', null=True, blank=True, max_length=256)
|
||||||
sex = models.CharField('性别', null=True, blank=True, max_length=256)
|
sex = models.CharField('性别', null=True, blank=True, max_length=256)
|
||||||
|
unit = models.CharField('自己输入单位', null=True, blank=True, max_length=256)
|
||||||
department = models.CharField('部门', null=True, blank=True, max_length=256)
|
department = models.CharField('部门', null=True, blank=True, max_length=256)
|
||||||
post = models.CharField('职务', null=True, blank=True, max_length=256)
|
post = models.CharField('职务', null=True, blank=True, max_length=256)
|
||||||
image = models.FileField(upload_to='profile', null=True, blank=True)
|
image = models.FileField(upload_to='profile', null=True, blank=True)
|
||||||
|
|
|
@ -6,7 +6,7 @@ from channels.generic.websocket import AsyncWebsocketConsumer
|
||||||
class ChatConsumer(AsyncWebsocketConsumer):
|
class ChatConsumer(AsyncWebsocketConsumer):
|
||||||
async def connect(self):
|
async def connect(self):
|
||||||
self.room_name = self.scope['url_route']['kwargs']['room_name']
|
self.room_name = self.scope['url_route']['kwargs']['room_name']
|
||||||
self.room_group_name = 'chat_%s' % self.room_name
|
self.room_group_name = self.room_name
|
||||||
|
|
||||||
# Join room group
|
# Join room group
|
||||||
await self.channel_layer.group_add(
|
await self.channel_layer.group_add(
|
||||||
|
@ -26,22 +26,23 @@ class ChatConsumer(AsyncWebsocketConsumer):
|
||||||
# Receive message from WebSocket
|
# Receive message from WebSocket
|
||||||
async def receive(self, text_data):
|
async def receive(self, text_data):
|
||||||
text_data_json = json.loads(text_data)
|
text_data_json = json.loads(text_data)
|
||||||
message = text_data_json['message']
|
print('receive from websock', text_data_json)
|
||||||
|
# message = text_data_json['message']
|
||||||
|
|
||||||
# Send message to room group
|
# # Send message to room group
|
||||||
await self.channel_layer.group_send(
|
# await self.channel_layer.group_send(
|
||||||
self.room_group_name,
|
# self.room_group_name,
|
||||||
{
|
# {
|
||||||
'type': 'chat_message',
|
# 'type': 'chat_message',
|
||||||
'message': message
|
# 'message': message
|
||||||
}
|
# }
|
||||||
)
|
# )
|
||||||
|
|
||||||
# Receive message from room group
|
# Receive message from room group
|
||||||
async def chat_message(self, event):
|
async def chat_message(self, event):
|
||||||
message = event['message']
|
message = event['message']
|
||||||
|
print('receive from room group', event)
|
||||||
# Send message to WebSocket
|
# Send message to WebSocket
|
||||||
await self.send(text_data=json.dumps({
|
# await self.send(text_data=json.dumps({
|
||||||
'message': message
|
# 'message': message
|
||||||
}))
|
# }))
|
||||||
|
|
17
polls/job.py
17
polls/job.py
|
@ -1,17 +0,0 @@
|
||||||
from background_task import background
|
|
||||||
from channels.layers import get_channel_layer
|
|
||||||
from asgiref.sync import async_to_sync
|
|
||||||
from polls.models import Message
|
|
||||||
|
|
||||||
|
|
||||||
@background(schedule=0)
|
|
||||||
def process_task(task, user_id):
|
|
||||||
channel_layer = get_channel_layer()
|
|
||||||
groups = task.groups
|
|
||||||
for g in groups:
|
|
||||||
async_to_sync(channel_layer.group_send)(g.id, {
|
|
||||||
"type": 0,
|
|
||||||
"send_from": user_id,
|
|
||||||
"group_id": g.id,
|
|
||||||
"content": g.content
|
|
||||||
})
|
|
|
@ -62,7 +62,7 @@ class Task(models.Model):
|
||||||
|
|
||||||
def add_groups(self, groups):
|
def add_groups(self, groups):
|
||||||
if not len(groups):
|
if not len(groups):
|
||||||
groups = Group.objects.filter(status='1')
|
groups = Group.objects.filter(status='开启')
|
||||||
for g in groups:
|
for g in groups:
|
||||||
self.groups.add(g)
|
self.groups.add(g)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
from background_task import background
|
||||||
|
from channels.layers import get_channel_layer
|
||||||
|
from asgiref.sync import async_to_sync
|
||||||
|
from polls.models import Message
|
||||||
|
|
||||||
|
|
||||||
|
@background(schedule=1)
|
||||||
|
def process_task(task, groups, user_id):
|
||||||
|
print(groups)
|
||||||
|
for g in groups:
|
||||||
|
print(g)
|
||||||
|
# async_to_sync(channel_layer.group_send)(g['id'], {
|
||||||
|
# "type": 0,
|
||||||
|
# "send_from": user_id,
|
||||||
|
# "group_id": g['id'],
|
||||||
|
# "content": task['content']
|
||||||
|
# })
|
||||||
|
channel_layer = get_channel_layer()
|
||||||
|
async_to_sync(channel_layer.send)('test_channel', {'type': g['id']})
|
|
@ -1,12 +1,11 @@
|
||||||
{% extends 'polls/base.html' %}
|
{% extends 'polls/base.html' %}
|
||||||
{% load static %}
|
{% load static %}
|
||||||
{% block content%}
|
{% block content%}
|
||||||
<div class="row">
|
<div class="flex-container">
|
||||||
<div class="col-xs-12">
|
<div class="row">
|
||||||
<div id="chart1" style="width: 100%%;height:400px;margin-bottom:40px;"></div>
|
<div class="col-xs-12">
|
||||||
</div>
|
<div id="chart1" style="width: 100%%;height:400px;margin-bottom:40px;"></div>
|
||||||
<div class="col-xs-12">
|
</div>
|
||||||
<div id="chart2" style="width: 100%%;height:400px;margin-bottom:40px;"></div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock%}
|
{% endblock%}
|
||||||
|
@ -15,38 +14,41 @@
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
var myChart = echarts.init(document.getElementById('chart1'));
|
var myChart = echarts.init(document.getElementById('chart1'));
|
||||||
var option = {
|
var option = {
|
||||||
title: {
|
title: {
|
||||||
text: '新媒体数量'
|
text: '新媒体占比',
|
||||||
},
|
left: 'center'
|
||||||
tooltip: {},
|
},
|
||||||
legend: {
|
tooltip: {
|
||||||
data:['数量']
|
trigger: 'item',
|
||||||
},
|
formatter: '{a} <br/>{b} : {c} ({d}%)'
|
||||||
xAxis: {
|
},
|
||||||
data: ["公众号","微博","头条号","其他"]
|
legend: {
|
||||||
},
|
orient: 'vertical',
|
||||||
yAxis: {},
|
left: 'left',
|
||||||
series: [{
|
data: ['微博', '公众号', '头条号', '抖音', '其它']
|
||||||
name: '数量',
|
},
|
||||||
type: 'bar',
|
series: [
|
||||||
data: [5, 20, 36, 10]
|
{
|
||||||
}]
|
name: '总量',
|
||||||
};
|
type: 'pie',
|
||||||
|
radius: '55%',
|
||||||
|
center: ['50%', '60%'],
|
||||||
|
data: [
|
||||||
|
{value: {{wbc}}, name: '微博'},
|
||||||
|
{value: {{wxc}}, name: '公众号'},
|
||||||
|
{value: {{ttc}}, name: '头条号'},
|
||||||
|
{value: {{dyc}}, name: '抖音'},
|
||||||
|
{value: {{qtc}}, name: '其它'}
|
||||||
|
],
|
||||||
|
emphasis: {
|
||||||
|
itemStyle: {
|
||||||
|
shadowBlur: 10,
|
||||||
|
shadowOffsetX: 0,
|
||||||
|
shadowColor: 'rgba(0, 0, 0, 0.5)'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]};
|
||||||
myChart.setOption(option);
|
myChart.setOption(option);
|
||||||
var myChart2 = echarts.init(document.getElementById('chart2'));
|
|
||||||
var option = {
|
|
||||||
title: {
|
|
||||||
text: '新媒体文章量'
|
|
||||||
},
|
|
||||||
xAxis: {
|
|
||||||
data: ["公众号","微博","头条号","其他"]
|
|
||||||
},
|
|
||||||
yAxis: {},
|
|
||||||
series: [{
|
|
||||||
data: [820, 932, 901, 934, 1290, ],
|
|
||||||
type: 'line'
|
|
||||||
}]
|
|
||||||
};
|
|
||||||
myChart2.setOption(option);
|
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -1,24 +1,15 @@
|
||||||
{% extends 'polls/base.html' %}
|
{% extends 'polls/base.html' %}
|
||||||
{% block content%}
|
{% block content%}
|
||||||
<div class="col-xs-12">
|
<div class="col-xs-12">
|
||||||
<h4 class="title">如何理解伟大抗疫精神,听习近平总书记这样阐释</h4>
|
<h4 class="title">{{ news.title }}</h4>
|
||||||
<div class="source">
|
<div class="source">
|
||||||
来源:中瓣网
|
来源:{{news.source}}
|
||||||
<span class="pull-right date">时间:2020-09-20 14:25:53</span>
|
<span class="pull-right date">时间:{{ news.date|date:"Y-m-d" }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-12">
|
<div class="col-xs-12">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<p>
|
{{news.content|safe}}
|
||||||
同困难作斗争,是物质的角力,也是精神的对垒。在抗击新冠肺炎疫情的斗争中,是什么精神力量支撑着我们,创造了人类同疾病斗争史上的英勇壮举?
|
|
||||||
</p>
|
|
||||||
<img src="http://cms-bucket.ws.126.net/2020/0909/2dcc71f3p00qge4xk008zc000go00toc.png" style="width:100%;height:400px;">
|
|
||||||
<p>
|
|
||||||
生命至上、举国同心、舍生忘死、尊重科学、命运与共——今日,在全国抗击新冠肺炎疫情表彰大会上,习近平总书记生动论述伟大抗疫精神。
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
人无精神则不立,国无精神则不强。唯有精神上站得住、站得稳,一个民族才能在历史洪流中屹立不倒、挺立潮头。什么是伟大抗疫精神?中华民族能够经历无数灾厄仍不断发展壮大的原因是什么?
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock%}
|
{% endblock%}
|
||||||
|
|
|
@ -17,8 +17,10 @@ urlpatterns = [
|
||||||
path('medias/create/', views.create_media, name='polls_add_media'),
|
path('medias/create/', views.create_media, name='polls_add_media'),
|
||||||
path('medias/list/', views.medias, name='polls_medias'),
|
path('medias/list/', views.medias, name='polls_medias'),
|
||||||
path('news/list/', views.news_list, name='polls_news'),
|
path('news/list/', views.news_list, name='polls_news'),
|
||||||
path('news/detail/', views.news_detail, name='polls_news_detail'),
|
path('news/detail/<str:news_id>/', views.news_detail, name='polls_news_detail'),
|
||||||
path('monitor/statistics/', views.monitor_statistics, name='polls_monitor_statistics'),
|
path('monitor/statistics/', views.monitor_statistics, name='polls_monitor_statistics'),
|
||||||
path('tasks/list/', views.tasks, name='polls_tasks_list'),
|
path('tasks/list/', views.tasks, name='polls_tasks_list'),
|
||||||
path('tasks/create/', views.create_task, name='polls_tasks_create'),
|
path('tasks/create/', views.create_task, name='polls_tasks_create'),
|
||||||
|
path('groups/list/', views.groups, name='polls_groups_list'),
|
||||||
|
path('compartments/list/', views.compartments, name='polls_compartments_list'),
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,6 +7,7 @@ from channels.db import database_sync_to_async
|
||||||
from .exceptions import ClientError
|
from .exceptions import ClientError
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from polls.models import FileMessage, ImageMessage, NormalMessage, URLMessage
|
from polls.models import FileMessage, ImageMessage, NormalMessage, URLMessage
|
||||||
|
from itertools import chain
|
||||||
|
|
||||||
|
|
||||||
def sent_sms_code(phone, code):
|
def sent_sms_code(phone, code):
|
||||||
|
@ -107,13 +108,36 @@ def build_message(type, user_id, group_id, task_id, payload):
|
||||||
|
|
||||||
elif type == 2:
|
elif type == 2:
|
||||||
ImageMessage.objects.create(send_from__id=user_id, send_to__id=group_id,
|
ImageMessage.objects.create(send_from__id=user_id, send_to__id=group_id,
|
||||||
task__id=task_id, title=payload.title, image=payload.image)
|
task__id=task_id, title=payload.title, image=payload.image)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
NormalMessage.objects.create(send_from__id=user_id, send_to__id=group_id,
|
NormalMessage.objects.create(send_from__id=user_id, send_to__id=group_id,
|
||||||
category=0, task__id=task_id, content=payload.content)
|
category=0, task__id=task_id, content=payload.content)
|
||||||
|
|
||||||
|
|
||||||
|
def model_to_dict(instance, fields):
|
||||||
|
opts = instance._meta
|
||||||
|
data = {}
|
||||||
|
for f in chain(opts.concrete_fields, opts.private_fields, opts.many_to_many):
|
||||||
|
if not getattr(f, 'editable', False):
|
||||||
|
continue
|
||||||
|
if fields and f.name not in fields:
|
||||||
|
continue
|
||||||
|
if f.name == 'id':
|
||||||
|
data[f.name] = str(f.value_from_object(instance))
|
||||||
|
else:
|
||||||
|
data[f.name] = f.value_from_object(instance)
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def queryset_to_list(q, fields):
|
||||||
|
l = []
|
||||||
|
for row in q:
|
||||||
|
r = model_to_dict(row, fields)
|
||||||
|
l.append(r)
|
||||||
|
return l
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# sent_sms_code('13993199566')
|
# sent_sms_code('13993199566')
|
||||||
og_title, og_description, og_url, og_image = parse(
|
og_title, og_description, og_url, og_image = parse(
|
||||||
|
|
|
@ -3,4 +3,6 @@ from .notice import notices, read_notice
|
||||||
from .media import medias, create_media
|
from .media import medias, create_media
|
||||||
from .news import news_list, news_detail
|
from .news import news_list, news_detail
|
||||||
from .monitor import monitor_statistics
|
from .monitor import monitor_statistics
|
||||||
from .task import tasks, create_task
|
from .task import tasks, create_task
|
||||||
|
from .group import groups
|
||||||
|
from .compartment import compartments
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,22 @@
|
||||||
|
from django.shortcuts import render
|
||||||
|
from dashboard.models import Area_code_2020
|
||||||
|
from django.http import JsonResponse
|
||||||
|
|
||||||
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
|
from polls.decorators import polls_login_required
|
||||||
|
|
||||||
|
|
||||||
|
@csrf_exempt
|
||||||
|
@polls_login_required
|
||||||
|
def compartments(request):
|
||||||
|
parent_code = request.GET.get('pcode', '620000000000')
|
||||||
|
compartments = Area_code_2020.objects.filter(pcode=parent_code)
|
||||||
|
results = []
|
||||||
|
for o in compartments:
|
||||||
|
result = dict()
|
||||||
|
result['code'] = o.code
|
||||||
|
result['name'] = o.name
|
||||||
|
result['level'] = o.level
|
||||||
|
result['pcode'] = o.pcode
|
||||||
|
results.append(result)
|
||||||
|
return JsonResponse({'status': 'success', 'message': results}, safe=False)
|
|
@ -0,0 +1,24 @@
|
||||||
|
from django.shortcuts import render
|
||||||
|
from django.http import HttpResponse, JsonResponse
|
||||||
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
from polls.decorators import polls_login_required
|
||||||
|
from django.core.exceptions import ObjectDoesNotExist
|
||||||
|
from dashboard.models import Group
|
||||||
|
|
||||||
|
@csrf_exempt
|
||||||
|
@polls_login_required
|
||||||
|
def groups(request):
|
||||||
|
if request.method == 'POST':
|
||||||
|
return HttpResponse(status=405)
|
||||||
|
id = request.user.id
|
||||||
|
groups = Group.objects.filter(status='开启')
|
||||||
|
results = []
|
||||||
|
for o in groups:
|
||||||
|
result = dict()
|
||||||
|
result['id'] = str(o.id)
|
||||||
|
result['name'] = o.name
|
||||||
|
result['image'] = request.build_absolute_uri(o.image.url)
|
||||||
|
results.append(result)
|
||||||
|
return JsonResponse(results, safe=False)
|
|
@ -1,4 +1,11 @@
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
|
from dashboard.models import Douyin, Qita, Toutiao, Weibo, Weixin
|
||||||
|
|
||||||
|
|
||||||
def monitor_statistics(request):
|
def monitor_statistics(request):
|
||||||
return render(request, 'polls/monitor_statistics.html')
|
wbc = Weibo.objects.count()
|
||||||
|
wxc = Weixin.objects.count()
|
||||||
|
ttc = Toutiao.objects.count()
|
||||||
|
qtc = Qita.objects.count()
|
||||||
|
dyc = Douyin.objects.count()
|
||||||
|
return render(request, 'polls/monitor_statistics.html', {'wbc': wbc, 'wxc': wxc, 'ttc': ttc, 'dyc': dyc, 'qtc': qtc})
|
||||||
|
|
|
@ -2,8 +2,14 @@ from django.shortcuts import render
|
||||||
from dashboard.models import News
|
from dashboard.models import News
|
||||||
from django.http import JsonResponse
|
from django.http import JsonResponse
|
||||||
|
|
||||||
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
|
from polls.decorators import polls_login_required
|
||||||
|
|
||||||
|
|
||||||
|
@csrf_exempt
|
||||||
|
@polls_login_required
|
||||||
def news_list(request):
|
def news_list(request):
|
||||||
category = request.GET.get('category','1')
|
category = request.GET.get('category', '1')
|
||||||
news_list = News.objects.filter(type=category)
|
news_list = News.objects.filter(type=category)
|
||||||
results = []
|
results = []
|
||||||
for o in news_list:
|
for o in news_list:
|
||||||
|
@ -11,10 +17,13 @@ def news_list(request):
|
||||||
result['id'] = o.id
|
result['id'] = o.id
|
||||||
result['title'] = o.title
|
result['title'] = o.title
|
||||||
result['author'] = o.author
|
result['author'] = o.author
|
||||||
result['content'] = o.content
|
result['source'] = o.source
|
||||||
result['date'] = o.date
|
result['image'] = request.build_absolute_uri(o.image.url) if o.image else ''
|
||||||
|
result['date'] = o.date.strftime("%Y-%m-%d")
|
||||||
results.append(result)
|
results.append(result)
|
||||||
return JsonResponse(results, safe=False)
|
return JsonResponse({'status': 'success', 'message': results}, safe=False)
|
||||||
|
|
||||||
def news_detail(request):
|
|
||||||
return render(request, 'polls/news_detail.html')
|
def news_detail(request, news_id):
|
||||||
|
news = News.objects.get(pk=news_id)
|
||||||
|
return render(request, 'polls/news_detail.html', {'news': news})
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from django.http import HttpResponse, JsonResponse
|
from django.http import HttpResponse, JsonResponse
|
||||||
from django.views.decorators.csrf import csrf_exempt
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
from django.forms.models import model_to_dict
|
|
||||||
import datetime
|
import datetime
|
||||||
|
from channels.layers import get_channel_layer
|
||||||
|
from asgiref.sync import async_to_sync
|
||||||
|
|
||||||
from polls.decorators import polls_login_required
|
from polls.decorators import polls_login_required
|
||||||
from polls.models import Task, TaskAddition
|
from polls.models import Task, TaskAddition
|
||||||
from polls.job import process_task
|
from polls.tasks import process_task
|
||||||
from django.core.exceptions import ObjectDoesNotExist
|
from django.core.exceptions import ObjectDoesNotExist
|
||||||
|
from polls.utils import model_to_dict, queryset_to_list
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@csrf_exempt
|
@csrf_exempt
|
||||||
|
@ -46,14 +49,19 @@ def create_task(request):
|
||||||
url = request.POST.get('url')
|
url = request.POST.get('url')
|
||||||
file = request.FILES.get('file')
|
file = request.FILES.get('file')
|
||||||
picture = request.FILES.get('picture')
|
picture = request.FILES.get('picture')
|
||||||
if not url:
|
if url:
|
||||||
urlAddtion = TaskAddition.objects.create(
|
urlAddtion = TaskAddition.objects.create(
|
||||||
task=task, category=0, url=url)
|
task=task, category=0, url=url)
|
||||||
if not file:
|
if file:
|
||||||
fileAddtion = TaskAddition.objects.create(
|
fileAddtion = TaskAddition.objects.create(
|
||||||
task=task, category=1, file=file)
|
task=task, category=1, file=file)
|
||||||
if not picture:
|
if picture:
|
||||||
pictureAddtion = TaskAddition.objects.create(
|
pictureAddtion = TaskAddition.objects.create(
|
||||||
task=task, category=2, image=picture)
|
task=task, category=2, image=picture)
|
||||||
process_task(task, user)
|
t = model_to_dict(task, ["id", "content"])
|
||||||
|
gs = queryset_to_list(task.groups.all(), ["id"])
|
||||||
|
channel_layer = get_channel_layer()
|
||||||
|
# async_to_sync(channel_layer.send)('test_channel', {'type': 'hello'})
|
||||||
|
async_to_sync(channel_layer.group_send)("chat", {"type": "update_price", "content":"helo"})
|
||||||
|
|
||||||
return JsonResponse({'status': 'success'})
|
return JsonResponse({'status': 'success'})
|
||||||
|
|
Loading…
Reference in New Issue