1. Nicolás Echániz
  2. django-live

Commits

Nicolás Echániz  committed c9e7349

better channel name handling

  • Participants
  • Parent commits 00aac99
  • Branches default

Comments (0)

Files changed (8)

File demo/demo.db

Binary file modified.

File live/frontend_views.py

View file
         if request.user:
             nickname = request.user.username
         channel = content_object
-        return chat_channel(request, channel.slug, extra_context=req_context)
+        return chat_html(request, channel.slug, extra_context=req_context)
     
 frontend.site.register_view(Channel, ChannelWindow)

File live/locale/es/LC_MESSAGES/django.mo

Binary file modified.

File live/locale/es/LC_MESSAGES/django.po

View file
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2011-03-12 12:53-0300\n"
+"POT-Creation-Date: 2011-03-12 21:25-0300\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
 msgid "password"
 msgstr "clave"
 
-#: models.py:55
+#: models.py:56
 msgid "allow guests"
 msgstr "permitir visitantes"
 
-#: models.py:57
+#: models.py:58
 msgid "save conversation log"
 msgstr "registrar las conversacione"
 
-#: models.py:58
+#: models.py:59
 msgid "pertistant"
 msgstr "persistente"
 
-#: views.py:66
+#: views.py:67
 #, python-format
 msgid ""
 "You are already participating in this chat channel. You can <a href=\"/live/"
 "Ya estás participando de este canal. Puedes <a href=\"/live/kickme/%s"
 "\">cerrar tus sesiones activas</a> y volver a intentarlo."
 
-#: views.py:162
+#: views.py:164
 msgid "You may now try to enter the channel."
 msgstr "Ahora puedes intentar entrar al canal."
 
-#: views.py:179
+#: views.py:181
 msgid "Not allowed"
 msgstr "No permitido"
 
 
 #: templates/live/chat.html:107
 msgid "You have been disconnected"
-msgstr "Ha sido desconectado"
+msgstr "Has sido desconectado"
 
 #: templates/live/chat.html:116
 msgid "has left this channel."
 msgid "Connected as"
 msgstr "Te has conectado como"
 
+#: templates/live/chat.html:267
+msgid "Transport closed (code:"
+msgstr "Conexión terminada (código:"
+
 #: templates/live/chat.html:272
 msgid "type your message here and press ENTER to send"
 msgstr "escribe tu mensaje y presiona ENTER para enviarlo"

File live/templates/live/base.html

View file
 
     #input{
         background-color: #62886a;
-        border: 2px;
+        border: 1px #777 solid;
         width: 70%;
         color: #eeffd0;
         padding: 3px;
     }
 
+    #channel_name{
+        font-size: 16px;
+        float: left;
+        margin-left: 10px;
+        width: 200px;
+    }
+
     #change_name{
         margin-left: auto;
         margin-bottom: 10px;

File live/templates/live/chat.html

View file
             self.output.innerHTML += "<span class='sender'>"+ u +"</span>"+
                 "<span class='message user_message'>&rarr; " + s + "</span><br>"
         }
-        self.output.scrollTop = self.output.scrollHeight     
+        if (chat_scroll){
+            self.output.scrollTop = self.output.scrollHeight
+        }
     }
 
     self.format = function(expr)
 <script>
 
 var current_nickname = '{{ nickname }}'
-var channel_name = '{{ channel_name }}'
+var channel_slug = '{{ channel_slug }}'
 
 var just_entered = true
 var previous_nickname = ''
+var chat_scroll = true
 
 var manager_channel = "{{ manager_channel }}"
-var chat_channel = "{{ channel }}"
 var stomp_port = {{ STOMP_PORT }}
 
 // stomp broker parameters
 var send_headers = {exchange:''}
-var subscribe_destination = chat_channel
+var subscribe_destination = channel_slug
 var send_headers = {exchange:''}
 var subscribe_headers = {exchange:''};
 
 
 var leave = function() {
     var xhr = createXHR()
-    xhr.open('GET', '{% url kickme_from_channel channel_name=channel_name %}', false)
+    xhr.open('GET', '{% url kickme_from_channel channel_slug=channel_slug %}', false)
     xhr.send()
 }
 
     if (!nickname) json_msg = JSON.stringify({'message': {'action': action, 'payload': payload}})
     else json_msg = JSON.stringify({'message': {'action': action, 'payload': payload},
                                     'nickname': nickname,})
