コード例 #1
0
    def on_open(self, request):
        if self.session.session_id not in OperationNotifier.sessions:
            return False
        logging.debug('ChatConnection::on_open. session_id: %s' %
                      unicode(self.session.session_id))
        user, company, employee, client_cts = OperationNotifier.sessions[
            self.session.session_id]
        if employee._id not in OperationNotifier.connections:
            OperationNotifier.connections[employee._id] = [self]
            OperationNotifier.on_employee_online(employee._id)
            self.notify_online(employee)
        else:
            OperationNotifier.connections[employee._id].append(self)
        mem_cache.set('on-%s' % str(employee._id), 1, 0)
        self.company = company
        self.employee = employee
        self.user = user
        self.client_cts = client_cts
        self.connection_date = datetime.now()

        self.tailable_cursor = Operation.objects.collection.find(
            {
                'listeners': employee._id,
                'is_service': False,
                'timestamp': {
                    '$gt': self.client_cts
                }
            },
            tailable=True)

        op_list = self.get_missed_ops(self.client_cts)
        if len(op_list):
            server_cts = get_cts()
            self.client_cts = server_cts
            self.emit('operations', {'ops': op_list, 'new_cts': server_cts})
コード例 #2
0
ファイル: server.py プロジェクト: StanislavKraev/rekvizitka
    def on_open(self, request):
        if self.session.session_id not in OperationNotifier.sessions:
            return False
        logging.debug('ChatConnection::on_open. session_id: %s' % unicode(self.session.session_id))
        user, company, employee, client_cts = OperationNotifier.sessions[self.session.session_id]
        if employee._id not in OperationNotifier.connections:
            OperationNotifier.connections[employee._id] = [self]
            OperationNotifier.on_employee_online(employee._id)
            self.notify_online(employee)
        else:
            OperationNotifier.connections[employee._id].append(self)
        mem_cache.set('on-%s' % str(employee._id), 1, 0)
        self.company = company
        self.employee = employee
        self.user = user
        self.client_cts = client_cts
        self.connection_date = datetime.now()

        self.tailable_cursor = Operation.objects.collection.find({'listeners' : employee._id,
                                                                  'is_service' : False,
                                                                  'timestamp' : {'$gt' : self.client_cts}}, tailable=True)

        op_list = self.get_missed_ops(self.client_cts)
        if len(op_list):
            server_cts = get_cts()
            self.client_cts = server_cts
            self.emit('operations', {'ops' : op_list,
                                     'new_cts' : server_cts})
コード例 #3
0
    def test_first_mr(self):
        om1 = Operation({
            'owner': self.e2,
            'operation_type': OperationTypeEnum.OT_NEW_MESSAGE,
            'data': {
                'dialog': ObjectId(),
                'text': 'first',
                'email': 'email1'
            },
            'listeners': [self.e1, self.e2]
        })
        om1.save()

        oo1 = Operation({
            'owner': self.e1,
            'operation_type': OperationTypeEnum.OT_STATUS_CHANGE,
            'data': {
                'online': True
            },
            'listeners': [self.e2, self.e3]
        })
        oo1.save()

        task = UnreadDialogNotificationTask()
        task.make_employee_op_collection(get_cts() + 100000, 0)

        all_eo_items = mongodb_connection_manager.database[
            'chat_dialog_mr_udn'].find().sort([('value.ts', 1)])
        items = [item for item in all_eo_items]
        self.assertEqual(all_eo_items.count(), 2)

        test_m1 = items[0]
        test_o1 = items[1]

        self.assertIn('_id', test_m1)
        self.assertIn('_id', test_o1)

        self.assertIn('value', test_m1)
        self.assertIn('value', test_o1)

        m1_key = test_m1['_id']
        o1_key = test_o1['_id']

        self.assertIn('owner', m1_key)
        self.assertIn('owner', o1_key)

        self.assertEqual(m1_key['owner'], self.e1)
        self.assertEqual(o1_key['owner'], self.e1)

        self.assertIn('op', m1_key)
        self.assertIn('op', o1_key)

        self.assertEqual(m1_key['op'], 2)
        self.assertEqual(o1_key['op'], 3)

        m1_value = test_m1['value']
        o1_value = test_o1['value']

        self.assertIn('ts', m1_value)
        self.assertIn('ts', o1_value)
