]> git.parisson.com Git - telemeta.git/commitdiff
add user authentication, disable admin panel for anonymous users, allow to enable...
authorolivier <>
Sun, 11 Apr 2010 14:41:21 +0000 (14:41 +0000)
committerolivier <>
Sun, 11 Apr 2010 14:41:21 +0000 (14:41 +0000)
INSTALL
telemeta/htdocs/css/telemeta.css
telemeta/locale/fr/LC_MESSAGES/django.mo
telemeta/locale/fr/LC_MESSAGES/django.po
telemeta/templates/telemeta/login.html [new file with mode: 0644]
telemeta/templates/telemeta_default/base.html
telemeta/templates/telemeta_default/login.html [new file with mode: 0644]
telemeta/templates/telemeta_default/mediaitem_detail.html
telemeta/urls.py
telemeta/web/base.py

diff --git a/INSTALL b/INSTALL
index 586842231e8b56517773a088df666c08e764b3f6..b782cc156bfe5ce17c91e325e13bb92bd6894dff 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -123,6 +123,8 @@ Modifiy the following variables:
     :DATABASE_*:        your database settings (don't forget to create the database if needed)
     :MEDIA_ROOT:        absolute path to the media directory you just created
     :INSTALLED_APPS:    add 'telemeta'
+    :TEMPLATE_CONTEXT_PROCESSORS: include 'django.core.context_processors.request' and 
+                                  'django.core.context_processors.auth'
 
 Add the following variables:
 
@@ -131,9 +133,12 @@ Add the following variables:
                             as "Ethnology", etc...
     :TELEMETA_CACHE_DIR:    absolute path to the cache directory that you just created
     :TELEMETA_GMAP_KEY:     your Google Map API key
+    :TELEMETA_DOWNLOAD_ENABLED: True to enable audio data download 
 
-Just paste the two lines below::
+Just paste the lines below::
 
+    LOGIN_URL = '/login'
+    LOGIN_REDIRECT_URL = '/'
     TELEMETA_EXPORT_CACHE_DIR = TELEMETA_CACHE_DIR + "/export"
     CACHE_BACKEND = "file://" + TELEMETA_CACHE_DIR + "/data"
 
index 5a92fb66700b1d8b67d4083a139541d5c19506f3..729100a7e0f4fc0345eb8845c9fc80c09d8e875e 100644 (file)
@@ -199,9 +199,9 @@ input[type=reset][disabled] {
  border-style: solid;\r
  color: #999;\r
 }\r
-input[type=text], input.textwidget, textarea { border: 1px solid #ccc; }\r
-input[type=text], input.textwidget { padding: .25em .1em }\r
-input[type=text]:focus, input.textwidget:focus, textarea:focus {\r
+input[type=text], input[type=password], input.textwidget, textarea { border: 1px solid #ccc; }\r
+input[type=text], input[type=password], input.textwidget { padding: .25em .1em }\r
+input[type=text]:focus, input[type=password]:focus, input.textwidget:focus, textarea:focus {\r
    border-color: #aaa;\r
 }\r
 option { border-bottom: 1px dotted #d7d7d7; }\r
@@ -237,10 +237,12 @@ label.disabled { color: #d7d7d7 }
     margin-top: .3em;\r
     clear: left;\r
 }\r
+\r
 #quick_search a {\r
     font-size: .8em;\r
     font-weight: bold;\r
 }\r
+\r
 #quick_search input {\r
     vertical-align: middle;\r
     font-size: .8em;\r
@@ -255,6 +257,46 @@ label.disabled { color: #d7d7d7 }
     font-weight: bold;\r
 }\r
 \r
+/* Authentication */\r
+#auth_info {\r
+    position: absolute;\r
+    top: 0.2em;\r
+    right: 1.1em;\r
+    margin-right: 12px;\r
+    font-size: .8em;\r
+}\r
+\r
+#auth_info a {\r
+    /* font-weight: bold; */\r
+}\r
+\r
+form.login {\r
+    font-size: 0.8em;\r
+    float: left;\r
+    margin-top: 2em;\r
+    margin-bottom: 4em;\r
+    padding: .5em;\r
+    border: 1px dotted #888;\r
+}\r
+\r
+.login-error {\r
+    color: #BB0000;\r
+}\r
+\r
+form.login label {\r
+    display: block;\r
+    width: 11em;\r
+    float: left;\r
+    clear: left;\r
+    font-weight: bold;\r
+    padding-top: 0.3em;\r
+}\r
+\r
+form.login .submit {\r
+    float: right;\r
+    margin-top: 1em;\r
+}\r
+\r
 /* Search form */\r
 #searchform {\r
     margin: 15px 0;\r
index cad407b5613976b99b3b78f4a4cd39849a843567..0868964df5e72573a17f6cc46ff0650b96321020 100644 (file)
Binary files a/telemeta/locale/fr/LC_MESSAGES/django.mo and b/telemeta/locale/fr/LC_MESSAGES/django.mo differ
index 0833e065cf19f2476cc6f081be723f090b52d5a1..f6e1bb2820189e37c86413cb4b6d7993941939b8 100644 (file)
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-03-08 18:30+0100\n"
+"POT-Creation-Date: 2010-04-11 17:36+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: Olivier Guilyardi <olivier samalyse com>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -426,40 +426,49 @@ msgstr "heure"
 msgid "user"
 msgstr "utilisateur"
 
-#: templates/telemeta_default/base.html:32
+#: templates/telemeta_default/base.html:37
+msgid "Sign out"
+msgstr "Déconnexion"
+
+#: templates/telemeta_default/base.html:39
+#: templates/telemeta_default/login.html:20
+msgid "Sign in"
+msgstr "Connexion"
+
+#: templates/telemeta_default/base.html:46
 #: templates/telemeta_default/search_criteria.html:134
 msgid "Search"
 msgstr "Recherche"
 
-#: templates/telemeta_default/base.html:34
+#: templates/telemeta_default/base.html:48
 msgid "Advanced search"
 msgstr "Recherche avancée"
 
-#: templates/telemeta_default/base.html:41
+#: templates/telemeta_default/base.html:55
 msgid "Collections"
 msgstr "Collections"
 
-#: templates/telemeta_default/base.html:41
+#: templates/telemeta_default/base.html:55
 msgid "Items"
 msgstr "Items"
 
-#: templates/telemeta_default/base.html:41
+#: templates/telemeta_default/base.html:55
 msgid "Geo Navigator"
 msgstr "Géo-Navigateur"
 
-#: templates/telemeta_default/base.html:41
+#: templates/telemeta_default/base.html:55
 msgid "Admin"
 msgstr "Admin"
 
-#: templates/telemeta_default/base.html:61
+#: templates/telemeta_default/base.html:75
 msgid "Powered by"
 msgstr "Propulsé par"
 
-#: templates/telemeta_default/base.html:62
+#: templates/telemeta_default/base.html:76
 msgid "By"
 msgstr "Par"
 
-#: templates/telemeta_default/base.html:66
+#: templates/telemeta_default/base.html:80
 msgid "Visit the Telemeta open source project at"
 msgstr "Visitez le projet libre Telemeta"
 
@@ -468,46 +477,46 @@ msgstr "Visitez le projet libre Telemeta"
 msgid "Collection"
 msgstr "Collection"
 
-#: templates/telemeta_default/collection_detail.html:52
+#: templates/telemeta_default/collection_detail.html:53
 msgid "Recording year"
 msgstr "Année d'enregistrement"
 
-#: templates/telemeta_default/collection_detail.html:61
-#: templates/telemeta_default/mediaitem_detail.html:146
+#: templates/telemeta_default/collection_detail.html:63
+#: templates/telemeta_default/mediaitem_detail.html:148
 msgid "Geographic and cultural informations"
 msgstr "Indications géographiques et culturelles"
 
-#: templates/telemeta_default/collection_detail.html:74
+#: templates/telemeta_default/collection_detail.html:76
 msgid "Legal mentions"
 msgstr "Mentions légales"
 
-#: templates/telemeta_default/collection_detail.html:79
+#: templates/telemeta_default/collection_detail.html:81
 #: templates/telemeta_default/inc/collection_list.html:17
 #: templates/telemeta_default/inc/mediaitem_list.html:16
 msgid "Recordist"
 msgstr "Collecteur"
 
-#: templates/telemeta_default/collection_detail.html:100
-#: templates/telemeta_default/mediaitem_detail.html:211
+#: templates/telemeta_default/collection_detail.html:102
+#: templates/telemeta_default/mediaitem_detail.html:213
 msgid "Archiving data"
 msgstr "Données d'archivage"
 
-#: templates/telemeta_default/collection_detail.html:123
-#: templates/telemeta_default/mediaitem_detail.html:226
+#: templates/telemeta_default/collection_detail.html:125
+#: templates/telemeta_default/mediaitem_detail.html:228
 msgid "Technical data"
 msgstr "Données techniques"
 
-#: templates/telemeta_default/collection_detail.html:128
-#: templates/telemeta_default/mediaitem_detail.html:229
+#: templates/telemeta_default/collection_detail.html:130
+#: templates/telemeta_default/mediaitem_detail.html:231
 msgid "Media type"
 msgstr "Type de media"
 
-#: templates/telemeta_default/collection_detail.html:128
-#: templates/telemeta_default/mediaitem_detail.html:229
+#: templates/telemeta_default/collection_detail.html:130
+#: templates/telemeta_default/mediaitem_detail.html:231
 msgid "Audio"
 msgstr "Audio"
 
-#: templates/telemeta_default/collection_detail.html:133
+#: templates/telemeta_default/collection_detail.html:135
 #: templates/telemeta_default/geo_countries.html:14
 msgid "Number of items"
 msgstr "Nombre d'items"
@@ -628,25 +637,37 @@ msgstr "Accéder au navigateur géographique"
 msgid "Musical selection"
 msgstr "Sélection musicale"
 
+#: templates/telemeta_default/login.html:5
+msgid "User authentication"
+msgstr "Identification"
+
+#: templates/telemeta_default/login.html:8
+msgid "Your username and password didn't match. Please try again."
+msgstr "Vos nom d'utilisateur et/ou mot de passe sont incorrects. Essayez à nouveau."
+
 #: templates/telemeta_default/mediaitem_detail.html:5
 #: templates/telemeta_default/mediaitem_detail_dc.html:5
 msgid "Item"
 msgstr "Item"
 
-#: templates/telemeta_default/mediaitem_detail.html:137
+#: templates/telemeta_default/mediaitem_detail.html:120
+msgid "Download:"
+msgstr "Téléchargement:"
+
+#: templates/telemeta_default/mediaitem_detail.html:139
 msgid "Recording date"
 msgstr "Date d'enregistrement"
 
-#: templates/telemeta_default/mediaitem_detail.html:149
+#: templates/telemeta_default/mediaitem_detail.html:151
 #: templates/telemeta_default/inc/mediaitem_list.html:18
 msgid "Location"
 msgstr "Lieu"
 
-#: templates/telemeta_default/mediaitem_detail.html:164
+#: templates/telemeta_default/mediaitem_detail.html:166
 msgid "Musical informations"
 msgstr "Informations sur la musique"
 
-#: templates/telemeta_default/mediaitem_detail.html:200
+#: templates/telemeta_default/mediaitem_detail.html:202
 msgid "General informations"
 msgstr "Informations générales"
 
diff --git a/telemeta/templates/telemeta/login.html b/telemeta/templates/telemeta/login.html
new file mode 100644 (file)
index 0000000..e6c64d5
--- /dev/null
@@ -0,0 +1 @@
+{% extends "telemeta_default/login.html" %}
index 36ea19518e74ee5b135a24687cbfb2bd35a8148d..034f568b16db51dea0693bf007378b74a5e7da09 100644 (file)
 {% endblock %}
 </div>
 
+<div id="auth_info">
+{% if user.is_authenticated %} 
+{% if user.first_name and user.last_name %}
+{{ user.first_name }} {{ user.last_name }} 
+{% else %}
+{{ user.username }}
+{% endif %}
+|
+<a href="{% url telemeta-logout %}">{% trans "Sign out" %}</a>
+{% else %}
+<a href="{% url telemeta-login %}?next={{ request.path|urlencode }}">{% trans "Sign in" %}</a>
+{% endif %}
+</div>
+
 <div id="quick_search">
 <form action="{% url telemeta-search %}" method="GET">
 <input type="text" id="quick_search_pattern" name="pattern" />
@@ -38,7 +52,7 @@
 {% block menu %}
 <ul>
 {# spaces between li and a elements breaks layout #}
-<li><a href="{% url telemeta-collections %}">{% trans "Collections" %}</a></li><li><a href="{% url telemeta-items %}">{% trans "Items" %}</a></li><li class="first"><a href="{% url telemeta-geo-continents %}">{% trans "Geo Navigator" %}</a></li><li class="last"><a href="{% url telemeta-admin %}">{% trans "Admin" %}</a></li>
+<li><a href="{% url telemeta-collections %}">{% trans "Collections" %}</a></li><li><a href="{% url telemeta-items %}">{% trans "Items" %}</a></li><li {% if not user.is_authenticated %} class="last" {% endif %}><a href="{% url telemeta-geo-continents %}">{% trans "Geo Navigator" %}</a></li>{% if user.is_authenticated %}<li class="last"><a href="{% url telemeta-admin %}">{% trans "Admin" %}</a></li>{% endif %}
 </ul>
 {% endblock %}
 </div>
diff --git a/telemeta/templates/telemeta_default/login.html b/telemeta/templates/telemeta_default/login.html
new file mode 100644 (file)
index 0000000..e408425
--- /dev/null
@@ -0,0 +1,26 @@
+{% extends "telemeta/base.html" %}
+{% load i18n %}
+
+{% block content %}
+<h3>{% trans "User authentication" %}</h3>
+
+{% if form.errors %}
+<p class="login-error">{% trans "Your username and password didn't match. Please try again." %}</p>
+{% endif %}
+
+<form class="login" method="post" action="{% url telemeta-login %}">
+<p>
+{{ form.username.label_tag }}
+{{ form.username }}<br />
+
+{{ form.password.label_tag }}
+{{ form.password }}
+
+</p>
+<input class="submit" type="submit" value="{% trans "Sign in" %}"/>
+<input type="hidden" name="next" value="{{ next }}" />
+</form>
+
+<div class="wazing" />
+
+{% endblock %}
index 1251eb2ffd16227ecbafd2fe2ba7aa5d5867500f..2e3bb841a3ff3481bba30aa302f8d09bc6d2360e 100644 (file)
@@ -115,12 +115,14 @@ load_player({{ item.computed_duration.as_seconds }});
         \r
         </div>\r
 \r
+        {% if audio_export_enabled %}\r
         <div class="exporter">\r
-            <p>Download:\r
+            <p>{% trans "Download:" %}\r
             {% for format in export_formats %}\r
             <a href="{% url telemeta-item-export item.public_id,format.extension %}">{{ format.name }}</a>\r
             {% endfor %}</p>\r
         </div>\r
+        {% endif %}\r
 \r
     </div>\r
 {% endif %}\r
index 3ebe77160be4263a78aafe94bf3c96ca9bfd03a6..336205cd5878d0af612d15189d1ed980b5f540c8 100644 (file)
@@ -169,5 +169,10 @@ urlpatterns = patterns('',
     url(r'^page/(?P<path>.*)$', web_view.render_flatpage, name="telemeta-flatpage"),
 
     # OAI-PMH Data Provider
-    url(r'^oai/.*$', web_view.handle_oai_request, name="telemeta-oai")
+    url(r'^oai/.*$', web_view.handle_oai_request, name="telemeta-oai"),
+
+    # Authentication
+    url(r'^login/$', 'django.contrib.auth.views.login', {'template_name': 'telemeta/login.html'},
+        name="telemeta-login"),
+    url(r'^logout/$', web_view.logout, name="telemeta-logout"),
 )
index 5edff21c80bde4773f94a77a900bed223c66d134..8be7cc9bce0dbdcee44eaa46d044ecef4a1d8de8 100644 (file)
@@ -36,13 +36,15 @@ import re
 import os
 import sys
 
-from django.template import Context, loader
+from django.template import RequestContext, loader
 from django import template
 from django.http import HttpResponse
 from django.http import Http404
 from django.shortcuts import render_to_response, redirect
 from django.views.generic import list_detail
 from django.conf import settings
+from django.contrib import auth
+from django.contrib.auth.decorators import login_required
 
 import telemeta
 from telemeta.models import MediaItem, Location, MediaCollection, EthnicGroup
@@ -60,6 +62,10 @@ from telemeta.web import pages
 import datetime
 from telemeta.util.unaccent import unaccent_icmp
 
+def render(request, template, data = None, mimetype = None):
+    return render_to_response(template, data, context_instance=RequestContext(request), 
+                              mimetype=mimetype) 
+
 class WebView(Component):
     """Provide web UI methods"""
 
@@ -74,13 +80,14 @@ class WebView(Component):
         ids = [id for id in MediaItem.objects.all().values_list('id', flat=True).order_by('?')[0:4]]
         items = MediaItem.objects.enriched().filter(pk__in=ids)
 
-        context = Context({'page_content': pages.get_page_content(request, 'parts/home', ignore_slash_issue=True),
-                           'items': items})
+        context = RequestContext(request, {
+                    'page_content': pages.get_page_content(request, 'parts/home', ignore_slash_issue=True),
+                    'items': items})
         return HttpResponse(template.render(context))
 
     def collection_detail(self, request, public_id, template=''):
         collection = MediaCollection.objects.get(public_id=public_id)
-        return render_to_response(template, {'collection': collection})
+        return render(request, template, {'collection': collection})
 
 
     def item_detail(self, request, public_id, template='telemeta/mediaitem_detail.html'):
@@ -118,10 +125,12 @@ class WebView(Component):
         for plugin in vamp_plugins:
             vamp_plugin_list.append(':'.join(plugin[1:]))
           
-        return render_to_response(template, 
+        return render(request, template, 
                     {'item': item, 'export_formats': formats, 
                     'visualizers': visualizers, 'visualizer_id': visualizer_id,
-                    'analysers': analyzers, 'vamp_plugins': vamp_plugin_list})
+                    'analysers': analyzers, 'vamp_plugins': vamp_plugin_list,
+                    'audio_export_enabled': getattr(settings, 'TELEMETA_DOWNLOAD_ENABLED', False)
+                    })
                     
     def item_visualize(self, request, public_id, visualizer_id, width, height):
         for visualizer in self.visualizers:
@@ -147,6 +156,10 @@ class WebView(Component):
 
     def item_export(self, request, public_id, extension):                    
         """Export a given media item in the specified format (OGG, FLAC, ...)"""
+
+        if extension != 'mp3' and not getattr(settings, 'TELEMETA_DOWNLOAD_ENABLED', False):
+            raise Http404 # FIXME: should be some sort of permissions denied error
+
         for exporter in self.exporters:
             if exporter.get_file_extension() == extension:
                 break
@@ -173,7 +186,7 @@ class WebView(Component):
         rec_years = year_min and year_max and range(year_min, year_max + 1) or []
         year_min, year_max = MediaCollection.objects.all().publishing_year_range()
         pub_years = year_min and year_max and range(year_min, year_max + 1) or []
-        return render_to_response('telemeta/search_criteria.html', {
+        return render(request, 'telemeta/search_criteria.html', {
             'rec_years': rec_years,
             'pub_years': pub_years,
             'ethnic_groups': MediaItem.objects.all().ethnic_groups(),
@@ -284,8 +297,9 @@ class WebView(Component):
     def __get_admin_context_vars(self):
         return {"enumerations": self.__get_enumerations_list()}
 
+    @login_required
     def admin_index(self, request):
-        return render_to_response('telemeta/admin.html', self. __get_admin_context_vars())
+        return render(request, 'telemeta/admin.html', self. __get_admin_context_vars())
 
     def __get_enumeration(self, id):
         from django.db.models import get_models
@@ -299,6 +313,7 @@ class WebView(Component):
 
         return model
 
+    @login_required
     def edit_enumeration(self, request, enumeration_id):        
 
         enumeration  = self.__get_enumeration(enumeration_id)
@@ -309,8 +324,9 @@ class WebView(Component):
         vars["enumeration_id"] = enumeration._meta.module_name
         vars["enumeration_name"] = enumeration._meta.verbose_name            
         vars["enumeration_values"] = enumeration.objects.all()
-        return render_to_response('telemeta/enumeration_edit.html', vars)
+        return render(request, 'telemeta/enumeration_edit.html', vars)
 
+    @login_required
     def add_to_enumeration(self, request, enumeration_id):        
 
         enumeration  = self.__get_enumeration(enumeration_id)
@@ -322,6 +338,7 @@ class WebView(Component):
 
         return self.edit_enumeration(request, enumeration_id)
 
+    @login_required
     def update_enumeration(self, request, enumeration_id):        
         
         enumeration  = self.__get_enumeration(enumeration_id)
@@ -333,6 +350,7 @@ class WebView(Component):
 
         return self.edit_enumeration(request, enumeration_id)
 
+    @login_required
     def edit_enumeration_value(self, request, enumeration_id, value_id):        
 
         enumeration  = self.__get_enumeration(enumeration_id)
@@ -343,8 +361,9 @@ class WebView(Component):
         vars["enumeration_id"] = enumeration._meta.module_name
         vars["enumeration_name"] = enumeration._meta.verbose_name            
         vars["enumeration_record"] = enumeration.objects.get(id__exact=value_id)
-        return render_to_response('telemeta/enumeration_edit_value.html', vars)
+        return render(request, 'telemeta/enumeration_edit_value.html', vars)
 
+    @login_required
     def update_enumeration_value(self, request, enumeration_id, value_id):        
 
         if request.POST.has_key("save"):
@@ -365,7 +384,7 @@ class WebView(Component):
             raise Http404
 
         template = loader.get_template(template)
-        context = Context({'collection': collection, 'host': request.META['HTTP_HOST']})
+        context = RequestContext(request, {'collection': collection, 'host': request.META['HTTP_HOST']})
         return HttpResponse(template.render(context), mimetype=mimetype)
 
     def item_playlist(self, request, public_id, template, mimetype):
@@ -375,24 +394,24 @@ class WebView(Component):
             raise Http404
 
         template = loader.get_template(template)
-        context = Context({'item': item, 'host': request.META['HTTP_HOST']})
+        context = RequestContext(request, {'item': item, 'host': request.META['HTTP_HOST']})
         return HttpResponse(template.render(context), mimetype=mimetype)
 
     def list_continents(self, request):
         continents = MediaItem.objects.all().countries(group_by_continent=True)
-        return render_to_response('telemeta/geo_continents.html', 
+        return render(request, 'telemeta/geo_continents.html', 
                     {'continents': continents, 'gmap_key': settings.TELEMETA_GMAP_KEY })
 
     def country_info(self, request, id):
         country = Location.objects.get(pk=id)
-        return render_to_response('telemeta/country_info.html', {
+        return render(request, 'telemeta/country_info.html', {
             'country': country, 'continent': country.continents()[0]})
 
     def list_countries(self, request, continent):                    
         continent = Location.objects.by_flatname(continent)[0]
         countries = MediaItem.objects.by_location(continent).countries()
 
-        return render_to_response('telemeta/geo_countries.html', {
+        return render(request, 'telemeta/geo_countries.html', {
             'continent': continent,
             'countries': countries
         })
@@ -431,5 +450,8 @@ class WebView(Component):
         if isinstance(content, pages.PageAttachment):
             return HttpResponse(content, content.mimetype())
         else:
-            return render_to_response('telemeta/flatpage.html', {'page_content': content })
-        
+            return render(request, 'telemeta/flatpage.html', {'page_content': content })
+
+    def logout(self, request):
+        auth.logout(request)
+        return redirect('telemeta-home')