-    stomp.send(json_msg, chat_channel, send_headers)
+    stomp.send(json_msg, channel_slug, send_headers)
 }
 
 var user_message = function (msg){
     stomp.onconnectedframe = function() {
         shell.print('{% trans "Connected as"%} ' + current_nickname)
         stomp.subscribe(subscribe_destination, subscribe_headers)
-        manager_message(current_nickname, chat_channel)
+        manager_message(current_nickname, channel_slug)
         // TODO: get initial participants for channel from django through an ajax view
         channel_action('join', '', current_nickname)
         var xhr = createXHR()
-        xhr.open('GET', '{% url channel_participants channel_name=channel_name %}', true)
+        xhr.open('GET', '{% url channel_participants channel_slug=channel_slug %}', true)
         xhr.onreadystatechange = function() {
             if (xhr.readyState==4){
                 participants = JSON.parse(xhr.responseText)
     window.onunload = function(){leave()}
 
     stomp.onclose = function(code) {
-        shell.print('Transport closed (code: ' + code + ')')
+        shell.print(' {% trans "Transport closed (code:" %} ' + code + ')')
 //        stomp.reset()
     }
 
 
 {% block content %}
 <div id="container">
+    <div id="channel_name">{{ channel_name }}</div>
     <div id="change_name">
     {% trans "your name" %}: <input id="nickname" value="{{ nickname  }}" onKeyPress="previous_nickname = current_nickname; if(event.keyCode==13) change_nickname(this.value);"/>
     </div>
       <div id="input_box">
         <input id="input" value="" size="40" 
          onKeyPress="if (just_entered){ this.value=''; just_entered = false}; if(event.keyCode==13) user_message();"/>
+    <label for="chat_scroll">{% trans "auto-scroll" %}</label>
+        <input id="chat_scroll" type="checkbox" checked="checked"
+         onChange="chat_scroll = this.value;"/>
+
       </div>
     </div>
 

File live/urls.py

View file
 urlpatterns = patterns('live.views',
     url(r'^$', 'public', name='index'),
     url(r'^chat/$', 'chat', name='random_chat_channel'),
-    url(r'^chat/(?P<channel_name>[\w\.]+)/$', 'chat',
+    url(r'^chat/(?P<channel_name>[\w\s-]+)/$', 'chat',
         name='named_chat_channel'),
     ## url(r'^chat/(?P<channel_name>[\w\.]+)/(?P<username>\w+)$', 'chat',
     ##     name='named_chat_channel_as_user'),
     url(r'^manage/$', 'manage', name='manage'),
     url(r'^public/$', 'public', name='default_public_channel'),
-    url(r'^public/(?P<channel_name>\w+)$', 'public',
+    url(r'^public/(?P<channel_name>[\w\s-]+)$', 'public',
         name='named_public_channel'),
-    url(r'^kickme/(?P<channel_name>[\w\.]+)/$', 'kickme',
+    url(r'^kickme/(?P<channel_slug>[\w-]+)/$', 'kickme',
         name='kickme_from_channel'),
-    url(r'^participants/(?P<channel_name>\w+)$', 'channel_participants',
+    url(r'^participants/(?P<channel_slug>[\w-]+)$', 'channel_participants',
         name='channel_participants'),                       
     url(r'^restq/$', 'restq', name='restq_init'),
     url(r'^restq/(?P<command>[\w\.]+)/$', 'restq', name='restq_command'),

File live/views.py

View file
 conn.connect()
 ##conn.subscribe(destination='PUBLIC', ack='auto')
 
+# copied from django.templates.defaultfilters
+def slugify(value):
+    """
+    Normalizes string, converts to lowercase, removes non-alpha characters,
+    and converts spaces to hyphens.
+    """
+    import unicodedata, re
+    value = unicode(value)
+    value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore')
+    value = unicode(re.sub('[^\w\s-]', '', value).strip().lower())
+    return re.sub('[-\s]+', '-', value)
+
 
 def json_response(json_data):
     return HttpResponse(json_data, mimetype='application/json')
 def chat_html(request, channel_name=None, nickname=None,
                manager_channel="MANAGE", extra_context=None):
 
-    try:
-        session = Session.objects.get(session_key=request.session.session_key)
-    except:
-        print "no session yet"
-    else:
-        is_subscribed = Channel.objects.filter(participants__session=session, name=channel_name)
-        ## if a user was participating in a channel and joins again
-        ## we show a page to let him kick himself before re-joining
-        if is_subscribed:
-            return HttpResponse(_('You are already participating in this chat channel. You can <a href="/live/kickme/%s">close your active sessions</a> and try again' % channel_name))
+    ## we will be using the slug and not the name so we slugify in case we received
+    ## the name from an arbitrary URL
+    channel_slug = slugify(channel_name)
+    session = Session.objects.get(session_key=request.session.session_key)
+    is_subscribed = Channel.objects.filter(participants__session=session,
+                                           slug=channel_slug)
+
+    ## if a user was participating in a channel and joins again
+    ## we show a page to let him kick himself before re-joining
+    if is_subscribed:
+        return HttpResponse(_('You are already participating in this chat channel. You can <a href="/live/kickme/%s">close your active sessions</a> and try again' % channel_slug))
 
     if not nickname:
         nickname = 'guest' + str(time.time())
-    channel_session = "%s__%s" % (request.session.session_key, channel_name)
+    channel_session = "%s__%s" % (request.session.session_key, channel_slug)
 
     ## we make sure the session gets saved
     request.session.modified = True
                                  {'ORBITED_HOST': s.ORBITED_HOST,
                                   'ORBITED_PORT': s.ORBITED_PORT,
                                   'STOMP_PORT': s.STOMP_PORT,
-                                  'channel': channel_name,
+                                  'channel_name': channel_name,
                                   'manager_channel': manager_channel,
                                   'nickname': nickname,
                                   'username': channel_session,
-                                  'channel_name': channel_name,
+                                  'channel_slug': channel_slug,
                                   })
     if extra_context:
         req_context.update(extra_context)
 
 def _show_chat(request, channel_name=None, nickname=None,
                manager_channel="MANAGE", extra_context=None):
-
+    
     return HttpResponse(chat_html(request, channel_name, nickname,
                                    manager_channel, extra_context))
     
     
-def _get_channel(name):
+def _get_channel(channel_slug):
+    print "get channel", channel_slug
     try:
-        channel = Channel.objects.get(name=name)
+        channel = Channel.objects.get(slug=channel_slug)
     except:
         channel = None
     return channel
 
 
-def _get_or_create_channel(name):
-    if Channel.objects.filter(name=name).exists():
-        channel = Channel.objects.get(name=name)
+def _get_or_create_channel(channel_slug):
+    if Channel.objects.filter(slug=channel_slug).exists():
+        channel = Channel.objects.get(slug=channel_slug)
     else:
-        channel = Channel(name=name)
+        channel = Channel(name=channel_slug)
         channel.save()
     return channel
 
     return _show_chat(request, channel_name, nickname, manager_channel)
 
 
-def kickme(request, channel_name):
+def kickme(request, channel_slug):
     """"Kick the participant/s corresponding to this session (cleanup)"""
 
-    channel = _get_channel(channel_name)
+    channel = _get_channel(channel_slug)
+    print channel_slug
     if channel:
+        print "channel exists", channel
         session = Session.objects.get(session_key=request.session.session_key)
         participants = channel.participants.filter(session=session)
         for participant in participants:
             _leave(participant, channel)
-    import time
     return HttpResponse(_('You may now try to enter the channel.'))
 
 
     return _show_chat(request, channel_name=channel_name, nickname=nickname)
 
 
-def channel_participants(request, channel_name):
+def channel_participants(request, channel_slug):
     """Return a JSON list of current participants for a given channel"""
-    channel = _get_channel(channel_name)
+    channel = _get_channel(channel_slug)
     json_data = []
     if channel:
         participants = channel.participants.all()
     destination = incoming_data.get('destination', None)
     stomp_username = incoming_data.get('username', None)
     
-    ## we "encoded" the session_key and channel_name in the STOMP username
+    ## we "encoded" the session_key and channel_slug in the STOMP username
     ## so here we extract that info in order to determine the real user
     session = None
     user = None
     if stomp_username:
-        session_key, channel_name = stomp_username.split('__')
+        session_key, channel_slug = stomp_username.split('__')
         session = Session.objects.get(session_key=session_key)
         uid = session.get_decoded().get('_auth_user_id')
 
     elif command == "disconnect":
         ## Morbid sends no destination data for disconnect command
         ## so we use the channel_name we got earlier
-        channel = _get_channel(channel_name)
+        channel = _get_channel(channel_slug)
         try:
             participant = channel.participants.get(session=session)
         except:
-            print "no participant for session", session, "on", channel_name
+            print "no participant for session", session, "on", channel_slug
         else:
             print "kickeando", participant
             _leave(participant, channel)