示例#1
0
    def create_new_thread_with_topic(title, session_id, course_id, topic,
                                     is_instructor):
        newThread = Thread(title=escape(title),
                           original_poster=session_id,
                           course_id=course_id,
                           topic=topic,
                           pinned=is_instructor)
        newThread.save()
        unique_key = 'threads' + course_id + topic
        redis_publisher = RedisPublisher(facility=unique_key, broadcast=True)
        message = RedisMessage(
            json.dumps({
                'type': 'thread_created',
                'thread_id': newThread.pk,
                'thread_title': newThread.title,
                'replyNum': newThread.getNumberOfReplies(),
                'pinned': newThread.pinned,
            }))
        redis_publisher.publish_message(message)

        redis_publisher = RedisPublisher(facility=session_id, broadcast=True)
        message = RedisMessage(
            json.dumps({
                'type': 'created-thread',
                'thread_id': newThread.pk
            }))
        redis_publisher.publish_message(message)
        return newThread
示例#2
0
 def process_workbook(self, filepaths):
     redis_publisher = RedisPublisher(facility='processing',
                                      **{'broadcast': True})
     counter = 1
     redis_data = {
         "total_rows": 0,
         "rows_processed": 0,
         "rows_ignored": 0,
         "jd_created": 0,
         "error": False,
         "error_message": ""
     }
     for filepath in filepaths:
         try:
             data = self.readxlsx(filepath)
             redis_data["total_rows"] += len(data)
             message = RedisMessage(json.dumps(redis_data))
             redis_publisher.publish_message(message)
             from core.models import WorkBook
             for row in data:
                 redis_data["rows_processed"] += 1
                 workbook, created = WorkBook.objects.get_or_create(
                     id=row['ID'])
                 if not created:
                     redis_data["rows_ignored"] += 1
                 else:
                     redis_data['jd_created'] += 1
                     workbook.role = row['Role']
                     workbook.level = row['Level']
                     workbook.primary_skill = row['Primary Skill']
                     workbook.secondary_skill = row['Secondary Skill']
                     workbook.description = row['Description']
                     workbook.save()
                 message = RedisMessage(json.dumps(redis_data))
                 redis_publisher.publish_message(message)
             counter += 1
         except KeyError:
             redis_data['error'] = True
             redis_data[
                 'error_message'] = "Some fields are missing in file %s<br>" % filepath.replace(
                     'media/', '')  # noqa
             message = RedisMessage(json.dumps(redis_data))
             redis_publisher.publish_message(message)
             continue
         except xlrd.XLRDError:
             redis_data['error'] = True
             redis_data[
                 'error_message'] += "Invalid File Provided %s<br>" % filepath.replace(
                     'media/', '')  # noqa
             message = RedisMessage(json.dumps(redis_data))
             redis_publisher.publish_message(message)
             continue
示例#3
0
 def setUp(self):
     self.facility = u'unittest'
     self.prefix = getattr(settings, 'WS4REDIS_PREFIX', 'ws4redis')
     self.websocket_base_url = self.live_server_url.replace('http:', 'ws:', 1) + u'/ws/' + self.facility
     self.message = RedisMessage(''.join(unichr(c) for c in range(33, 128)))
     self.factory = RequestFactory()
     # SessionStore
     # as used here: http://stackoverflow.com/a/7722483/1913888
     settings.SESSION_ENGINE = 'redis_sessions.session'
     engine = import_module(settings.SESSION_ENGINE)
     store = engine.SessionStore()
     store.save()
     self.session = store
     self.client.cookies[settings.SESSION_COOKIE_NAME] = store.session_key
