This commit is contained in:
Holger Trampe 2020-05-31 01:57:41 +02:00
parent ee77bb43c4
commit 984751c59b
17 changed files with 660 additions and 92 deletions

39
chat/forms.py Normal file
View File

@ -0,0 +1,39 @@
from django import forms
from .models import ChatRoom
from users.models import UserFullName
class ChatUpdateChatRoom(forms.ModelForm):
class Meta:
model = ChatRoom
labels = {
"roomname" : "Raumname",
"chatmembers" : "Mitglieder",
"chatmembers_admin" : "Verwalter",
}
fields = ['roomname', 'chatmembers', 'chatmembers_admin']
def __init__(self, *args, **kwargs):
print(kwargs)
super(ChatUpdateChatRoom, self).__init__(*args, **kwargs)
self.fields['chatmembers'] = forms.MultipleChoiceField(required=True, label="Mitglieder", choices=[(u.id, u) for u in UserFullName.objects.filter(profile__agency__pk=kwargs["instance"].creator.profile.agency.pk).exclude(pk=kwargs["instance"].creator.pk)], widget=forms.CheckboxSelectMultiple())
self.fields['chatmembers_admin'] = forms.MultipleChoiceField(required=False, label="Raumverwalter", choices=[(u.id, u) for u in UserFullName.objects.filter(profile__agency__pk=kwargs["instance"].creator.profile.agency.pk).exclude(pk=kwargs["instance"].creator.pk)], widget=forms.CheckboxSelectMultiple())
class ChatAddChatRoom(forms.ModelForm):
class Meta:
model = ChatRoom
labels = {
"roomname" : "Raumname",
"chatmembers" : "Mitglieder",
"chatmembers_admin" : "Verwalter",
}
fields = ['roomname', 'chatmembers', 'chatmembers_admin']
def __init__(self, *args, **kwargs):
super(ChatAddChatRoom, self).__init__(*args, **kwargs)
self.fields['chatmembers'] = forms.MultipleChoiceField(required=True, label="Mitglieder", choices=[(u.id, u) for u in UserFullName.objects.filter(profile__agency__pk=kwargs["instance"].profile.agency.pk).exclude(pk=kwargs["instance"].pk)], widget=forms.CheckboxSelectMultiple())
self.fields['chatmembers_admin'] = forms.MultipleChoiceField(required=False, label="Raumverwalter", choices=[(u.id, u) for u in UserFullName.objects.filter(profile__agency__pk=kwargs["instance"].profile.agency.pk).exclude(pk=kwargs["instance"].pk)], widget=forms.CheckboxSelectMultiple())

View File

@ -3,7 +3,7 @@ from django.contrib.auth.models import User
from users.models import Agency
from django.urls import reverse
from django.utils import timezone
from django_cryptography.fields import encrypt
'''
@ -13,7 +13,7 @@ MODEL ChatMessage
'''
class ChatMessage(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE)
content = models.CharField(max_length=5000, blank=False, default="")
content = encrypt(models.CharField(max_length=5000, blank=False, default=""))
sendtime = models.DateTimeField(default=timezone.now, blank=True)
room = models.ForeignKey("ChatRoom", on_delete=models.CASCADE)
'''
@ -24,7 +24,7 @@ Model ChatRoom
class ChatRoom(models.Model):
creator = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)
creator = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
'''
chatroomtype
@ -34,9 +34,11 @@ class ChatRoom(models.Model):
'''
chatroomtype = models.IntegerField(default=0)
roomname = models.CharField(max_length=200, blank=False, default="")
grouproomname = models.CharField(max_length=200, blank=False, default="")
# This field is for random-String Django Channels
roomname_channel = models.CharField(max_length=200, blank=False)
chatmembers = models.ManyToManyField(User, blank=True, related_name='users_in_chatroom')
chatmembers_admin = models.ManyToManyField(User, blank=True, related_name='adminusers_in_chatroom')
chatroom_createddate = models.DateTimeField(blank=True)
chatmember_single = models.ForeignKey(User, related_name='singleuserchat', on_delete=models.CASCADE, null=True, blank=True)
'''
@ -53,6 +55,8 @@ class ChatRoom(models.Model):
def __str__(self):
return f'{self.roomname}'
def get_absolute_url(self):
return reverse('chat-update', kwargs={'pk':self.pk})

View File

