Skip to content

Commit 8ca54ff

Browse files
authored
Merge branch 'master' into master
2 parents 850dcca + e6634c2 commit 8ca54ff

File tree

12 files changed

+96
-26
lines changed

12 files changed

+96
-26
lines changed

docs/changelog.rst

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,32 @@
44
Release History
55
===============
66

7-
0.4.7 develop
8-
-------------
7+
0.5.0
8+
-----
9+
* Support for Django-1.11.
10+
11+
0.4.8
12+
-----
13+
* Support Redis connections over Unix Domain Sockets.
914

15+
0.4.7
16+
-----
1017
Instalation settings:
1118

1219
* Adding support to run websockets in cross domains (setting WEBSOCKET_HOST).
1320

1421
Improvements to the javascript API:
1522

1623
* Performing reconnection attempts when the first connection (on instantiation) fails.
17-
* Adding the 'close()' method to enable closing the connection explicitly. When the connection is closed calling this method, there will be no reconnection attempts. In order to connect again, the client must be re-instantiated.
18-
* Adding 'connecting' and 'disconnected' callback options. The first is fired right before the Websocket is being instantiated, while tha last is fired after connection is closed.
19-
* Adding the following methods to check websocket status: is_connecting(), is_connected(), is_closing(), is_closed().
24+
* Adding the 'close()' method to enable closing the connection explicitly. When the connection is
25+
closed calling this method, there will be no reconnection attempts. In order to connect again,
26+
the client must be re-instantiated.
27+
* Adding 'connecting' and 'disconnected' callback options. The first is fired right before the
28+
Websocket is being instantiated, while tha last is fired after connection is closed.
29+
* Adding the following methods to check websocket status: ``is_connecting()``, ``is_connected()``,
30+
``is_closing()``, ``is_closed()``.
31+
* Replaced ``STATIC_URL`` against ``{% static %}`` in all templates.
32+
* Keep track on opened websockets.
2033

2134
0.4.6
2235
-----

docs/installation.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,15 @@ override these values
8282
8383
.. note:: Specify only the values, which deviate from the default.
8484

85+
If your Redis instance is accessed via a Unix Domain Socket, you can configure that as well:
86+
87+
.. code-block:: python
88+
89+
WS4REDIS_CONNECTION = {
90+
'unix_socket_path': '/tmp/redis.sock',
91+
'db': 5
92+
}
93+
8594
**Websocket for Redis** can be configured with ``WS4REDIS_EXPIRE``, to additionally persist messages
8695
published on the message queue. This is advantageous in situations, where clients shall be able
8796
to access the published information after reconnecting the websocket, for instance after a page

examples/chatserver/settings.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@
9898
# URL that distinguishes websocket connections from normal requests
9999
WEBSOCKET_URL = '/ws/'
100100

101-
# Set the number of seconds each message shall persited
101+
# Set the number of seconds each message shall be persisted
102102
WS4REDIS_EXPIRE = 3600
103103

104104
WS4REDIS_HEARTBEAT = '--heartbeat--'

examples/chatserver/templates/chat_base.html

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{% load static from staticfiles %}
12
{% load tutorial_tags %}
23
<!DOCTYPE html>
34
<html lang="en">
@@ -94,11 +95,11 @@ <h1>Simple chat {% block "title" %}{% endblock %}</h1>
9495
</div>
9596
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js" type="text/javascript"></script>
9697
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js" type="text/javascript"></script>
97-
<script src="{{ STATIC_URL }}js/ws4redis.js" type="text/javascript"></script>
98+
<script src="{% static "js/ws4redis.js" %}" type="text/javascript"></script>
9899
{% block script_panel %}{% endblock %}
99100
<a href="https://github.com/jrief/django-websocket-redis" class="hidden-xs">
100101
<img style="position: absolute; top: 0; right: 0; border: 0; z-index: 1001;" src="https://camo.githubusercontent.com/365986a132ccd6a44c23a9169022c0b5c890c387/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f7265645f6161303030302e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_red_aa0000.png">
101102
</a>
102103
</body>
103104