示例#4
0
    def mpc_idle(self):
        """Idle until event received from MPD.
        Note: this is blocking. To break this loop, toggle some switch on MPD.
        """
        self.ensure_connected()
        res = ['']
        if self.connected:
            res = self.client.idle()
            self.check_party_mode(res)

        if 'update' in res and 'updating_db' not in self.client.status():
            # let ratings scanner do rescan if database updated
            self.main.rescan_ratings = True
            # clear yellow LED
            write_gpio_pipe('1 0')
        elif 'update' in res:
            # raise yellow LED
            write_gpio_pipe('1 1')

        if 'playlist' in res:
            # Tell playlist view to update its status.
            redis_publisher = RedisPublisher(facility='piremote',
                                             broadcast=True)
            redis_publisher.publish_message(RedisMessage('playlist'))

        if 'player' not in res:
            return

        # Publish current player state via websocket via redis broadcast.
        state = self.client.status()
        cur = self.client.currentsong()
        state_data = dict(event=res)
        msg = json.dumps(state_data)
        redis_publisher = RedisPublisher(facility='piremote', broadcast=True)
        redis_publisher.publish_message(RedisMessage(msg))

        # Check if playing and file changed --> insert into history if so.
        if 'state' in state and state['state'] == 'play':
            file = cur['file']
            if file != self.last_file:
                self.last_file = file
                if 'artist' in cur and 'title' in cur:
                    title = '%s - %s' % (cur['artist'], cur['title'])
                elif 'title' in cur:
                    title = cur['title']
                else:
                    no_ext = os.path.splitext(file)[0]
                    title = os.path.basename(no_ext).replace('_', ' ')
                self.insert_into_history(file, title)
示例#5
0
def test_publish(request):
    pref = settings.MY_PREFIX
    redis_publisher = RedisPublisher(facility=pref, broadcast=True)
    message = RedisMessage(
        json.dumps({
            'type': 'test',
            'message': 'this is a test message from server to everyone!'
        }))
    redis_publisher.publish_message(message)
    if request.GET.get('facility', None):
        redis_publisher = RedisPublisher(facility=request.GET['facility'],
                                         broadcast=True)
        redis_publisher.publish_message(
            RedisMessage('this is a test message from server to group!'))
    return HttpResponse('OK')
示例#6
0
def stk_push(phone_number, price, first_name, last_name, user_name):
    push_url = 'http://pay.brandfi.co.ke:8301/api/stkpush'

    push_params = {
        "clientId": "2",
        "transactionType": "CustomerPayBillOnline",
        "phoneNumber": phone_number,
        "amount": "1",
        "callbackUrl": "http://pay.brandfi.co.ke/payfi-success",
        "accountReference": "demo",
        "transactionDesc": "Test"
    }

    headers = {'Content-type': 'application/json'}

    r = requests.post(push_url, json=push_params, headers=headers)
    parsed_json = json.loads(r.text)
    checkoutRequestId = parsed_json['CheckoutRequestID']
    mobile_number = phone_number.replace("254", "0")

    stk_push_query = STKPushQuery(
        checkoutRequestId, mobile_number, first_name, last_name, user_name)

    """Example of how to send server generated events to clients."""
    while not stk_push_query.is_result:
        stk_push_query.push_query()
        redis_publisher = RedisPublisher(facility='foobar', broadcast=True)
        message = RedisMessage(stk_push_query.result)
        redis_publisher.publish_message(message)

        if(stk_push_query.is_result):
            break
示例#7
0
def notify_user(user_names: List[str], content: dict):
    try:
        redis_publisher = RedisPublisher(facility=settings.FACILITY_WS4REDIS, broadcast=False, users=user_names)
        message = RedisMessage(json.dumps(content))
        redis_publisher.publish_message(message)
    except:
        logging.exception('Error while sending notification to users "%s"', user_names)
    def listen_and_replay_to_redis(self):

        logger = logging.getLogger("django")

        tid = random.randint(1, 1000)
        logger.debug(" >> [%s] websocket starting thread" % tid)


        try:

            redis_publisher = RedisPublisher(facility='foobar', broadcast=True)

            while True:
                data = str(uuid.uuid4())

                #self.counter += 1

                #data = "%s - %s" % (data, self.counter)

                redis_publisher.publish_message(RedisMessage(data))
                ttw = random.uniform(3, 10)
                logger.debug(" >> [%s] websocket thread %s: %s waiting %s seconds" % (tid, datetime.now().strftime("%H:%M:%S"), data, ttw))
                time.sleep(ttw)
        except Exception as e:
            logger.debug(" >> [%s] websocket thread error: %s" % (tid,e))

        logger.debug(" >> [%s] websocket thread dying" % tid)
示例#9
0
文件: views.py 项目: murtraja/mychat
def group_post(request):
    redis_publisher = RedisPublisher(facility='myg',
                                     groups=request.POST.get('group'))
    msg = request.POST.get('message')
    message = RedisMessage(request.POST.get('user') + ": " + msg)
    redis_publisher.publish_message(message)
    return HttpResponse('OK')
