Added notify system.
This commit is contained in:
parent
e1a95588e7
commit
bd68997a5d
@ -21,6 +21,8 @@ Motions:
|
||||
- Added support for export motions in a zip archive [#3189].
|
||||
- Bugfix: changing motion line length did not invalidate cache [#3202]
|
||||
- Bugfix: Added more distance in motion PDF for DEL-tags in new lines [#3211].
|
||||
- Added warning message if an edit dialog was already opened by another
|
||||
client [#3212].
|
||||
|
||||
Users:
|
||||
- User without permission to see users can now see agenda item speakers,
|
||||
@ -36,6 +38,7 @@ Core:
|
||||
application [#3172].
|
||||
- Adding support for choosing image files as logos [#3184, #3207].
|
||||
- Fixing error when clearing empty chat [#3199].
|
||||
- Added notify system [#3212].
|
||||
|
||||
General:
|
||||
- Several bugfixes and minor improvements.
|
||||
|
@ -99,6 +99,11 @@ angular.module('OpenSlidesApp.core', [
|
||||
ErrorMessage.clearConnectionError();
|
||||
};
|
||||
};
|
||||
Autoupdate.send = function (message) {
|
||||
if (socket) {
|
||||
socket.send(JSON.stringify(message));
|
||||
}
|
||||
};
|
||||
Autoupdate.closeConnection = function () {
|
||||
if (socket) {
|
||||
socket.close();
|
||||
@ -262,38 +267,40 @@ angular.module('OpenSlidesApp.core', [
|
||||
'autoupdate',
|
||||
'dsEject',
|
||||
function (DS, autoupdate, dsEject) {
|
||||
// Handler for normal autoupdate messages.
|
||||
autoupdate.onMessage(function(json) {
|
||||
// TODO: when MODEL.find() is called after this
|
||||
// a new request is fired. This could be a bug in DS
|
||||
var dataList = [];
|
||||
try {
|
||||
dataList = JSON.parse(json);
|
||||
dataList = JSON.parse(json);
|
||||
} catch(err) {
|
||||
console.error(json);
|
||||
}
|
||||
|
||||
var dataListByCollection = _.groupBy(dataList, 'collection');
|
||||
_.forEach(dataListByCollection, function(list, key) {
|
||||
_.forEach(dataListByCollection, function (list, key) {
|
||||
var changedElements = [];
|
||||
var deletedElements = [];
|
||||
var collectionString = key;
|
||||
_.forEach(list, function(data) {
|
||||
_.forEach(list, function (data) {
|
||||
// Uncomment this line for debugging to log all autoupdates:
|
||||
// console.log("Received object: " + data.collection + ", " + data.id);
|
||||
|
||||
// remove (=eject) object from local DS store
|
||||
var instance = DS.get(data.collection, data.id);
|
||||
if (instance) {
|
||||
dsEject(data.collection, instance);
|
||||
}
|
||||
// check if object changed or deleted
|
||||
if (data.action === 'changed') {
|
||||
changedElements.push(data.data);
|
||||
} else if (data.action === 'deleted') {
|
||||
deletedElements.push(data.id);
|
||||
} else {
|
||||
console.error('Error: Undefined action for received object' +
|
||||
'(' + data.collection + ', ' + data.id + ')');
|
||||
// Now handle autoupdate message but do not handle notify messages.
|
||||
if (data.collection !== 'notify') {
|
||||
// remove (=eject) object from local DS store
|
||||
var instance = DS.get(data.collection, data.id);
|
||||
if (instance) {
|
||||
dsEject(data.collection, instance);
|
||||
}
|
||||
// check if object changed or deleted
|
||||
if (data.action === 'changed') {
|
||||
changedElements.push(data.data);
|
||||
} else if (data.action === 'deleted') {
|
||||
deletedElements.push(data.id);
|
||||
} else {
|
||||
console.error('Error: Undefined action for received object' +
|
||||
'(' + data.collection + ', ' + data.id + ')');
|
||||
}
|
||||
}
|
||||
});
|
||||
// add (=inject) all given objects into local DS store
|
||||
@ -307,6 +314,26 @@ angular.module('OpenSlidesApp.core', [
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Handler for notify messages.
|
||||
autoupdate.onMessage(function(json) {
|
||||
var dataList = [];
|
||||
try {
|
||||
dataList = JSON.parse(json);
|
||||
} catch(err) {
|
||||
console.error(json);
|
||||
}
|
||||
|
||||
var dataListByCollection = _.groupBy(dataList, 'collection');
|
||||
_.forEach(dataListByCollection, function (list, key) {
|
||||
_.forEach(list, function (data) {
|
||||
if (data.collection === 'notify') {
|
||||
// TODO: Add more code here.
|
||||
console.log(data);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
])
|
||||
|
||||
|
@ -276,6 +276,7 @@ angular.module('OpenSlidesApp.motions.site', [
|
||||
.factory('MotionForm', [
|
||||
'gettextCatalog',
|
||||
'operator',
|
||||
'autoupdate',
|
||||
'Editor',
|
||||
'MotionComment',
|
||||
'Category',
|
||||
@ -287,10 +288,18 @@ angular.module('OpenSlidesApp.motions.site', [
|
||||
'Workflow',
|
||||
'Agenda',
|
||||
'AgendaTree',
|
||||
function (gettextCatalog, operator, Editor, MotionComment, Category, Config, Mediafile, MotionBlock, Tag, User, Workflow, Agenda, AgendaTree) {
|
||||
function (gettextCatalog, operator, autoupdate, Editor, MotionComment, Category, Config, Mediafile, MotionBlock, Tag, User, Workflow, Agenda, AgendaTree) {
|
||||
return {
|
||||
// ngDialog for motion form
|
||||
getDialog: function (motion) {
|
||||
//TODO: This is just a test implementation. Remove it later.
|
||||
autoupdate.send([{
|
||||
collection: 'notify',
|
||||
name: 'motion_edit_dialog_opened',
|
||||
//users: [4, 5, ],
|
||||
//replyChannels: ["daphne.response.StSjKMGYeq!PfqbSbiJNP", ],
|
||||
}]);
|
||||
//End of test implementation
|
||||
return {
|
||||
template: 'static/templates/motions/motion-form.html',
|
||||
controller: motion ? 'MotionUpdateCtrl' : 'MotionCreateCtrl',
|
||||
|
@ -6,6 +6,7 @@ from openslides.utils.autoupdate import (
|
||||
ws_add_site,
|
||||
ws_disconnect_projector,
|
||||
ws_disconnect_site,
|
||||
ws_receive_site,
|
||||
)
|
||||
|
||||
projector_routing = [
|
||||
@ -16,6 +17,7 @@ projector_routing = [
|
||||
site_routing = [
|
||||
route("websocket.connect", ws_add_site),
|
||||
route("websocket.disconnect", ws_disconnect_site),
|
||||
route("websocket.receive", ws_receive_site),
|
||||
]
|
||||
|
||||
channel_routing = [
|
||||
|
@ -1,7 +1,7 @@
|
||||
import json
|
||||
import time
|
||||
import warnings
|
||||
from collections import Iterable
|
||||
from collections import Iterable, defaultdict
|
||||
|
||||
from channels import Channel, Group
|
||||
from channels.asgi import get_channel_layer
|
||||
@ -87,6 +87,67 @@ def ws_disconnect_site(message):
|
||||
websocket_user_cache.remove(message.user.id or 0, message.reply_channel.name)
|
||||
|
||||
|
||||
@channel_session_user
|
||||
def ws_receive_site(message):
|
||||
"""
|
||||
This function is called if a message from a client comes in. The message
|
||||
should be a list. Every item is broadcasted to the given users (or all
|
||||
users if no user list is given) if it is a notify element.
|
||||
|
||||
The server adds the sender's user id (0 for anonymous) and reply
|
||||
channel name so that a receiver client may reply to the sender or to all
|
||||
sender's instances.
|
||||
"""
|
||||
try:
|
||||
incomming = json.loads(message.content['text'])
|
||||
except ValueError:
|
||||
# Message content is invalid. Just do nothing.
|
||||
pass
|
||||
else:
|
||||
if isinstance(incomming, list):
|
||||
# Parse all items
|
||||
receivers_users = defaultdict(list)
|
||||
receivers_reply_channels = defaultdict(list)
|
||||
items_for_all = []
|
||||
for item in incomming:
|
||||
if item.get('collection') == 'notify':
|
||||
use_receivers_dict = False
|
||||
item['senderReplyChannelName'] = message.reply_channel.name
|
||||
item['senderUserId'] = message.user.id or 0
|
||||
|
||||
users = item.get('users')
|
||||
if isinstance(users, list):
|
||||
# Send this item only to all reply channels of some site users.
|
||||
for user_id in users:
|
||||
receivers_users[user_id].append(item)
|
||||
use_receivers_dict = True
|
||||
|
||||
reply_channels = item.get('replyChannels')
|
||||
if isinstance(reply_channels, list):
|
||||
# Send this item only to some reply channels.
|
||||
for reply_channel_name in reply_channels:
|
||||
receivers_reply_channels[reply_channel_name].append(item)
|
||||
use_receivers_dict = True
|
||||
|
||||
if not use_receivers_dict:
|
||||
# Send this item to all reply channels.
|
||||
items_for_all.append(item)
|
||||
|
||||
# Send all items
|
||||
for user_id, channel_names in websocket_user_cache.get_all().items():
|
||||
output = receivers_users[user_id]
|
||||
if len(output) > 0:
|
||||
for channel_name in channel_names:
|
||||
send_or_wait(Channel(channel_name).send, {'text': json.dumps(output)})
|
||||
|
||||
for channel_name, output in receivers_reply_channels.items():
|
||||
if len(output) > 0:
|
||||
send_or_wait(Channel(channel_name).send, {'text': json.dumps(output)})
|
||||
|
||||
if len(items_for_all) > 0:
|
||||
send_or_wait(Group('site').send, {'text': json.dumps(items_for_all)})
|
||||
|
||||
|
||||
@channel_session_user_from_http
|
||||
def ws_add_projector(message, projector_id):
|
||||
"""
|
||||
|
Loading…
Reference in New Issue
Block a user