Merge remote-tracking branch 'origin/master'

This commit is contained in:
Bob 2020-09-20 19:22:57 +08:00
commit 8f35e873a2
22 changed files with 195 additions and 100 deletions

View File

@ -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],
}, },
}, },
} }

View File

@ -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)

View File

@ -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
})) # }))

View File

@ -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
})

View File

@ -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)

19
polls/tasks.py Normal file
View File

@ -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']})

View File

@ -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 %}

View File

@ -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%}

View File

@ -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'),
] ]

View File

@ -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(

View File

@ -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.

View File

@ -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)

24
polls/views/group.py Normal file
View File

@ -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)

View File

@ -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})

View File

@ -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})

View File

@ -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'})