示例#10
0
def display(msg,
            task_id,
            color=None,
            stderr=False,
            screen_only=False,
            log_only=False,
            runner=None):
    # prevent a very rare case of interlaced multiprocess I/O
    log_flock(runner)
    while msg.startswith("\n"):
        msg = msg.replace("\n", "")
    msg2 = msg + '\n'
    if color:
        msg2 = stringc(msg, color) + '\n'

    logger.debug('TASK_ID: {task_id} | MSG: {message}'.format(task_id=task_id,
                                                              message=msg2))

    # Pusblish the message on websocket
    redis_publisher = RedisPublisher(facility=task_id, broadcast=True)
    redis_message = RedisMessage(msg2)
    redis_publisher.publish_message(message=redis_message)

    # Store the message into a redis list to let the user get all
    # history of the logs
    redis_connection.rpush('tasks:' + task_id, msg2)
    # reset the expire of the list
    if settings.WS4REDIS_EXPIRE:
        if settings.WS4REDIS_EXPIRE > 0:
            redis_connection.expire('tasks:' + task_id,
                                    settings.WS4REDIS_EXPIRE)
    log_unflock(runner)
def old_listen_and_replay_to_redis():
    TCP_IP = '127.0.0.1'
    TCP_PORT = 5555
    BUFFER_SIZE = 1024

    redis_publisher = RedisPublisher(facility='foobar', broadcast=True)

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    s.bind((TCP_IP, TCP_PORT))
    s.listen(1)

    while True:
        conn, addr = s.accept()

        print 'Connection address:', addr

        data = conn.recv(BUFFER_SIZE)
        if not data:
            continue

        try:
            redis_publisher.publish_message(RedisMessage(data))
        except Exception as e:
            print "could not publish in redis because %s" % e

        conn.send("Thank you for your message. Bye.\n")
        conn.close()
示例#12
0
 def get(self, request, *args, **kwargs):
     welcome = RedisMessage(
         'Hello everybody'
     )  # create a welcome message to be sent to everybody
     RedisPublisher(facility='foobar',
                    broadcast=True).publish_message(welcome)
     return super(BroadcastChatView, self).get(request, *args, **kwargs)
示例#13
0
 def dumpTargetData(self, request, pk=None):
     connectionCheck()
     ids = json.loads(request.data['ids'])
     data = ''
     count = 1
     for pk in ids:
         try:
             target = Target.objects.get(pk=pk)
             target.wasSent()
             data += str(count) + '\t' + str(target.ptype) + '\t' + str(
                 target.latitude
             ) + '\t' + str(
                 target.longitude
             ) + '\t' + target.orientation + '\t' + target.shape + '\t' + target.background_color + '\t' + target.alphanumeric + '\t' + target.alphanumeric_color + '\t' + target.picture.url + '\n'
             count += 1
         except Target.DoesNotExist:
             continue
     # websocket response for "sent"
     redis_publisher = RedisPublisher(facility='viewer',
                                      sessions=gcsSessions())
     redis_publisher.publish_message(
         RedisMessage(json.dumps({
             'target': 'sent',
             'ids': ids
         })))
     return Response({'data': data})
示例#14
0
def lanzafinllamada(request, base, agente):

    if Agente.objects.filter(anexo=int(agente)).count() > 1:

        a = simplejson.dumps('Existe muchos agentes agente con el anexo ' +
                             agente)
        return HttpResponse(a, content_type="application/json")

    if Agente.objects.filter(anexo=int(agente)).count() == 0:

        a = simplejson.dumps('No existe el agente con anexo ' + agente)
        return HttpResponse(a, content_type="application/json")

    _agente = Agente.objects.get(anexo=int(agente))

    _agente.estado_id = 3
    _agente.id_estado = 4
    _agente.save()

    redis_publisher = RedisPublisher(
        facility='foobar',
        users=[_agente.user.username, 'edeamat', 'scondezo'])

    message = RedisMessage('llamada-' + str(base))

    redis_publisher.publish_message(message)

    a = simplejson.dumps('Se lanzo FIN  llamada al agente con el anexo ' +
                         agente)
    return HttpResponse(a, content_type="application/json")