コード例 #4
0
    def on_check_dialog_viewed(self, **data):
        my_employee = self.employee
        try:
            dialog_id = data.get('dialog_id')
            dialog = ChatDialog.objects.get_one({
                '_id': ObjectId(dialog_id),
                'parties': my_employee._id
            })
            if not dialog:
                raise Exception('No such dialog')
        except Exception:
            self.emit('check_as_viewed', {'error': True})
            return
        ChatDialog.objects.collection.update(
            {'_id': dialog._id},
            {'$pull': {
                'not_viewed_by_parties': my_employee._id
            }})

        operation = Operation({
            'owner': my_employee._id,
            'operation_type': OperationTypeEnum.OT_MARK_READ,
            'data': {
                'dialog': dialog_id
            },
            'listeners': [my_employee._id]
        })
        operation.save()
        server_cts = get_cts()
        self.client_cts = server_cts
        OperationNotifier.notify(operation, self.client_cts)
コード例 #5
0
ファイル: server.py プロジェクト: StanislavKraev/rekvizitka
    def notify_status_change(self, employee, online = False):
        operation = Operation({'owner' : employee._id,
                               'operation_type' : OperationTypeEnum.OT_STATUS_CHANGE,
                               'data' : {'employee' : unicode(employee._id),
                                         'online' : online},
                               'listeners' : OperationNotifier.active_dialog_connections(employee._id)})

        operation.save()

        server_cts = get_cts()
        self.client_cts = server_cts
        OperationNotifier.notify(operation, self.client_cts)
コード例 #6
0
    def on_add_dlg_msg(self, **data):
        my_employee = self.employee
        try:
            text = data.get('text').strip()
            dialog_id = data.get('dialog_id')
            if not len(text):
                raise Exception('Missing required parameter "text"')
                # todo: asyncmongo
            dialog = ChatDialog.objects.get_one({
                '_id': ObjectId(dialog_id),
                'parties': my_employee._id
            })
            if not dialog:
                raise Exception('No such dialog')
        except Exception:
            self.emit('error', {'msg': u'Не удалось отправить сообщение'})
            return

        new_message = DialogMessage({
            'dialog': dialog._id,
            'text': text,
            'creator': my_employee._id
        })
        new_message.save()
        employee_tz = my_employee.get_tz()
        ChatDialog.objects.collection.update({'_id': dialog._id}, {
            '$set': {
                'last_message_date': new_message.date,
                'last_message_text': new_message.text[:200],
                'last_message_party': self.employee._id,
                'last_message_id': new_message._id,
                'hidden_by_parties': [],
                'not_viewed_by_parties': dialog.parties
            }
        })

        operation = Operation({
            'owner': my_employee._id,
            'operation_type': OperationTypeEnum.OT_NEW_MESSAGE,
            'data': {
                'dialog': dialog_id,
                'text': new_message.text,
                'date': new_message.date.astimezone(employee_tz).isoformat(),
                'author': unicode(my_employee._id),
                'message_id': unicode(new_message._id)
            },
            'listeners': dialog.parties
        })
        operation.save()
        server_cts = get_cts()
        self.client_cts = server_cts
        OperationNotifier.notify(operation, self.client_cts)