104-
</html>
105+
</html>

ws4redis/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
# -*- coding: utf-8 -*-
2-
__version__ = '0.4.6'
2+
__version__ = '0.5.0'

ws4redis/_compat.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
def is_authenticated(request):
2+
"""Wrapper for checking when a request is authenticated. This checks first
3+
for a valid request and user, then checks to see if `is_authenticated` is
4+
a callable in order to be compatible with Django 1.10, wherein using a
5+
callable for `is_authenticated` is deprecated in favor of a property.
6+
"""
7+
if not request:
8+
return False
9+
if not request.user:
10+
return False
11+
if callable(request.user.is_authenticated):
12+
return request.user.is_authenticated()
13+
return request.user.is_authenticated

ws4redis/django_runserver.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
import six
33
import base64
44
import select
5+
import logging
56
from hashlib import sha1
67
from wsgiref import util
78
from django.core.wsgi import get_wsgi_application
89
from django.core.servers.basehttp import WSGIServer, WSGIRequestHandler
9-
from django.core.handlers.wsgi import logger
1010
from django.conf import settings
1111
from django.core.management.commands import runserver
1212
from django.utils.six.moves import socketserver
@@ -15,6 +15,7 @@
1515
from ws4redis.wsgi_server import WebsocketWSGIServer, HandshakeError, UpgradeRequiredError
1616

1717
util._hoppish = {}.__contains__
18+
logger = logging.getLogger('django.request')
1819

1920

2021
class WebsocketRunServer(WebsocketWSGIServer):
@@ -63,7 +64,7 @@ def select(self, rlist, wlist, xlist, timeout=None):
6364
return select.select(rlist, wlist, xlist, timeout)
6465

6566

66-
def run(addr, port, wsgi_handler, ipv6=False, threading=False):
67+
def run(addr, port, wsgi_handler, ipv6=False, threading=False, **kwargs):
6768
"""
6869
Function to monkey patch the internal Django command: manage.py runserver
6970
"""

ws4redis/publisher.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,17 @@
22
from redis import ConnectionPool, StrictRedis
33
from ws4redis import settings
44
from ws4redis.redis_store import RedisStore
5+
from ws4redis._compat import is_authenticated
6+
from redis.connection import UnixDomainSocketConnection
57

6-
redis_connection_pool = ConnectionPool(**settings.WS4REDIS_CONNECTION)
7-
8+
if 'unix_socket_path' in settings.WS4REDIS_CONNECTION:
9+
# rename 'unix_socket_path' to 'path' and pass as args
10+
conn_args = dict(settings.WS4REDIS_CONNECTION,
11+
path=settings.WS4REDIS_CONNECTION['unix_socket_path'])
12+
del conn_args['unix_socket_path']
13+
pool = ConnectionPool(connection_class=UnixDomainSocketConnection, **conn_args)
14+
else:
15+
redis_connection_pool = ConnectionPool(**settings.WS4REDIS_CONNECTION)
816

917
class RedisPublisher(RedisStore):
1018
def __init__(self, **kwargs):
@@ -32,11 +40,11 @@ def fetch_message(self, request, facility, audience='any'):
3240
if request and request.session:
3341
channels.append('{prefix}session:{0}:{facility}'.format(request.session.session_key, prefix=prefix, facility=facility))
3442
if audience in ('user', 'any',):
35-
if request and request.user and request.user.is_authenticated():
43+
if is_authenticated(request):
3644
channels.append('{prefix}user:{0}:{facility}'.format(request.user.get_username(), prefix=prefix, facility=facility))
3745
if audience in ('group', 'any',):
3846
try:
39-
if request.user.is_authenticated():
47+
if is_authenticated(request):
4048
groups = request.session['ws4redis:memberof']
4149
channels.extend('{prefix}group:{0}:{facility}'.format(g, prefix=prefix, facility=facility)
4250
for g in groups)