示例#15
0
def detalle_venta(request, id_produccion):

    if request.method == 'POST':

        instance = Produccion()

        telefono = request.POST['telefono_1']

        instance = Produccion.objects.get(id=id_produccion)

        form = ProduccionForm(request.POST or None, instance=instance)

        if form.is_valid():

            form.save()

        redis_publisher = RedisPublisher(facility='foobar',
                                         users=[request.user.username])

        message = RedisMessage('llamada-' + str(telefono))

        redis_publisher.publish_message(message)

        return render(request, 'colasIN/exito.html', {})

    if request.method == 'GET':

        incidencia = Produccion.objects.get(id=id_produccion)

        incidenciaform = ProduccionForm(instance=incidencia)

        return render(request, 'colasIN/detalle_venta.html', {
            'incidenciaform': incidenciaform,
            'incidencia': incidencia
        })
示例#16
0
def gdelete(request):
    groupname = request.POST.get('name', 0)
    rd = StrictRedis()
    pref = settings.MY_PREFIX
    prefg = pref + ":" + groupname
    user = str(request.user)
    print "received request for deleting", groupname, "from", user
    ismember = rd.sismember(pref + ":groups", groupname)
    if not ismember:
        return JsonResponse({
            'done': False,
            'reason': 'No such group name'
        })
    # now check whether the requesting user is the one who created the group
    d = rd.hgetall(prefg + ":hash")
    if d['owner'] != user:
        return JsonResponse({
            'done': False,
            'reason': 'Only group owner can delete the group'
        })
    rd.srem(pref + ":groups", groupname)
    rd.delete(prefg + ":hash", pref + ":" + groupname)
    rd.delete(pref + ":" + groupname)
    redis_publisher = RedisPublisher(facility=pref, broadcast=True)
    redis_publisher.publish_message(
        RedisMessage(json.dumps({
            "type": "group_delete",
            "name": groupname
        })))
    return JsonResponse({'done': True})
示例#17
0
 def websocket_publish_message(channel,message):
     websocket_message = RedisMessage(message)  # create a welcome message to be sent to everybody
     RedisPublisher(facility=channel, broadcast=True).publish_message(websocket_message)
     
 
     
     
示例#18
0
    def send_message(self, game, message):

        facility = 'notify-%s' % game.slug
        self.stdout.write('  Sending %s [facility=%s]' % (message, facility))

        redis_publisher = RedisPublisher(facility=facility, broadcast=True)
        redis_publisher.publish_message(RedisMessage(message))
示例#19
0
    def postHeartbeat(self, request, pk=None):
        global EXPIRATION
        #check for seperate cache entry
        """
		if (cache.get('heartbeat') != None):	#trigger would be 'heartbeat' for status of heartbeats
			#SEND TRIGGER IN THIS CASE TO START
		"""

        if not cache.has_key('heartbeat'):
            #if doesn't have key heartbeat set its cache entry
            cache.set('heartbeat', 'connected', EXPIRATION)
        else:
            #else delete the old one
            cache.delete('heartbeat')
            #create a new one
            cache.set('heartbeat', 'connected', EXPIRATION)

        #ONCE STARTS RECEIVING HEARTBEATS
        #cache.set('heartbeat', 'triggering', EXPIRATION)

        #ONCE STOPS RECEIVING HEARTBEATS
        #cache.set('heartbeat','stopped', EXPIRATION)

        if cache.get('trigger') == 1:
            redis_publisher = RedisPublisher(facility="viewer",
                                             sessions=gcsSessions())
            redis_publisher.publish_message(
                RedisMessage(
                    json.dumps({
                        'triggering': 'true',
                        'time': cache.get("time")
                    })))
        elif cache.get('trigger') == 0:
            redis_publisher = RedisPublisher(facility="viewer",
                                             sessions=gcsSessions())
            redis_publisher.publish_message(
                RedisMessage(json.dumps({'triggering': 'false'})))

        if (cache.has_key('trigger')):
            return Response({
                'heartbeat': cache.get('trigger'),
                'loop': cache.get('loop'),
                'delay': cache.get('delay')
            })
        else:
            return Response({})
示例#20
0
def publish_in_ws(image):
    data = dict()
    data["id"] = image.id
    converted = image.converted_datetime
    data["created"] = time.mktime(image.created.timetuple())
    data["converted_datetime"] = converted and time.mktime(converted.timetuple()) or None
    msg = RedisMessage(json.dumps(data))
    RedisPublisher(facility='foobar', broadcast=True).publish_message(msg)