コード例 #7
0
ファイル: chat.py プロジェクト: StanislavKraev/rekvizitka
    def test_first_mr(self):
        om1 = Operation({'owner' : self.e2,
                         'operation_type' : OperationTypeEnum.OT_NEW_MESSAGE,
                         'data' : {'dialog' : ObjectId(),
                                   'text' : 'first',
                                   'email' : 'email1'},
                         'listeners' : [self.e1, self.e2]})
        om1.save()

        oo1 = Operation({'owner' : self.e1,
                         'operation_type' : OperationTypeEnum.OT_STATUS_CHANGE,
                         'data' : {'online' : True},
                         'listeners' : [self.e2, self.e3]})
        oo1.save()

        task = UnreadDialogNotificationTask()
        task.make_employee_op_collection(get_cts() + 100000, 0)

        all_eo_items = mongodb_connection_manager.database['chat_dialog_mr_udn'].find().sort([('value.ts', 1)])
        items = [item for item in all_eo_items]
        self.assertEqual(all_eo_items.count(), 2)

        test_m1 = items[0]
        test_o1 = items[1]

        self.assertIn('_id', test_m1)
        self.assertIn('_id', test_o1)

        self.assertIn('value', test_m1)
        self.assertIn('value', test_o1)

        m1_key = test_m1['_id']
        o1_key = test_o1['_id']

        self.assertIn('owner', m1_key)
        self.assertIn('owner', o1_key)

        self.assertEqual(m1_key['owner'], self.e1)
        self.assertEqual(o1_key['owner'], self.e1)

        self.assertIn('op', m1_key)
        self.assertIn('op', o1_key)

        self.assertEqual(m1_key['op'], 2)
        self.assertEqual(o1_key['op'], 3)

        m1_value = test_m1['value']
        o1_value = test_o1['value']

        self.assertIn('ts', m1_value)
        self.assertIn('ts', o1_value)
コード例 #8
0
    def execute(self):
        print >> sys.stdout, '%s Executing UnreadDialogNotificationTask' % unicode(datetime.now())

        search_ts = get_cts() - cts_from_timedelta(timedelta(hours = 3))
        ts_min = search_ts - cts_from_timedelta(timedelta(days = 3))
        result = self.make_employee_op_collection(search_ts, ts_min)
        if result['ok'] != 1:
            print >> sys.stderr, u'Failed to perform map_reduce during checking unread messages: %s' % repr(result)
            return

        result = self.make_employee_last_ops()
        if result['ok'] != 1:
            print >> sys.stderr, u'Failed to perform map_reduce step 2 during checking unread messages: %s' % repr(result)
            return

        unread_dialogs_cursor = self.find_unsent_messages()

        for unread_data in unread_dialogs_cursor:
            try:
                employee = unread_data['_id']
                if self.is_online(employee):
                    mark_as_sent = Operation({'owner' : employee,
                                              'operation_type' : OperationTypeEnum.OT_EMAIL_SENT,
                                              'data' : {'fake' : True},
                                              'listeners' : [employee],
                                              'is_service' : True})
                    mark_as_sent.save()
                    continue
                email = self.get_employee_email(employee)

                if not email or not is_valid_email(email):
                    continue

                action = create_action_id(actions.UNREAD_DIALOGS, employee)
                subj = u'Непрочитанные сообщения в Реквизитке'

                data = {'SITE_DOMAIN_NAME' : settings.SITE_DOMAIN_NAME}
                text = render_to_string('mail/chat/unread_dialogs.txt', data)
                html = render_to_string('mail/chat/unread_dialogs.html', data)

                notification_manager.remove(action)
                notification_manager.add(action, email, subj, text, html, settings.UNREAD_MESSAGE_EMAIL_NOTIFY_TIMEOUT)
                mark_as_sent = Operation({'owner' : employee,
                                          'operation_type' : OperationTypeEnum.OT_EMAIL_SENT,
                                          'data' : {},
                                          'listeners' : [employee],
                                          'is_service' : True})
                mark_as_sent.save()
            except Exception:
                pass
コード例 #9
0
    def get(self, request):
        company = request.company
        employee = request.employee

        data = DialogListInitialsView.generate_data_obj(employee, company)
        data.update(portal.get_common_data_for_company(request, company))
        module_init = mark_safe(simplejson.dumps(data))
        response = render_to_response('apps/chat/dialoglist/templates/template.html',
                {
                'chat_module_init' : module_init,
                'sidebar_mode' : 'some_company',
                'sidebar_initial_data' : company
            }, context_instance = RequestContext(request))
        response.set_cookie('cts', get_cts(), max_age=3600)
        return response