ws4redis/redis_store.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import six
33
import warnings
44
from ws4redis import settings
5+
from ws4redis._compat import is_authenticated
56

67

78
"""
@@ -18,7 +19,7 @@ def _wrap_users(users, request):
1819
"""
1920
result = set()
2021
for u in users:
21-
if u is SELF and request and request.user and request.user.is_authenticated():
22+
if u is SELF and is_authenticated(request):
2223
result.add(request.user.get_username())
2324
else:
2425
result.add(u)
@@ -36,7 +37,7 @@ def _wrap_groups(groups, request):
3637
"""
3738
result = set()
3839
for g in groups:
39-
if g is SELF and request and request.user and request.user.is_authenticated():
40+
if g is SELF and is_authenticated(request):
4041
result.update(request.session.get('ws4redis:memberof', []))
4142
else:
4243
result.add(g)
@@ -70,7 +71,7 @@ def __new__(cls, value):
7071
value = value.encode()
7172
return super(RedisMessage, cls).__new__(cls, value)
7273
elif isinstance(value, bytes):
73-
if value != settings.WS4REDIS_HEARTBEAT.encode():
74+
if settings.WS4REDIS_HEARTBEAT is None or value != settings.WS4REDIS_HEARTBEAT.encode():
7475
return super(RedisMessage, cls).__new__(cls, value)
7576
elif isinstance(value, list):
7677
if len(value) >= 2 and value[0] == b'message':
@@ -129,7 +130,7 @@ def _get_message_channels(self, request=None, facility='{facility}', broadcast=F
129130
# message is delivered to all listed groups
130131
channels.extend('{prefix}group:{0}:{facility}'.format(g, prefix=prefix, facility=facility)
131132
for g in _wrap_groups(groups, request))
132-
elif groups is True and request and request.user and request.user.is_authenticated():
133+
elif groups is True and is_authenticated(request):
133134
# message is delivered to all groups the currently logged in user belongs to
134135
warnings.warn('Wrap groups=True into a list or tuple using SELF', DeprecationWarning)
135136
channels.extend('{prefix}group:{0}:{facility}'.format(g, prefix=prefix, facility=facility)
@@ -146,7 +147,7 @@ def _get_message_channels(self, request=None, facility='{facility}', broadcast=F
146147
# message is delivered to all listed users
147148
channels.extend('{prefix}user:{0}:{facility}'.format(u, prefix=prefix, facility=facility)
148149
for u in _wrap_users(users, request))
149-
elif users is True and request and request.user and request.user.is_authenticated():
150+
elif users is True and is_authenticated(request):
150151
# message is delivered to browser instances of the currently logged in user
151152
warnings.warn('Wrap users=True into a list or tuple using SELF', DeprecationWarning)
152153
channels.append('{prefix}user:{0}:{facility}'.format(request.user.get_username(), prefix=prefix, facility=facility))

ws4redis/subscriber.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def set_pubsub_channels(self, request, channels):
4848
for key in self._get_message_channels(request=request, facility=facility, **audience):
4949
self._subscription.subscribe(key)
5050

51-
def send_persited_messages(self, websocket):
51+
def send_persisted_messages(self, websocket):
5252
"""
5353
This method is called immediately after a websocket is openend by the client, so that
5454
persisted messages can be sent back to the client upon connection.
@@ -58,6 +58,9 @@ def send_persited_messages(self, websocket):
5858
if message:
5959
websocket.send(message)
6060

61+
# for backwards compatibility: remove on major version upgrade (v1)
62+
send_persited_messages = send_persisted_messages
63+
6164
def get_file_descriptor(self):
6265
"""
6366
Returns the file descriptor used for passing to the select call when listening

0 commit comments

Comments
 (0)