def publish(object):
    """
    Publish an object to websocket listeners
    :param object: A Django predictive_model
    :return: {type: object class name, data: OBJECT}
    """
    message = RedisMessage(_serializer(object))
    redis_publisher.publish_message(message)
示例#22
0
def notify_file_ready(args):
    sess, msg = args
    # simulate hard work
    time.sleep(1)
    redis_publisher = RedisPublisher(facility='comm', sessions=[sess])
    message = RedisMessage(msg)
    redis_publisher.publish_message(message)
    return msg
示例#23
0
文件: views.py 项目: murtraja/mychat
def broadcast_post(request):
    redis_publisher = RedisPublisher(facility='foobar', broadcast=True)
    msg = request.POST.get('message')
    rip = request.META['REMOTE_ADDR']
    message = RedisMessage(rip + ': ' + msg)
    print msg, ' from ', rip
    redis_publisher.publish_message(message)
    return HttpResponse('OK')
示例#24
0
def create_notification(assignee, task_title):
    task = Task.objects.get(title=task_title)
    user = User.objects.get(pk=assignee)
    if task:
        notify = Notification.objects.create(assigned_to=user, notify=task)
        redis_publisher = RedisPublisher(facility="foobar", broadcast=True)
        message = RedisMessage("new")
        redis_publisher.publish_message(message)
        return True
示例#25
0
def publishMessage(topic, message="update", groups=[]):

    if not groups:
        redis_publisher = RedisPublisher(facility=topic, broadcast=True)
    else:
        redis_publisher = RedisPublisher(facility=topic, groups=groups)

    message = RedisMessage(message)
    redis_publisher.publish_message(message)
示例#26
0
def connectionCheck():

    if cache.has_key("checkallowed"):
        if not cache.has_key("android"):
            redis_publisher = RedisPublisher(facility='viewer',
                                             sessions=gcsSessions())
            redis_publisher.publish_message(
                RedisMessage(json.dumps({'disconnected': 'disconnected'})))
            cache.delete("checkallowed")
示例#27
0
文件: ajax.py 项目: coblan/first
def notify_refresh_user(id, name):
    redis_publisher = RedisPublisher(facility='talk', broadcast=True)
    message = RedisMessage(
        json.dumps({
            'op': 'notify_refresh_user',
            'id': id,
            'name': name
        }))
    redis_publisher.publish_message(message)
    return {'status': 'success'}
示例#28
0
 def add_to_queue(self, obj):
     if getattr(settings, 'UNIVERSAL_NOTIFICATIONS_TWILIO_ENABLE_PROXY', False):
         connection = StrictRedis(**private_settings.WS4REDIS_CONNECTION)
         r = JSONRenderer()
         json_data = r.render({'number': obj.from_phone})
         channel = getattr(settings, 'UNIVERSAL_NOTIFICATIONS_TWILIO_DISPATCHER_CHANNEL', '__un_twilio_dispatcher')
         connection.publish(channel, RedisMessage(json_data))
     else:
         self.send(obj.message)
         obj.message.save()
示例#29
0
    def UpdateDoc(self, row_data, user):
        err = {"error": "Input Validation Failed"}

        if not ValidateUserInput(row_data['comment']).ValidateInputMixed():
            return err

        query = {
            "doc": {
                "Record": {
                    "Comment": {
                        "Date": str(datetime.datetime.utcnow()),
                        "Analyst": str(user),
                        "Comment": row_data['comment']
                    },
                    "Tag": update_control.TagIntToStr(row_data['tag'])
                }
            }
        }

        try:
            r = requests.post(self.es_host + ":" + self.es_port + self.index +
                              self.type_audit_type +
                              '/{0}/_update?parent={1}'.format(
                                  row_data['rowId'], row_data['parent']),
                              data=json.dumps(query),
                              auth=(self.elastic_user, self.elastic_pass),
                              verify=False)
        except ConnectionError as e:
            ret = {"connection_error": e.args[0]}
            return ret

        try:
            q = requests.get(self.es_host + ":" + self.es_port + self.index +
                             self.type_audit_type + "/{0}?parent={1}".format(
                                 row_data['rowId'], row_data['parent']),
                             auth=(self.elastic_user, self.elastic_pass),
                             verify=False)
            case = q.json()['_source']['CaseInfo']['case_name']
        except ConnectionError as e:
            _ret = {"connection_error": e.args[0]}
            return _ret

        redis_publisher = RedisPublisher(facility='comments', broadcast=True)

        broadcast_comment = {
            "comment": row_data['comment'],
            "endpoint": row_data['parent'],
            "case": case,
            "analyst": str(user)
        }

        redis_publisher.publish_message(
            RedisMessage(json.dumps(broadcast_comment)))

        return r.json()