コード例 #10
0
ファイル: chat.py プロジェクト: StanislavKraev/rekvizitka
    def test_first_mr_after_ts(self):
        self.send_online(self.e1, [self.e2, self.e3])
        self.send_message(self.e1, self.e2)

        self.send_online(self.e2, [self.e1, self.e3])
        self.send_message(self.e2, self.e1)
        ts = self.send_message(self.e2, self.e1).timestamp
        self.send_message(self.e1, self.e2)
        self.send_message(self.e1, self.e3)
        self.send_online(self.e3, [self.e1, self.e2])
        self.send_message(self.e3, self.e1)

        task = UnreadDialogNotificationTask()
        task.make_employee_op_collection(get_cts() + 100000, ts)

        all_eo_items = mongodb_connection_manager.database['chat_dialog_mr_udn'].find().sort([('value.ts', 1)])
        self.assertEqual(all_eo_items.count(), 4)
コード例 #11
0
    def test_first_mr_after_ts(self):
        self.send_online(self.e1, [self.e2, self.e3])
        self.send_message(self.e1, self.e2)

        self.send_online(self.e2, [self.e1, self.e3])
        self.send_message(self.e2, self.e1)
        ts = self.send_message(self.e2, self.e1).timestamp
        self.send_message(self.e1, self.e2)
        self.send_message(self.e1, self.e3)
        self.send_online(self.e3, [self.e1, self.e2])
        self.send_message(self.e3, self.e1)

        task = UnreadDialogNotificationTask()
        task.make_employee_op_collection(get_cts() + 100000, ts)

        all_eo_items = mongodb_connection_manager.database[
            'chat_dialog_mr_udn'].find().sort([('value.ts', 1)])
        self.assertEqual(all_eo_items.count(), 4)
コード例 #12
0
    def notify_status_change(self, employee, online=False):
        operation = Operation({
            'owner':
            employee._id,
            'operation_type':
            OperationTypeEnum.OT_STATUS_CHANGE,
            'data': {
                'employee': unicode(employee._id),
                'online': online
            },
            'listeners':
            OperationNotifier.active_dialog_connections(employee._id)
        })

        operation.save()

        server_cts = get_cts()
        self.client_cts = server_cts
        OperationNotifier.notify(operation, self.client_cts)
コード例 #13
0
ファイル: server.py プロジェクト: StanislavKraev/rekvizitka
    def on_add_dlg_msg(self, **data):
        my_employee = self.employee
        try:
            text = data.get('text').strip()
            dialog_id = data.get('dialog_id')
            if not len(text):
                raise Exception('Missing required parameter "text"')
                # todo: asyncmongo
            dialog = ChatDialog.objects.get_one({'_id' : ObjectId(dialog_id),
                                                 'parties' : my_employee._id})
            if not dialog:
                raise Exception('No such dialog')
        except Exception:
            self.emit('error', {'msg' : u'Не удалось отправить сообщение'})
            return

        new_message = DialogMessage({'dialog' : dialog._id,
                                     'text' : text,
                                     'creator' : my_employee._id})
        new_message.save()
        employee_tz = my_employee.get_tz()
        ChatDialog.objects.collection.update({'_id' : dialog._id}, {'$set' : {
            'last_message_date' : new_message.date,
            'last_message_text' : new_message.text[:200],
            'last_message_party' : self.employee._id,
            'last_message_id' : new_message._id,
            'hidden_by_parties' : [],
            'not_viewed_by_parties' : dialog.parties
        }})

        operation = Operation({'owner' : my_employee._id,
                               'operation_type' : OperationTypeEnum.OT_NEW_MESSAGE,
                               'data' : {'dialog' : dialog_id,
                                         'text' : new_message.text,
                                         'date' : new_message.date.astimezone(employee_tz).isoformat(),
                                         'author' : unicode(my_employee._id),
                                         'message_id' : unicode(new_message._id)},
                               'listeners' : dialog.parties})
        operation.save()
        server_cts = get_cts()
        self.client_cts = server_cts
        OperationNotifier.notify(operation, self.client_cts)