@ -32,11 +32,11 @@
{% endif %}
{% if message.author == request.user %}
<div style="" class="chatmessageele_me col-7 mb-3 ">
<div style="" class="chatmessageele_me col-7 mb-3 " id="usermessage_{{message.pk}}">
<div class='icon-container ml-2 mt-1 ' style="float: right;">
<img class="img-profile roundimg" src="{{ message.author.profile.get_photo_url }}">
</div>
<h6 class="mt-3"><small>{{message.sendtime|date:"H:i"}}</small></h6>
<h6 class="mt-3"><button class="btn btn-small" onclick="javascript:deleteOwnMessage({{message.pk}})"><small><i class="fas fa-trash"></i></small></button>&nbsp;<small>{{message.sendtime|date:"H:i"}}</small></h6>
<div style="text-align: left;" class="mt-1">
<span style="float: right !important; font-size: 1.0em;">
{{message.content}}
@ -44,7 +44,7 @@
</div>
</div>
{% else %}
<div style="" class="chatmessageele_other col-7 mb-3">
<div style="" class="chatmessageele_other col-7 mb-3" id="usermessage_{{message.pk}}">
<div class='icon-container mr-2 mt-1 ' style="float: left;">
<img class="img-profile roundimg" src="{{ message.author.profile.get_photo_url }}">
</div>
@ -103,6 +103,7 @@ $(document).ready(function(){
datainfo = e["data"].split("__");
if(datainfo[0] == "starttyping")
{
typingname = (datainfo[1].split("_"))[1];
@ -136,7 +137,11 @@ $(document).ready(function(){
}
});
}
};
console.log(datainfo)
if(datainfo[0] == "delete_message"){
$("#usermessage_" + datainfo[1]).remove();
}
}
chatwebsocket.onclose = function(e) {
console.error('Chat socket closed unexpectedly');
@ -179,8 +184,22 @@ $(document).ready(function(){
});
}
}
function deleteOwnMessage(id){
$.ajax(
{
type: "GET",
url: "{% url 'chat:chat-ajax' %}",
data : {
action : "delmessage",
messageid : id
},
success: function( data )
{
chatwebsocket.send("delmessage__" + id + "__privatechat_{{roomdata.creator.pk}}_{{roomdata.chatmember_single.pk}}");
}
});
}
$(document).on('keypress',function(e) {
if(e.which == 13) {
if($("#message").val().length > 0 && sending){

View File

@ -69,11 +69,11 @@
{% endif %}
{% if message.author == request.user %}
<div style="" class="chatmessageele_me col-7 mb-3 ">
<div style="" class="chatmessageele_me col-7 mb-3 " id="usermessage_{{message.pk}}"">
<div class='icon-container ml-2 mt-1 ' style="float: right;">
<img class="img-profile roundimg-chat" src="{{ message.author.profile.get_photo_url }}">
</div>
<h6 class="mt-3"><small>{{message.sendtime|date:"H:i"}}</small></h6>
<h6 class="mt-3"><button class="btn btn-small" onclick="javascript:deleteOwnMessage({{message.pk}})"><small><i class="fas fa-trash"></i></small></button>&nbsp;<small>{{message.sendtime|date:"H:i"}}</small></h6>
<div style="text-align: left;" class="mt-1">
<span style="float: right !important; font-size: 1.0em;">
{{message.content}}
@ -81,7 +81,7 @@
</div>
</div>
{% else %}
<div style="" class="chatmessageele_other col-7 mb-3">
<div style="" class="chatmessageele_other col-7 mb-3" id="usermessage_{{message.pk}}">
<div class='icon-container mr-2 mt-1 ' style="float: left;">
<img class="img-profile roundimg-chat" src="{{ message.author.profile.get_photo_url }}">
</div>
@ -180,6 +180,10 @@ $(document).ready(function(){
}
});
}
if(datainfo[0] == "delete_message"){
$("#usermessage_" + datainfo[1]).remove();
}
};
chatwebsocket.onclose = function(e) {
@ -224,6 +228,22 @@ $(document).ready(function(){
}
}
function deleteOwnMessage(id){
$.ajax(
{
type: "GET",
url: "{% url 'chat:chat-ajax' %}",
data : {
action : "delmessage",
messageid : id
},
success: function( data )
{
chatwebsocket.send("delmessage__" + id + "__privatechat_{{roomdata.creator.pk}}_{{roomdata.chatmember_single.pk}}");
}
});
}
$(document).on('keypress',function(e) {
if(e.which == 13) {

View File

@ -0,0 +1,253 @@
{% load counter_tag %}
<h4 id="chattitle" style="margin-top: -3px">{{roomdata.roomname}}
{% if user in roomdata.chatmembers_admin.all or user == roomdata.creator %}
<button class="btn btn-secondary btn-sm ml-2 " style="float: right;" onclick="javascript:$('#confirm-delete_{{roomdata.pk}}').modal('toggle')"><small><i class="fas fa-trash"></i></small></button>
<button class="btn btn-secondary btn-sm " onclick="window.location.href='{% url 'chat:chat-update' roomdata.pk %}'" style="float: right;"><small><i class="fas fa-pen"></i></small></button>
{% endif %}
</h4>
<hr>
<div class="card" >
<div class="card-body scroll" id="chatcontentcomplete">
<div id="roomstart" style="min-width: 100%; text-align: center;">
<small>Unterhaltung gestartet am {{roomdata.chatroom_createddate}}</small>
</div>
<hr>
<div id="chatmessages">
{% for message in roomdata.messages.all %}
{% if forloop.counter0 == 0 %}
{% setMessageDayInfo message %}
{% else %}
{% getMessageDayInfo message as newday %}
{% if newday == True %}
<div style="" class="chatmessageele_breaker col-12 mb-3">
<div class="col-12 mb-3" style="text-align: center;">
<hr>
<small>{{message.sendtime|date:"d.m.Y"}}</small>
</div>
</div>
{% endif %}
{% endif %}
{% if message.author == request.user %}
<div style="" class="chatmessageele_me col-7 mb-3 " id="usermessage_{{message.pk}}">
<div class='icon-container ml-2 mt-1 ' style="float: right;">
<img class="img-profile roundimg" src="{{ message.author.profile.get_photo_url }}">
</div>
<h6 class="mt-3"><button class="btn btn-small" onclick="javascript:deleteOwnMessage({{message.pk}})"><small><i class="fas fa-trash"></i></small></button>&nbsp;<small>{{message.sendtime|date:"H:i"}}</small>
</h6>
<div style="text-align: left;" class="mt-1">
<span style="float: right !important; font-size: 1.0em;">
{{message.content}}
</span>
</div>
</div>
{% else %}
<div style="" class="chatmessageele_other col-7 mb-3" id="usermessage_{{message.pk}}">
<div class='icon-container mr-2 mt-1 ' style="float: left;">
<img class="img-profile roundimg" src="{{ message.author.profile.get_photo_url }}">
</div>
<h6 class="mt-3"><small>{{message.author.first_name}} {{message.author.last_name}},&nbsp;{{message.sendtime|date:"H:i"}}</small></h6>
<div style="text-align: left;" class="mt-1">
<span style="float: left !important; font-size: 1.0em;">
{{message.content}}
</span>
</div>
</div>
{% endif %}
{% endfor %}
</div><!-- END CHAT MESSAGES -->
<span id="scrolltarget">&nbsp;</span>
</div><!-- END CARD BODY-->
<div id="is_typing" class="ml-2">
<div class="spinner-grow spinner-border-sm" id="typingspinner" role="status" style="display: none;">
<span class="sr-only">Jemand tippt...</span>
</div>
<small id="is_typing_name" class="">&nbsp;
</small>
</div>
<div class="card-footer bg-transparent border-success">
<div class="input-group">
<input type="text" class="form-control" placeholder="Neue Nachricht" id="message" aria-describedby="">
<div class="input-group-append">
<button class="btn btn-primary" id="sendNewMessgeButton" onclick="javascript:sendNewMessage()" type="button"><i class="fas fa-location-arrow"></i></button>
</div>
</div>
</div>
</div>
<script type="text/javascript">
$(document).ready(function(){
$('#chatcontentcomplete').scrollTop( $('#chatcontentcomplete').height()*200 )
});
userownid = "{{user.pk}}";
ws_string = 'wss://'
if (location.protocol !== 'https:') {
ws_string = 'ws://'
}
if(typeof chatwebsocket != "undefined"){
chatwebsocket = new WebSocket(ws_string+window.location.host+"/ws/groupchat/{{roomdata.pk}}/")
}
else{
chatwebsocket = new WebSocket(ws_string+window.location.host+"/ws/groupchat/{{roomdata.pk}}/")
}
chatwebsocket.onmessage = function(e) {
datainfo = e["data"].split("__");
if(datainfo[0] == "starttyping")
{
typingname = (datainfo[1].split("_"))[1];
typingid = (datainfo[1].split("_"))[0];
if(typingid != userownid){
$("#is_typing_name").html("" + typingname);
$("#typingspinner").show();
}
}
if(datainfo[0] == "stoptyping")
{
$("#is_typing_name").html("&nbsp;");
$("#typingspinner").hide();
}
if(datainfo[0] == "reloadmessages")
{
$.ajax(
{
type: "GET",
url: "{% url 'chat:chat-ajax' %}",
data : {
action : "loadnewestmessage",
room : {{roomdata.pk}}
},
success: function( data )
{
$("#chatmessages").append(data);
$('#chatcontentcomplete').scrollTop( $('#chatcontentcomplete').height()*200 );
}
});
}
if(datainfo[0] == "delete_message"){
$("#usermessage_" + datainfo[1]).remove();
}
}
chatwebsocket.onclose = function(e) {
console.error('Chat socket closed unexpectedly');
};
$("#message").keyup(function(){
if($("#message").val().length > 0){
chatwebsocket.send("starttyping__{{user.pk}}__groupchat_{{roomdata.pk}}");
}
else{
chatwebsocket.send("stoptyping__{{user.pk}}__groupchat_{{roomdata.pk}}");
}
})
sending = true;
function sendNewMessage()
{
if($("#message").val().length > 0 && sending)
{
sending = false;
$.ajax(
{
type: "GET",
url: "{% url 'chat:chat-ajax' %}",
data : {
action : "addnewmessage",
new_chat_userid : userownid,
message : $("#message").val(),
room : {{roomdata.pk}}
},
success: function( data )
{
$("#message").val("");
chatwebsocket.send("load__{{user.pk}}__groupchat_{{roomdata.pk}}");
chatwebsocket.send("stoptyping__{{user.pk}}__groupchat_{{roomdata.pk}}");
sending = true;
}
});
}
}
$(document).on('keypress',function(e) {
if(e.which == 13) {
if($("#message").val().length > 0 && sending){
sendNewMessage();
}
}
});
function deleteOwnMessage(id){
$.ajax(
{
type: "GET",
url: "{% url 'chat:chat-ajax' %}",
data : {
action : "delmessage",
messageid : id
},
success: function( data )
{
chatwebsocket.send("delmessage__" + id + "__groupchat_{{roomdata.pk}}");
}
});
}
</script>
{% if user in roomdata.chatmembers_admin.all or user == roomdata.creator %}
<div class="modal fade" id="confirm-delete_{{roomdata.pk}}" tabindex="-1" role="dialog" aria-labelledby="" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Chatraum löschen</h5>
</div>
<div class="modal-body">
Möchten Sie wirklich den Chatraum {{roomdata.roomname}} löschen? Alle Nachrichten werden entfernt!
</div>
<div class="modal-footer">
<button class="btn btn-primary" id="dodel_{{roomdata.pk}}" >Löschen</button>
<button type="button" class="btn" data-dismiss="modal">Abbrechen</button>
</div>
</div>
</div>
</div>
<script type="text/javascript">
$("#dodel_{{roomdata.pk}}").click(function(){
$.ajax(
{
type: "GET",
url: "{% url 'chat:chat-ajax' %}",
data:{
action : "remove_chatroom",
groupchatid: {{roomdata.pk}},
},
success: function( data )
{
location.href = location.href;
}
});
});
</script>
{% endif %}

View File

@ -1,4 +1,4 @@
<div style="" class="chatmessageele_other col-7 mb-3 ">
<div style="" class="chatmessageele_other col-7 mb-3 " id="usermessage_{{newmessage.pk}}">
<div class='icon-container mr-2 mt-1 ' style="float: left;">
<img class="img-profile roundimg" src="{{ newmessage.author.profile.get_photo_url }}">
</div>

View File

@ -1,8 +1,8 @@
<div style="" class="chatmessageele_me col-7 mb-3 ">
<div style="" class="chatmessageele_me col-7 mb-3 " id="usermessage_{{newmessage.pk}}">
<div class='icon-container ml-2 mt-1 ' style="float: right;">
<img class="img-profile roundimg" src="{{ newmessage.author.profile.get_photo_url }}">
</div>
<h6 class="mt-3"><small>{{newmessage.sendtime|date:"H:i"}}</small></h6>
<h6 class="mt-3"><button class="btn btn-small" onclick="javascript:deleteOwnMessage({{newmessage.pk}})"><small><i class="fas fa-trash"></i></small></button>&nbsp;<small>{{newmessage.sendtime|date:"H:i"}}</small></h6>
<div style="text-align: left;" class="mt-1">
<span style="float: right !important; font-size: 1.0em;">
{{newmessage.content}}

View File

@ -53,23 +53,22 @@
min-height: 600px;
overflow-y: auto;
}
</style>
<div class="content-section col-12">
<h3>Chat&nbsp;<small><i data-toggle="tooltip" data-placement="top" title="Verwalten Sie hier Ihre Chatverläufe und starten Sie neue Unterhaltungen mit Mitarbeitern und anderen Agenturen." class="far fa-question-circle"></i></small>
</h3>
<small><b>ACHTUNG! Der Chat befindet sich im Beta-Stadium! Bitte vermeiden Sie es daher, persönliche oder intime Informationen zu verschicken, bis alle Funktionen ausreichend erprobt sind. Vielen Dank!</b></small>
<hr>
</div>
<div class="row col">
<div class="col-3">
<h4>Mitarbeiter und Räume</h4>
<h5>Mitarbeiter
</h5>
<hr>
{% for user in usersofagency %}
<div class="card mb-2 hoverchatcard" id="userchat_{{user.pk}}">
<div class="card-body">
<div class="card-body" style="margin: -15px !important;" >
<div style="float: left;" class="col-12 ">
<div class='icon-container mr-2'>
<img class="img-profile roundimg" src="{{ user.profile.get_photo_url }}">
@ -91,6 +90,29 @@
</div>
</div>
{% endfor %}
<hr>
<h5>Chaträume
<button class="btn btn-primary btn-sm" style="float: right; margin-top: -6px !important;" data-toggle="tooltip" data-placement="top" title="Erstellen Sie einen Gruppenchat." onclick="window.location.href='{% url 'chat:chat-addgroup' %}'"><i class="fas fa-plus"></i></button>
</h5>
<hr>
{% for chatroom in chatrooms %}
{% if user in chatroom.chatmembers.all or user in chatroom.chatmembers_admin.all or user == chatroom.creator and chatroom.chatroomtype == 1 %}
<div class="card mb-2 hoverchatcard" id="groupchat_{{chatroom.pk}}">
<div class="card-body" style="margin: -15px !important;">
<div style="float: left;" class="col-12 ">
<h5 class="mt-3">{{chatroom.roomname}}
</h5>
<small style="font-size: 10pt;">{% for member in chatroom.chatmembers.all %}
{{member.first_name}} {{member.last_name}}{% if forloop.counter < chatroom.chatmembers.all|length %}, {% endif %}
{% endfor %}
</small>
</div>
</div>
</div>
{% endif %}
{% endfor %}
</div>
<div class="col-9" style="" id="mainchatcontent">
@ -112,24 +134,48 @@
)
$(".hoverchatcard").click(function(){
clickedroomtype = $(this)[0]["id"].split("_")[0];
clickedroomid = $(this)[0]["id"].split("_")[1];
$.ajax(
{
type: "GET",
url: "{% url 'chat:chat-ajax' %}",
data : {
action : "startnewchat_user_user",
new_chat_userid : $(this)[0]["id"].split("_")[1],
is_basechat : 0
},
success: function( data )
{
if(creator_id != false && chatmember_id != false){
chatwebsocket.close();
}
$("#mainchatcontent").html(data);
}
});
if (clickedroomtype == "userchat"){
$.ajax(
{
type: "GET",
url: "{% url 'chat:chat-ajax' %}",
data : {
action : "startnewchat_user_user",
new_chat_userid : $(this)[0]["id"].split("_")[1],
is_basechat : 0
},
success: function( data )
{
if(creator_id != false && chatmember_id != false){
chatwebsocket.close();
}
$("#mainchatcontent").html(data);
}
});
}
//Open Groupchat
else{
$.ajax(
{
type: "GET",
url: "{% url 'chat:chat-ajax' %}",
data : {
action : "startnewchat_groupchat",
groupchatid : clickedroomid,
is_basechat : 0
},
success: function( data )
{
if(creator_id != false && chatmember_id != false){
chatwebsocket.close();
}
$("#mainchatcontent").html(data);
}
});
}
});
function updatePresenceLive() {

View File

@ -0,0 +1,48 @@
{% extends "users/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
{% if request.user.profile.agency.module_chat %}
<div class="content-section col-6">
<h3>Gruppenchat</h3>
<hr>
<form method="POST">
{% csrf_token %}
{{form|crispy}}
<small>Sie selbst sind Raumverwalter und können auch später weitere Mitglieder hinzufügen.</small>
<hr>
<a class="btn" href="{% url 'chat:chat-management' %} ">Abbrechen</a>
<button type="submit" class="btn btn-primary" style="float: right">Chatraum speichern</button>
</form>
</div>
<script type="text/javascript">
preventUpdatePresLive = true;
members = [{% for mem in object.chatmembers.all %} "{{mem.pk}}",{% endfor %}];
admins = [{% for mem in object.chatmembers_admin.all %} "{{mem.pk}}",{% endfor %}];
boxes = $(":checkbox");
for(i = 0; i < boxes.length; i++){
if(members.indexOf(boxes[i]["value"]) !== -1){
if(boxes[i]["id"].indexOf("chatmembers_admin") === -1 && boxes[i]["id"].indexOf("chatmembers") !== -1){
$("#" + boxes[i]["id"]).prop("checked", true)
}
}
if(admins.indexOf(boxes[i]["value"]) !== -1){
if(boxes[i]["id"].indexOf("chatmembers_admin") !== -1){
$("#" + boxes[i]["id"]).prop("checked", true)
}
}
}
</script>
{% else %}
<h3>Das Module Chat wurde in ihrer Agentur deaktiviert.</h3>
{% endif %}
{% endblock content %}

View File

@ -4,8 +4,11 @@ from . import views
app_name = 'chat'
urlpatterns = [
path('managemenet/', views.chatmanagement, name='chat-management'),
path('addgc/', views.ChatAddGroupChat, name='chat-addgroup'),
path('addgc/update/<int:pk>', views.ChatUpdateGroupChat.as_view(), name='chat-update'),
path('ajaxchat', views.chatajaxmain, name="chat-ajax"),
path('ajaxchat/getloggedusers', views.getloggedusers, name="chtaajax-getloggedusers"),
path('ajaxchat/getloggedusersdata', views.getloggedusersdata, name="chtaajax-getloggedusers-data")
]

View File

@ -1,4 +1,4 @@
from django.shortcuts import render
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from channels_presence.models import Presence
from django.http import HttpResponseRedirect,HttpResponse, JsonResponse
@ -8,6 +8,11 @@ from channels_presence.models import Presence
import channels.layers
from django.utils import timezone
from .models import ChatRoom, ChatMessage
from .forms import ChatAddChatRoom, ChatUpdateChatRoom
from django.contrib import messages
from django.views.generic import UpdateView
from django.urls import reverse_lazy
from django.contrib.auth.mixins import LoginRequiredMixin
# Create your views here.
@login_required
@ -18,13 +23,51 @@ def chatmanagement(request):
context = {
'active_link' : 'chat',
"usersofagency" : User.objects.filter(profile__agency=request.user.profile.agency).exclude(pk=request.user.pk).order_by("last_name"),
"onlineusers" : users_online.get_users()
"onlineusers" : users_online.get_users(),
"chatrooms" : ChatRoom.objects.all()
}
return render(request, 'chat/chatmanagement.html', context)
@login_required
def ChatAddGroupChat(request):
if request.method == "POST":
form = ChatAddChatRoom(request.POST, instance=request.user)
if(form.is_valid()):
newchatroom = ChatRoom(creator=request.user, chatroomtype=1, roomname=form.cleaned_data["roomname"], roomname_channel="groupchat", chatroom_createddate=timezone.now(), viewstatus=0)
newchatroom.save()
newchatroom.chatmembers.set(form.cleaned_data["chatmembers"])
newchatroom.chatmembers_admin.set(form.cleaned_data["chatmembers_admin"])
newchatroom.save()
messages.success(request, f'Raum angelegt!')
else:
messages.success(request, f'Raum konnte nicht angelegt werden!')
return redirect('chat:chat-management')
else:
context = {
'active_link' : 'chat',
"form" : ChatAddChatRoom(instance=request.user)
}
return render(request, 'chat/chatmanagement_addgc.html', context)
class ChatUpdateGroupChat(LoginRequiredMixin, UpdateView):
model = ChatRoom
template_name = 'chat/chatmanagement_addgc.html'
success_url = reverse_lazy('chat:chat-management')
form_class = ChatUpdateChatRoom
def form_valid(self, form):
# Send message to the site
messages.success(self.request, f'Chatraum aktualisiert!')
return super().form_valid(form)
def get_context_data(self, **kwargs):
context = super(ChatUpdateGroupChat, self).get_context_data(**kwargs)
context['active_link'] = 'chat'
print(context)
return context
@login_required
def getloggedusers(request):
@ -81,7 +124,7 @@ def chatajaxmain(request):
singleuser = User.objects.get(pk=singleuserid)
# NO PRIVATE CHAT THERE, CREATE ONE!
if(len(getroom) == 0):
newchatroom = ChatRoom(creator=request.user, chatroomtype=0, roomname="Gespräch mit " + singleuser.first_name + " " + singleuser.last_name, roomname_channel="privatechat_" + str(request.user.pk) + "_" + singleuserid, chatmember_single=singleuser, chatroom_createddate=timezone.now(), viewstatus=0)
newchatroom = ChatRoom(creator=request.user, chatroomtype=0, roomname=singleuser.first_name + " " + singleuser.last_name, roomname_channel="privatechat_" + str(request.user.pk) + "_" + singleuserid, chatmember_single=singleuser, chatroom_createddate=timezone.now(), viewstatus=0)
newchatroom.save()
context = {
"roomdata" : newchatroom
@ -94,9 +137,39 @@ def chatajaxmain(request):
return render(request, "chat/chat_content_basechat.html", context)
else:
return render(request, "chat/chat_content.html", context)
# NACHRICHT LÖSCHEN
elif request.GET["action"] == "delmessage":
message_to_del = ChatMessage.objects.get(pk=request.GET["messageid"])
if(message_to_del.author == request.user):
message_to_del.delete()
return JsonResponse({"status" : "OK"})
else:
return JsonResponse({"status" : "FORBIDDEN"})
# GRUPPENCHAT LÖSCHEN
elif request.GET["action"] == "remove_chatroom":
chatroom = ChatRoom.objects.get(pk=request.GET["groupchatid"])
if(request.user == chatroom.creator or request.user in chatroom.chatmembers_admin.all()):
chatroom.delete()
messages.success(request, f'Raum gelöscht!')
return JsonResponse({"status" : "RELOAD"})
else:
messages.success(request, f'Das dürfen Sie nicht!')
return JsonResponse({"status" : "RELOAD"})
# GRUPPENCHAT ÖFFNEN
elif request.GET["action"] == "startnewchat_groupchat":
chatroom = ChatRoom.objects.get(pk=request.GET["groupchatid"])
if(request.user == chatroom.creator or request.user in chatroom.chatmembers.all() or request.user in chatroom.chatmembers_admin.all()):
context = {
"roomdata" : chatroom
}
return render(request, "chat/chat_content_groupchat.html", context)
else:
JsonResponse({"status" : "Error on CHATAJAXMAIN"})
elif request.GET["action"] == "addnewmessage":
room = ChatRoom.objects.get(pk=request.GET["room"])
if(request.user == room.creator or request.user == room.chatmember_single):
if(request.user == room.creator or request.user == room.chatmember_single or request.user in room.chatmembers.all() or request.user in room.chatmembers_admin.all()):
newmessage = ChatMessage(room=room, author=request.user, content=request.GET["message"])
newmessage.save()
@ -118,12 +191,3 @@ def chatajaxmain(request):
return JsonResponse({"status" : "Error on CHATAJAXMAIN"})
'''
author = models.ForeignKey(User, on_delete=models.CASCADE)
content = models.CharField(max_length=5000, blank=False, default="")
sendtime = models.DateField(default=timezone.now, blank=True)
room = models.ForeignKey("ChatRoom", on_delete=models.CASCADE)
'''

View File

@ -7,6 +7,7 @@ from message.models import Message
from cloud.models import DataFile
from organizer.models import AGContacts
from timemanagement.models import Workday, Breaks, AbsenceReason, FreeDays, Absence
from chat.models import ChatRoom
admin.site.register(StandardComments)
admin.site.register(StandardCommentRate)
@ -28,3 +29,4 @@ admin.site.register(AbsenceReason)
admin.site.register(Absence)
admin.site.register(FreeDays)
admin.site.register(UserYearAbsenceInfo)
admin.site.register(ChatRoom)

View File

@ -8,7 +8,6 @@ import channels
from django.contrib.auth.models import User
from rest_framework.authtoken.models import Token
class UsersConsumer(WebsocketConsumer):
appconnect = False
@ -103,11 +102,7 @@ class UsersChat(WebsocketConsumer):
loggeduser = self.scope["user"]
roomname = "privatechat_" + str(self.scope["url_route"]["kwargs"]["creator"]) + "_" + str(self.scope["url_route"]["kwargs"]["single"])
# TODO: Hier das doppelte Problem lösen mit den Channels...Datenbank dazuziehen!!!
print(roomname)
print(loggeduser.pk)
channel_layer = channels.layers.get_channel_layer()
print(channel_layer)
Room.objects.add(roomname, self.channel_name, loggeduser)
def disconnect(self, close_code):
@ -129,7 +124,9 @@ class UsersChat(WebsocketConsumer):
elif datainfo[0] == 'load':
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)(datainfo[2], {'type' : 'reloadmessages'})
elif datainfo[0] == 'delmessage':
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)(datainfo[2], {'type' : 'delmessage', 'messageid' : datainfo[1] })
def start_typing(self, event):
useristyping = User.objects.get(pk=event["typingname"])
@ -152,3 +149,75 @@ class UsersChat(WebsocketConsumer):
# SOMETHING IN PRESENCE CHANGED
def update_presence_live(self, event):
self.send("presence_update")
def delmessage(self, event):
self.send("delete_message__" + event["messageid"])
class GroupChat(WebsocketConsumer):
def connect(self):
super().connect()
pathcheck = self.scope["path"].split("/")
loggeduser = ""
# CHECK IF SOCKET COMES FROM APP OR FROM WEB
#APP
if(len(pathcheck) == 7 and len(pathcheck[5]) > 0):
loggeduser = User.objects.get(pk=Token.objects.get(key=pathcheck[5]).user_id)
self.appconnect = True
else:
loggeduser = self.scope["user"]
roomname = "groupchat_" + str(self.scope["url_route"]["kwargs"]["chatid"])
channel_layer = channels.layers.get_channel_layer()
Room.objects.add(roomname, self.channel_name, loggeduser)
def disconnect(self, close_code):
Presence.objects.touch(self.channel_name)
Room.objects.remove("", self.channel_name)
# WEBSOCKET-DATA-CONTENT
def receive(self, text_data=None, bytes_data=None):
datainfo = text_data.split("__")
typinguserid = datainfo[1]
print(datainfo[2])
if datainfo[0] == 'starttyping':
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)(datainfo[2], {'type' : 'start_typing', 'typingname' : typinguserid})
elif datainfo[0] == 'stoptyping':
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)(datainfo[2], {'type' : 'stop_typing'})
elif datainfo[0] == 'load':
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)(datainfo[2], {'type' : 'reloadmessages'})
elif datainfo[0] == 'delmessage':
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)(datainfo[2], {'type' : 'delmessage', 'messageid' : datainfo[1] })
def start_typing(self, event):
useristyping = User.objects.get(pk=event["typingname"])
self.send("starttyping__" + str(useristyping.pk) + "_" + useristyping.first_name + " " + useristyping.last_name + " tippt...")
def stop_typing(self, event):
self.send("stoptyping")
def reloadmessages(self, event):
self.send("reloadmessages")
# UPDATET STANDARD
def update_standard(self, event):
self.send("standard_update")
# NEW AGENCY NEWS
def agency_newnews(self, event):
self.send("Neue Agenturnews!")
# SOMETHING IN PRESENCE CHANGED
def update_presence_live(self, event):
self.send("presence_update")
def delmessage(self, event):
self.send("delete_message__" + event["messageid"])