示例#30
0
def interop_error_handler(error, startTime):
    code, reason, text = error.errorData()

    #response to client accordingly
    #but keep going...if something fails, respond and ignore it
    #alert mission planner about the error though
    if code == 400:
        return Response({
            'time': time() - startTime,
            'error': "WARNING: Invalid telemetry data. Skipping"
        })

    elif code == 404:
        return Response({
            'time': time() - startTime,
            'error': "WARNING: Server might be down"
        })

    elif code == 405 or code == 500:
        return Response({
            'time': time() - startTime,
            'error': "WARNING: Interop Internal Server Error"
        })
    #EXCEPT FOR THIS
    elif code == 403:
        creds = cache.get("Creds")
        times = 5
        for i in xrange(0, times):
            try:
                interop_login(username=creds['username'],
                              password=creds['password'],
                              server=creds['server'],
                              tout=5)
                return Response({
                    'time': time() - startTime,
                    'error': "Had to relogin in. Succeeded"
                })
            except Exception as e:
                sleep(2)
                continue
        code, _, __ = e.errorData()
        #Everyone should be alerted of this
        resp = {
            'time':
            time() - startTime,
            'error':
            "CRITICAL: Re-login has Failed. We will login again when allowed\nLast Error was %d"
            % code
        }
        redis_publisher = RedisPublisher(facility='viewer',
                                         sessions=gcsSessions())
        redis_publisher.publish_message(
            RedisMessage(json.dumps({'warning': resp})))
        return Response(resp)