コード例 #14
0
ファイル: server.py プロジェクト: StanislavKraev/rekvizitka
    def on_refresh_connection(self, endpoint_name):
        logging.debug('* * * Refresh connection')
        data_list = self.get_missed_ops(self.client_cts)

        if len(data_list):
            logging.debug('* * * %i new operations:' % len(data_list))
            for op in data_list:
                logging.debug(repr(op))
            # dirty hack
            server_cts = get_cts()
            self.client_cts = server_cts
            msg = proto.event(endpoint_name, 'operations', None, {'ops' : data_list, 'new_cts' : server_cts})
            self.session.send_queue.append(msg)
            return True

        cur_date = datetime.now()
        dt = cur_date - self.connection_date
        if dt.seconds / 3600.0 > 2:
            return False

        return True
コード例 #15
0
ファイル: server.py プロジェクト: StanislavKraev/rekvizitka
    def on_check_dialog_viewed(self, **data):
        my_employee = self.employee
        try:
            dialog_id = data.get('dialog_id')
            dialog = ChatDialog.objects.get_one({'_id' : ObjectId(dialog_id),
                                                 'parties' : my_employee._id})
            if not dialog:
                raise Exception('No such dialog')
        except Exception:
            self.emit('check_as_viewed', {'error' : True})
            return
        ChatDialog.objects.collection.update({'_id' : dialog._id},
                                             {'$pull' : {'not_viewed_by_parties' : my_employee._id}})

        operation = Operation({'owner' : my_employee._id,
                               'operation_type' : OperationTypeEnum.OT_MARK_READ,
                               'data' : {'dialog' : dialog_id},
                               'listeners' : [my_employee._id]})
        operation.save()
        server_cts = get_cts()
        self.client_cts = server_cts
        OperationNotifier.notify(operation, self.client_cts)
コード例 #16
0
    def on_refresh_connection(self, endpoint_name):
        logging.debug('* * * Refresh connection')
        data_list = self.get_missed_ops(self.client_cts)

        if len(data_list):
            logging.debug('* * * %i new operations:' % len(data_list))
            for op in data_list:
                logging.debug(repr(op))
            # dirty hack
            server_cts = get_cts()
            self.client_cts = server_cts
            msg = proto.event(endpoint_name, 'operations', None, {
                'ops': data_list,
                'new_cts': server_cts
            })
            self.session.send_queue.append(msg)
            return True

        cur_date = datetime.now()
        dt = cur_date - self.connection_date
        if dt.seconds / 3600.0 > 2:
            return False

        return True
コード例 #17
0
    def get(self, request, dialog_id):
        employee = request.employee
        try:
            dialog = ChatDialog.objects.get_one({'_id' : ObjectId(dialog_id),
                                                 'hidden_by_parties' : {'$ne' : employee._id},
                                                 'parties' : employee._id})
            if not dialog:
                raise Exception()
        except Exception:
            raise Http404()

        company = request.company

        data = DialogInitialsView.generate_data_obj(dialog, employee, company)
        data.update(portal.get_common_data_for_company(request, company))
        module_initials = mark_safe(simplejson.dumps(data))
        response = render_to_response('apps/chat/dialog/templates/template.html',
                {
                'chat_module_init' : module_initials,
                'sidebar_mode' : 'some_company',
                'sidebar_initial_data' : company
            }, context_instance = RequestContext(request))
        response.set_cookie('cts', get_cts(), max_age=3600)
        return response
コード例 #18
0
 def save(self):
     self.timestamp = get_cts()
     return super(Operation, self).save()