View File

@ -4,6 +4,7 @@ from . import mainwebsocket
websocket_urlpatterns = [
re_path(r'ws/chat/(?P<creator>\w+)/(?P<single>\w+)/$', mainwebsocket.UsersChat, name="ws-chat"),
re_path(r'ws/groupchat/(?P<chatid>\w+)/$', mainwebsocket.GroupChat, name="ws-groupchat"),
re_path(r'ws/appchat/(?P<creator>\w+)/(?P<single>\w+)/(?P<token>\w+)/$', mainwebsocket.UsersChat, name="ws-appchat"),
re_path(r'ws/', mainwebsocket.UsersConsumer, name="ws-default"),
]

View File

@ -154,6 +154,7 @@
{% endif %}
{% if request.user.profile.agency.module_chat %}
<script type="text/javascript">preventUpdatePresLive = false;</script>
{% if active_link == 'chat' %}
<li class="nav-item active">
{% else%}
@ -436,7 +437,7 @@
<button id="chatButton" class="btn btn-primary" style="position: fixed; right: 36px; bottom: 30px;"><i class="far fa-comments"></i></button>
<!-- CHATAREA -->
<div id="dynamicchatwindow" class="col-4" style="position: absolute; bottom: 30px; right: 23px; display: none;z-index: 999;">
<div id="dynamicchatwindow" class="col-4" style="position: fixed; bottom: 30px; right: 23px; display: none;z-index: 999;">
<div class="card">
<div class="card-body">
@ -444,7 +445,9 @@
</div>
</div>
</div>
<script type="text/javascript">
</script>
<!-- CHATAREA END -->
{% endif %}
</div>
@ -739,7 +742,9 @@ $(document).ready(function(){
else{
{% if active_link == "chat" %}
updatePresenceLive();
if(preventUpdatePresLive == false){
updatePresenceLive();
}
{% endif %}
}
};

View File

@ -36,7 +36,8 @@ urlpatterns = [
path('setuserparent/', views.setuserparent, name="users-setuserparent"),
path('sendpassmail/', views.sendpassmail, name="users-sendpassmail"),
path('changeonlinestat/', views.changeonlinestat, name="users-updateonlinestat"),
path('dacron/<slug:code>', views.cronactions, name="cronmain")
path('dacron/<slug:code>', views.cronactions, name="cronmain"),
path('dacrondaily/<slug:code>', views.cronactionsdaily, name="cronmaindaily")
]

View File

@ -41,6 +41,7 @@ from channels_presence.models import Room
from channels_presence.models import Presence
import channels.layers
from datetime import date
from timemanagement.models import Workday
def randomString(stringLength=10):
"""Generate a random string of fixed length """
@ -826,6 +827,7 @@ def handler500(request):
CRONJOB FUNCTION
'''
# CRONJOBS ALLE 5 MINUTEN
def cronactions(request, code):
data = {}
if(code == settings.CRONAPIKEY):
@ -856,15 +858,21 @@ def cronactions(request, code):
newnotification = UserNotification(touser=user, notificationtext="Neue Agenturnews: " + news.name, notificationtype="agencynews", elementid=news.pk)
newnotification.save()
# TODO: CronJob für REST-Urlaub implementieren
# CRONJOBS UM 00:01!
def cronactionsdaily(request, code):
data = {}
if(code == settings.CRONAPIKEY):
allusers = User.objects.all()
'''
Pro User gibt es das Feld loose_holiday in der UserTime-Info. Ist dieser Tag vorbei, muss die Differenz der days_inuse des VORJHARES in den Rest das AKTUELLEN JAHRES gespeichert werden!
'''
today = date.today()
for user in allusers:
# REST URLAUB BERECHNUNG
usertimedata = UserTime.objects.get(user=user)
day_tocheck = usertimedata.loose_holidedate.split(".")[0]
@ -887,31 +895,17 @@ def cronactions(request, code):
next_year.restdays = this_year.days - this_year.days_inuse
next_year.save()
data.update({"status" : "ok"})
elif(code == settings.MAILINFOKEY):
pass
'''
# GET ALL USERS
users = User.objects.all().exclude(username="root")
# ARBEITSTAGE BEENDEN
# Benutzer hat Zeiterfassung aktiv
if(user.usertime.usetime):
workdays = Workday.objects.filter(user=user, end=None)
for wd in workdays:
wd.end = datetime(wd.start.year, wd.start.month, wd.start.day, 23, 59)
wd.save()
data.update({"status" : "ok"})
for u in users:
u.username = u.email
try:
u.save()
notificationtext = "ab sofort können Sie sich nur noch mit Ihrer E-Mailadresse anmelden. Diese lautet " + u.email + "!"
msg_html = render_to_string('users/password_to_username_mail.html', {'user': u, 'notificationtext' : notificationtext})
send_mail(
'Agentur-Benachrichtigung',
'Hallo ' + u.first_name + ' ' + u.last_name + '! ' + notificationtext,
'noreply@digitale-agentur.com',
[u.email],
html_message=msg_html,
fail_silently=True
)
data.update({"user_" + str(u.pk) : u.email})
except:
data.update({"ERROR_user_" + str(u.pk) : u.email})
'''
else:
print("API CODE FAILED")
data.update({"status" : "failed"})