class WebsocketTests(LiveServerTestCase):
    fixtures = ['data.json']

    @classmethod
    def setUpClass(cls):
        os.environ.update(DJANGO_LIVE_TEST_SERVER_ADDRESS="localhost:8000-8010,8080,9200-9300")
        super(WebsocketTests, cls).setUpClass()
        cls.server_thread.httpd.set_app(application)

    def setUp(self):
        self.facility = u'unittest'
        self.prefix = getattr(settings, 'WS4REDIS_PREFIX', 'ws4redis')
        self.websocket_base_url = self.live_server_url.replace('http:', 'ws:', 1) + u'/ws/' + self.facility
        self.message = RedisMessage(''.join(unichr(c) for c in range(33, 128)))
        self.factory = RequestFactory()
        # SessionStore
        # as used here: http://stackoverflow.com/a/7722483/1913888
        settings.SESSION_ENGINE = 'redis_sessions.session'
        engine = import_module(settings.SESSION_ENGINE)
        store = engine.SessionStore()
        store.save()
        self.session = store
        self.client.cookies[settings.SESSION_COOKIE_NAME] = store.session_key

    @classmethod
    def tearDownClass(cls):
        time.sleep(1)

    def test_subscribe_broadcast(self):
        audience = {'broadcast': True}
        publisher = RedisPublisher(facility=self.facility, **audience)
        publisher.publish_message(self.message, 10)
        websocket_url = self.websocket_base_url + u'?subscribe-broadcast'
        ws = create_connection(websocket_url)
        self.assertTrue(ws.connected)
        result = ws.recv()
        if six.PY3:
            self.message = self.message.decode()
        self.assertEqual(result, self.message)
        ws.close()
        self.assertFalse(ws.connected)

    def test_pubsub_broadcast(self):
        websocket_url = self.websocket_base_url + u'?subscribe-broadcast&publish-broadcast'
        ws = create_connection(websocket_url)
        self.assertTrue(ws.connected)
        ws.send(self.message)
        result = ws.recv()
        if six.PY3:
            self.message = self.message.decode()
        self.assertEqual(result, self.message)
        ws.close()
        self.assertFalse(ws.connected)

    def test_publish_broadcast(self):
        websocket_url = self.websocket_base_url + u'?publish-broadcast'
        ws = create_connection(websocket_url)
        self.assertTrue(ws.connected)
        ws.send(self.message)
        ws.close()
        self.assertFalse(ws.connected)
        publisher = RedisPublisher()
        request = self.factory.get('/chat/')
        result = publisher.fetch_message(request, self.facility, 'broadcast')
        self.assertEqual(result, self.message)
        # now access Redis store directly
        self.assertEqual(publisher._connection.get(self.prefix + ':broadcast:' + self.facility), self.message)

    def test_subscribe_user(self):
        logged_in = self.client.login(username='******', password='******')
        self.assertTrue(logged_in, 'John is not logged in')
        request = self.factory.get('/chat/')
        request.user = User.objects.get(username='******')
        audience = {'users': ['john', 'mary']}
        publisher = RedisPublisher(request=request, facility=self.facility, **audience)
        publisher.publish_message(self.message, 10)
        websocket_url = self.websocket_base_url + u'?subscribe-user'
        header = ['Cookie: sessionid={0}'.format(self.client.cookies['sessionid'].coded_value)]
        ws = create_connection(websocket_url, header=header)
        self.assertTrue(ws.connected)
        result = ws.recv()
        if six.PY3:
            self.message = self.message.decode()
        self.assertEqual(result, self.message)
        ws.close()
        self.assertFalse(ws.connected)

    def test_publish_user(self):
        logged_in = self.client.login(username='******', password='******')
        self.assertTrue(logged_in, 'John is not logged in')
        websocket_url = self.websocket_base_url + u'?publish-user'
        header = ['Cookie: sessionid={0}'.format(self.client.cookies['sessionid'].coded_value)]
        ws = create_connection(websocket_url, header=header)
        self.assertTrue(ws.connected)
        ws.send(self.message)
        ws.close()
        self.assertFalse(ws.connected)
        publisher = RedisPublisher()
        request = self.factory.get('/chat/')
        request.user = User.objects.get(username='******')
        result = publisher.fetch_message(request, self.facility, 'user')
        self.assertEqual(result, self.message)
        request.user = None
        result = publisher.fetch_message(request, self.facility, 'user')
        self.assertEqual(result, None)

    def test_subscribe_group(self):
        logged_in = self.client.login(username='******', password='******')
        self.assertTrue(logged_in, 'John is not logged in')
        request = self.factory.get('/chat/')
        request.user = User.objects.get(username='******')
        audience = {'groups': ['chatters']}
        publisher = RedisPublisher(request=request, facility=self.facility, **audience)
        publisher.publish_message(self.message, 10)
        websocket_url = self.websocket_base_url + u'?subscribe-group'
        header = ['Cookie: sessionid={0}'.format(self.client.cookies['sessionid'].coded_value)]
        ws = create_connection(websocket_url, header=header)
        self.assertTrue(ws.connected)
        result = ws.recv()
        if six.PY3:
            self.message = self.message.decode()
        self.assertEqual(result, self.message)
        ws.close()
        self.assertFalse(ws.connected)

    def test_publish_group(self):
        logged_in = self.client.login(username='******', password='******')
        self.assertTrue(logged_in, 'John is not logged in')
        websocket_url = self.websocket_base_url + u'?publish-group'
        header = ['Cookie: sessionid={0}'.format(self.client.cookies['sessionid'].coded_value)]
        ws = create_connection(websocket_url, header=header)
        self.assertTrue(ws.connected)
        ws.send(self.message)
        ws.close()
        self.assertFalse(ws.connected)
        publisher = RedisPublisher()
        request = self.factory.get('/chat/')
        request.user = User.objects.get(username='******')
        logged_in = self.client.login(username='******', password='******')
        self.assertTrue(logged_in, 'Mary is not logged in')
        request.session = self.client.session
        result = publisher.fetch_message(request, self.facility, 'group')
        self.assertEqual(result, self.message)

    def test_subscribe_session(self):
        logged_in = self.client.login(username='******', password='******')
        self.assertTrue(logged_in, 'John is not logged in')
        self.assertIsInstance(self.client.session, (dict, type(self.session)), 'Did not receive a session key')
        session_key = self.client.session.session_key
        self.assertGreater(len(session_key), 30, 'Session key is too short')
        request = self.factory.get('/chat/')
        request.session = self.client.session
        audience = {'sessions': [SELF]}
        publisher = RedisPublisher(request=request, facility=self.facility, **audience)
        publisher.publish_message(self.message, 10)
        websocket_url = self.websocket_base_url + u'?subscribe-session'
        header = ['Cookie: sessionid={0}'.format(session_key)]
        ws = create_connection(websocket_url, header=header)
        self.assertTrue(ws.connected)
        result = ws.recv()
        if six.PY3:
            self.message = self.message.decode()
        self.assertEqual(result, self.message)
        ws.close()
        self.assertFalse(ws.connected)

    def test_publish_session(self):
        logged_in = self.client.login(username='******', password='******')
        self.assertTrue(logged_in, 'Mary is not logged in')
        self.assertIsInstance(self.client.session, (dict, type(self.session)), 'Did not receive a session key')
        session_key = self.client.session.session_key
        self.assertGreater(len(session_key), 30, 'Session key is too short')
        websocket_url = self.websocket_base_url + u'?publish-session'
        header = ['Cookie: sessionid={0}'.format(session_key)]
        ws = create_connection(websocket_url, header=header)
        self.assertTrue(ws.connected)
        ws.send(self.message)
        ws.close()
        self.assertFalse(ws.connected)
        publisher = RedisPublisher()
        request = self.factory.get('/chat/')
        request.session = self.client.session
        result = publisher.fetch_message(request, self.facility, 'session')
        self.assertEqual(result, self.message)

    def test_invalid_request(self):
        websocket_url = self.live_server_url + u'/ws/foobar'
        response = requests.get(websocket_url)
        self.assertEqual(response.status_code, 400)
        content = response.content
        if six.PY3:
            content = content.decode()
        self.assertIn('upgrade to a websocket', content)
        response = requests.post(websocket_url, {})
        self.assertEqual(response.status_code, 400)

    def t_e_s_t_invalid_version(self):
        # does not work: websocket library overrides Sec-WebSocket-Version
        websocket_url = self.websocket_base_url + u'?publish-broadcast'
        header = ['Sec-WebSocket-Version: 6']  # Version 6 is not supported
        ws = create_connection(websocket_url, header=header)
        self.assertFalse(ws.connected)

    def test_defining_multiple_publishers(self):
        pub1 = RedisPublisher(facility=self.facility, broadcast=True)
        self.assertEqual(pub1._publishers, set([self.prefix + ':broadcast:' + self.facility]))
        pub2 = RedisPublisher(facility=self.facility, users=['john'])
        self.assertEqual(pub2._publishers, set([self.prefix + ':user:john:' + self.facility]))

    def test_forbidden_channel(self):
        websocket_url = self.websocket_base_url + u'?subscribe-broadcast&publish-broadcast'
        try:
            create_connection(websocket_url, header=['Deny-Channels: YES'])
            self.fail('Did not reject channels')
        except WebSocketException:
            self.assertTrue(True)

    def test_close_connection(self):

        class Counter:
            def __init__(self):
                self.value = 0

        counter = Counter()
        old_handle_error = WSGIServer.handle_error

        def handle_error(self, *args, **kwargs):
            # we need a reference to an object for this to work not a simple variable
            counter.value += 1
            return old_handle_error(self, *args, **kwargs)

        WSGIServer.handle_error = handle_error

        statuses = [1000, 1001, 1002, 1003, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1015, ]
        websocket_url = self.websocket_base_url + u'?subscribe-broadcast&publish-broadcast'
        for status in statuses:
            value_before = counter.value
            ws = create_connection(websocket_url)
            self.assertTrue(ws.connected)
            ws.close(status)
            self.assertFalse(ws.connected)
            self.assertEqual(value_before, counter.value,
                             'Connection error while closing with {}'.format(status))

    def test_protocol_support(self):
        protocol = 'unittestprotocol'
        websocket_url = self.websocket_base_url + u'?subscribe-broadcast&publish-broadcast'
        ws = create_connection(websocket_url, subprotocols=[protocol])
        self.assertTrue(ws.connected)
        self.assertIn('sec-websocket-protocol', ws.headers)
        self.assertEqual(protocol, ws.headers['sec-websocket-protocol'])
        ws.close()
        self.assertFalse(ws.connected)