├── CNAME ├── generic ├── models.py ├── __init__.py ├── static │ ├── sass │ │ ├── _mixins.scss │ │ ├── _reset.scss │ │ ├── print.scss │ │ ├── ie.scss │ │ ├── _global.scss │ │ ├── _variables.scss │ │ ├── _form.scss │ │ ├── _grid.scss │ │ ├── _layout.scss │ │ ├── _typo.scss │ │ └── styles.scss │ ├── img │ │ ├── logo.png │ │ ├── expli1.png │ │ ├── expli2.png │ │ ├── expli3.png │ │ ├── expli4.png │ │ ├── favicon.ico │ │ ├── favicon.png │ │ ├── home_1.jpg │ │ ├── home_2.jpg │ │ ├── home_3.jpg │ │ ├── bg-footer.png │ │ ├── error404.png │ │ ├── error500.png │ │ ├── logo-grey.png │ │ ├── home-illustration.jpg │ │ └── bg-home-illustration.jpg │ ├── fonts │ │ ├── museo300-regular-webfont.eot │ │ ├── museo300-regular-webfont.ttf │ │ ├── museo300-regular-webfont.woff │ │ ├── museo700-regular-webfont.eot │ │ ├── museo700-regular-webfont.ttf │ │ ├── museo700-regular-webfont.woff │ │ └── museo700-regular-webfont.svg │ ├── css │ │ ├── print.css │ │ ├── ie.css │ │ ├── styles.css │ │ └── normalize.css │ └── config.rb ├── templates │ ├── registration │ │ ├── activation_email_subject.txt │ │ ├── logout.html │ │ ├── password_change_done.html │ │ ├── registration_complete.html │ │ ├── password_reset_done.html │ │ ├── password_reset_email.html │ │ ├── password_reset_complete.html │ │ ├── password_change_form.html │ │ ├── password_reset_form.html │ │ ├── activation_complete.html │ │ ├── activate.html │ │ ├── password_reset_confirm.html │ │ ├── activation_email.txt │ │ ├── registration_form.html │ │ └── login.html │ ├── 404.html │ ├── 500.html │ ├── dashboard.html │ └── layout.html ├── locale │ └── fr │ │ └── LC_MESSAGES │ │ ├── django.mo │ │ └── django.po ├── views.py └── tests.py ├── pages ├── __init__.py ├── models.py ├── markdown │ ├── .gitkeep │ ├── en │ │ └── mentions-legales.md │ └── fr │ │ └── mentions-legales.md ├── locale │ └── fr │ │ └── LC_MESSAGES │ │ ├── django.mo │ │ └── django.po ├── templates │ ├── mails │ │ ├── admin_suggest.txt │ │ ├── admin_contact.txt │ │ ├── en │ │ │ ├── contact.txt │ │ │ └── suggest.txt │ │ └── fr │ │ │ ├── contact.txt │ │ │ └── suggest.txt │ └── pages │ │ ├── markdown.html │ │ ├── confirm_contact.html │ │ └── contact.html ├── utils.py ├── forms.py ├── views.py └── tests.py ├── uxperiment ├── __init__.py ├── static │ └── .gitkeep ├── settings │ ├── local.py.sample │ ├── test.py │ ├── staging.py │ ├── __init__.py │ ├── production.py │ ├── dev.py │ └── base.py ├── config.rb ├── wsgi.py ├── utils.py └── urls.py ├── websites ├── __init__.py ├── migrations │ ├── __init__.py │ ├── 0001_initial.py │ └── 0002_auto__add_field_website_submitter.py ├── fixtures │ └── green-nature.jpg ├── locale │ └── fr │ │ └── LC_MESSAGES │ │ ├── django.mo │ │ └── django.po ├── admin.py ├── forms.py ├── models.py ├── utils.py ├── templates │ └── websites │ │ ├── suggest.html │ │ └── index.html ├── views.py └── tests.py ├── Procfile ├── .gitignore ├── .travis.yml ├── manage.py ├── requirements.txt ├── requirements-dev.txt └── README.md /CNAME: -------------------------------------------------------------------------------- 1 | prswb.fr 2 | -------------------------------------------------------------------------------- /generic/models.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pages/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pages/models.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /generic/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pages/markdown/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /uxperiment/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /websites/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /uxperiment/static/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /generic/static/sass/_mixins.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /websites/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /uxperiment/settings/local.py.sample: -------------------------------------------------------------------------------- 1 | # Feel free to override the base settings from here 2 | -------------------------------------------------------------------------------- /generic/static/sass/_reset.scss: -------------------------------------------------------------------------------- 1 | @import "reset/utilities"; 2 | 3 | @include global-reset; 4 | -------------------------------------------------------------------------------- /generic/static/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n1k0/prswb/master/generic/static/img/logo.png -------------------------------------------------------------------------------- /generic/static/img/expli1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n1k0/prswb/master/generic/static/img/expli1.png -------------------------------------------------------------------------------- /generic/static/img/expli2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n1k0/prswb/master/generic/static/img/expli2.png -------------------------------------------------------------------------------- /generic/static/img/expli3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n1k0/prswb/master/generic/static/img/expli3.png -------------------------------------------------------------------------------- /generic/static/img/expli4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n1k0/prswb/master/generic/static/img/expli4.png -------------------------------------------------------------------------------- /generic/static/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n1k0/prswb/master/generic/static/img/favicon.ico -------------------------------------------------------------------------------- /generic/static/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n1k0/prswb/master/generic/static/img/favicon.png -------------------------------------------------------------------------------- /generic/static/img/home_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n1k0/prswb/master/generic/static/img/home_1.jpg -------------------------------------------------------------------------------- /generic/static/img/home_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n1k0/prswb/master/generic/static/img/home_2.jpg -------------------------------------------------------------------------------- /generic/static/img/home_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n1k0/prswb/master/generic/static/img/home_3.jpg -------------------------------------------------------------------------------- /generic/static/img/bg-footer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n1k0/prswb/master/generic/static/img/bg-footer.png -------------------------------------------------------------------------------- /generic/static/img/error404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n1k0/prswb/master/generic/static/img/error404.png -------------------------------------------------------------------------------- /generic/static/img/error500.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n1k0/prswb/master/generic/static/img/error500.png -------------------------------------------------------------------------------- /generic/static/img/logo-grey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n1k0/prswb/master/generic/static/img/logo-grey.png -------------------------------------------------------------------------------- /pages/markdown/en/mentions-legales.md: -------------------------------------------------------------------------------- 1 | Legal terms 2 | 3 | Legal terms 4 | =========== 5 | 6 | To be contributed. 7 | -------------------------------------------------------------------------------- /websites/fixtures/green-nature.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n1k0/prswb/master/websites/fixtures/green-nature.jpg -------------------------------------------------------------------------------- /generic/templates/registration/activation_email_subject.txt: -------------------------------------------------------------------------------- 1 | {% load i18n %}{% trans "Your UXperiment membership" %} 2 | -------------------------------------------------------------------------------- /pages/locale/fr/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n1k0/prswb/master/pages/locale/fr/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /pages/templates/mails/admin_suggest.txt: -------------------------------------------------------------------------------- 1 | L'utilisateur : {{ data.username }}, vient de proposer le site {{ data.website }} -------------------------------------------------------------------------------- /generic/locale/fr/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n1k0/prswb/master/generic/locale/fr/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /generic/static/img/home-illustration.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n1k0/prswb/master/generic/static/img/home-illustration.jpg -------------------------------------------------------------------------------- /websites/locale/fr/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n1k0/prswb/master/websites/locale/fr/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: python manage.py migrate;python manage.py collectstatic --noinput;python manage.py run_gunicorn -b 0.0.0.0:$PORT 2 | -------------------------------------------------------------------------------- /pages/templates/mails/admin_contact.txt: -------------------------------------------------------------------------------- 1 | Email : {{ data.sender }} 2 | Sujet : {{ data.subject }} 3 | Message : 4 | {{ data.message }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.sass-cache 3 | /test.db 4 | /dummy.db 5 | /uxperiment/media/* 6 | /uxperiment/settings/local.py 7 | .env 8 | 9 | -------------------------------------------------------------------------------- /generic/static/img/bg-home-illustration.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n1k0/prswb/master/generic/static/img/bg-home-illustration.jpg -------------------------------------------------------------------------------- /generic/static/fonts/museo300-regular-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n1k0/prswb/master/generic/static/fonts/museo300-regular-webfont.eot -------------------------------------------------------------------------------- /generic/static/fonts/museo300-regular-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n1k0/prswb/master/generic/static/fonts/museo300-regular-webfont.ttf -------------------------------------------------------------------------------- /generic/static/fonts/museo300-regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n1k0/prswb/master/generic/static/fonts/museo300-regular-webfont.woff -------------------------------------------------------------------------------- /generic/static/fonts/museo700-regular-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n1k0/prswb/master/generic/static/fonts/museo700-regular-webfont.eot -------------------------------------------------------------------------------- /generic/static/fonts/museo700-regular-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n1k0/prswb/master/generic/static/fonts/museo700-regular-webfont.ttf -------------------------------------------------------------------------------- /generic/static/fonts/museo700-regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n1k0/prswb/master/generic/static/fonts/museo700-regular-webfont.woff -------------------------------------------------------------------------------- /pages/templates/mails/en/contact.txt: -------------------------------------------------------------------------------- 1 | Hello, 2 | 3 | Your comment on www.uxperiment.fr was recieved. 4 | 5 | Thank you for your participation. 6 | 7 | Regards, 8 | 9 | The UXperiment team. -------------------------------------------------------------------------------- /pages/templates/mails/en/suggest.txt: -------------------------------------------------------------------------------- 1 | Hello, 2 | 3 | Your suggested website on www.experiment.fr was recieved. 4 | 5 | Thank you for your participation. 6 | 7 | Regards, 8 | 9 | The UXperiment team -------------------------------------------------------------------------------- /generic/templates/registration/logout.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% load i18n %} 3 | 4 | {% block content %} 5 |
{% trans "You've been succesfully logged out." %}
6 | {% endblock %} 7 | -------------------------------------------------------------------------------- /pages/templates/pages/markdown.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% load i18n %} 3 | 4 | {% block meta_title %}{{ title }}{% endblock %} 5 | 6 | {% block content %} 7 | {{ html|safe }} 8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /pages/templates/mails/fr/contact.txt: -------------------------------------------------------------------------------- 1 | Bonjour, 2 | 3 | Votre commentaire sur le site www.uxperiment.fr a bien été pris en compte. 4 | 5 | Nous vous remercions de votre participation. 6 | 7 | A bientôt, 8 | 9 | L'équipe UXperiment -------------------------------------------------------------------------------- /pages/templates/mails/fr/suggest.txt: -------------------------------------------------------------------------------- 1 | Bonjour, 2 | 3 | Votre proposition de site internet sur le site www.uxperiment.fr a bien été pris en compte. 4 | 5 | Nous vous remercions de votre participation. 6 | 7 | A bientôt, 8 | 9 | L'équipe UXperiment -------------------------------------------------------------------------------- /generic/static/css/print.css: -------------------------------------------------------------------------------- 1 | /* Welcome to Compass. Use this file to define print styles. 2 | * Import this file using the following HTML or equivalent: 3 | * */ 4 | -------------------------------------------------------------------------------- /generic/templates/registration/password_change_done.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% load i18n %} 3 | 4 | {% block content %} 5 |{% trans "Password changed" %}
7 | {% endblock %} 8 | -------------------------------------------------------------------------------- /websites/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | from models import Website 4 | 5 | 6 | class WebsiteAdmin(admin.ModelAdmin): 7 | class Meta: 8 | model = Website 9 | 10 | 11 | admin.site.register(Website, WebsiteAdmin) -------------------------------------------------------------------------------- /generic/static/sass/print.scss: -------------------------------------------------------------------------------- 1 | /* Welcome to Compass. Use this file to define print styles. 2 | * Import this file using the following HTML or equivalent: 3 | * */ 4 | -------------------------------------------------------------------------------- /uxperiment/settings/test.py: -------------------------------------------------------------------------------- 1 | from .base import * 2 | 3 | DATABASES = { 4 | 'default': { 5 | 'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'. 6 | 'NAME': 'test.db', 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 2.7 3 | 4 | env: DJANGO_SETTINGS_MODULE=uxperiment.settings.test 5 | 6 | # command to install depencies 7 | install: pip install -r requirements-dev.txt --use-mirrors 8 | script: python manage.py test generic websites pages 9 | -------------------------------------------------------------------------------- /generic/templates/registration/registration_complete.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% load i18n %} 3 | 4 | {% block content %} 5 |{% trans "You are now registered. Activation email sent." %}
7 | {% endblock %} 8 | -------------------------------------------------------------------------------- /generic/templates/registration/password_reset_done.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% load i18n %} 3 | 4 | {% block content %} 5 |{% trans "Email with password reset instructions has been sent." %}
7 | {% endblock %} 8 | -------------------------------------------------------------------------------- /generic/templates/registration/password_reset_email.html: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% blocktrans %}Reset password at {{ site_name }}{% endblocktrans %}: 3 | {% block reset_link %} 4 | {{ protocol }}://{{ domain }}{% url auth_password_reset_confirm uidb36=uid, token=token %} 5 | {% endblock %} 6 | -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "uxperiment.settings") 7 | 8 | from django.core.management import execute_from_command_line 9 | 10 | execute_from_command_line(sys.argv) 11 | -------------------------------------------------------------------------------- /generic/static/css/ie.css: -------------------------------------------------------------------------------- 1 | /* Welcome to Compass. Use this file to write IE specific override styles. 2 | * Import this file using the following HTML or equivalent: 3 | * */ 6 | -------------------------------------------------------------------------------- /generic/static/sass/ie.scss: -------------------------------------------------------------------------------- 1 | /* Welcome to Compass. Use this file to write IE specific override styles. 2 | * Import this file using the following HTML or equivalent: 3 | * */ 6 | -------------------------------------------------------------------------------- /generic/templates/registration/password_reset_complete.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% load i18n %} 3 | 4 | {% block content %} 5 |{% trans "Password reset successfully" %}
7 | 8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /generic/templates/404.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% load i18n %} 3 | 4 | {% block body_class %}error error404{% endblock %} 5 | 6 | {% block content %} 7 |9 | {% trans "Your registration being complete, you can now" %} 10 | {% trans "log in" %}. 11 |
12 | {% endblock %} 13 | -------------------------------------------------------------------------------- /requirements-dev.txt: -------------------------------------------------------------------------------- 1 | Django==1.4.2 2 | South==0.7.6 3 | Markdown==2.2.0 4 | -e git+git://github.com/vinyll/django-imagefit.git#egg=django-imagefit 5 | beautifulsoup4==4.1.3 6 | django-gravatar==0.1.0 7 | django-registration==0.8 8 | django-debug-toolbar==0.9.4 9 | wsgiref==0.1.2 10 | PIL==1.1.7 11 | requests==0.14.0 12 | #heroku requirements to not add 13 | #dj-database-url==0.2.1 14 | #gunicorn==0.14.6 15 | #psycopg2==2.4.5 16 | -------------------------------------------------------------------------------- /uxperiment/settings/staging.py: -------------------------------------------------------------------------------- 1 | import os 2 | import dj_database_url 3 | 4 | from .base import * 5 | 6 | 7 | INSTALLED_APPS += ( 8 | 'gunicorn', 9 | ) 10 | 11 | DATABASES = {'default': dj_database_url.config(default='postgres://localhost')} 12 | 13 | EMAIL_RECIPIENT = os.environ.get('EMAIL_RECIPIENT') 14 | EMAIL_HOST_USER = os.environ.get('EMAIL_HOST_USER') 15 | EMAIL_HOST_PASSWORD = os.environ.get('EMAIL_HOST_PASSWORD') 16 | -------------------------------------------------------------------------------- /generic/templates/registration/activate.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% load i18n %} 3 | {% load url from future %} 4 | 5 | {% block content %} 6 | {% if account %} 7 |{% trans "Account successfully activated" %}
8 | 9 | {% else %} 10 |{% trans "Account activation failed" %}
11 | {% endif %} 12 | {% endblock %} 13 | -------------------------------------------------------------------------------- /pages/templates/pages/confirm_contact.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% load url from future %} 3 | {% load i18n %} 4 | 5 | {% block content %} 6 |{% trans "Your comment on UXperiment has been received." %}
8 | 9 |{% trans "Thanks for your participation." %}
10 | 11 |{% trans "Cheers," %}
12 | 13 | {% trans "The UXperiment team" %} 14 | {% endblock %} 15 | -------------------------------------------------------------------------------- /generic/templates/registration/password_reset_confirm.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% load i18n %} 3 | 4 | {% block content %} 5 |{% trans "Password reset failed" %}
14 | {% endif %} 15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /generic/static/sass/_global.scss: -------------------------------------------------------------------------------- 1 | /*Floats*/ 2 | .fl { 3 | float: left; 4 | } 5 | .fr { 6 | float: right; 7 | } 8 | 9 | /*Clearing floats*/ 10 | .clear { 11 | clear: both; 12 | display: block; 13 | overflow: hidden; 14 | visibility: hidden; 15 | width: 0; 16 | height: 0; 17 | } 18 | .clearfix:before, 19 | .clearfix:after { 20 | content: ""; 21 | display: table; 22 | } 23 | .clearfix:after { clear: both; } 24 | .clearfix { *zoom:1 } 25 | 26 | ul { 27 | margin: 0 28 | } -------------------------------------------------------------------------------- /uxperiment/settings/__init__.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | UXPERIMENT_ENV = os.environ.get('UXPERIMENT_ENV') 4 | 5 | if UXPERIMENT_ENV == 'dev': 6 | from .dev import * 7 | elif UXPERIMENT_ENV == 'test': 8 | from .test import * 9 | elif UXPERIMENT_ENV == 'staging': 10 | from .staging import * 11 | elif UXPERIMENT_ENV == 'production': 12 | from .production import * 13 | else: 14 | from .base import * 15 | 16 | # local settings 17 | try: 18 | from .local import * 19 | except ImportError: 20 | pass 21 | -------------------------------------------------------------------------------- /generic/views.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from django.conf import settings 4 | from django.http import HttpResponseRedirect 5 | from django.utils.translation import check_for_language 6 | 7 | 8 | def change_language(request, lang): 9 | response = HttpResponseRedirect('/') 10 | if lang and check_for_language(lang): 11 | if hasattr(request, 'session'): 12 | request.session['django_language'] = lang 13 | else: 14 | response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang) 15 | return response 16 | -------------------------------------------------------------------------------- /generic/templates/registration/activation_email.txt: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% load url from future %} 3 | 4 | {% trans "Hey," %} 5 | 6 | {% trans "Thanks for registering with UXperiment." %} 7 | 8 | {% trans "Please click the link below to activate your account:" %} 9 | http://{{ site }}{% url 'registration_activate' activation_key=activation_key %} 10 | 11 | {% blocktrans %}Note: this link will expires in {{ expiration_days }} days.{% endblocktrans %} 12 | 13 | {% trans "Thank you," %} 14 | 15 | -- 16 | {% trans "The UXperiment Team" %} 17 | http://{{ site }} 18 | -------------------------------------------------------------------------------- /pages/utils.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from django.conf import settings 4 | 5 | 6 | def resolve_markdown_path(slug, lang): 7 | """ Retrieves an existing markdown file path from slug and a language code. 8 | Returns None in case no matching file was found. 9 | """ 10 | i18n_filename = os.path.join(settings.MARKDOWN_DIR, lang, '%s.md' % slug) 11 | filename = os.path.join(settings.MARKDOWN_DIR, '%s.md' % slug) 12 | if os.path.isfile(i18n_filename): 13 | return i18n_filename 14 | elif os.path.isfile(filename): 15 | return filename 16 | -------------------------------------------------------------------------------- /uxperiment/settings/production.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from .base import * 4 | 5 | 6 | DATABASES = { 7 | 'default': { 8 | 'ENGINE': 'django.db.backends.postgresql_psycopg2', 9 | 'USER': os.environ.get('UXPERIMENT_POSTGRES_USERNAME', 'postgres'), 10 | 'PASSWORD': os.environ.get('UXPERIMENT_POSTGRES_PASSWORD'), 11 | 'HOST': os.environ.get('UXPERIMENT_POSTGRES_HOST', 'localhost'), 12 | 'PORT': os.environ.get('UXPERIMENT_POSTGRES_PORT', 5432), 13 | } 14 | } 15 | 16 | EMAIL_RECIPIENT = os.environ.get('EMAIL_RECIPIENT') 17 | EMAIL_HOST_USER = os.environ.get('EMAIL_HOST_USER') 18 | EMAIL_HOST_PASSWORD = os.environ.get('EMAIL_HOST_PASSWORD') 19 | -------------------------------------------------------------------------------- /generic/static/sass/_variables.scss: -------------------------------------------------------------------------------- 1 | 2 | // === FONTS === 3 | $default-font-stack: "Open Sans", Arial, sans-serif; //main font 4 | $special-font-stack: "museo_700regular", Arial, sans-serif; //font-face 5 | $special-font-stack-light: "museo_300regular", Arial, sans-serif; //font-face 6 | 7 | // === COLORS === 8 | $secondary-color: #29abe2; //in this case, blue 9 | $links: $secondary-color; //links color 10 | $links-hover : #007; //hover links color 11 | $links-with-bg : #fff; //links with background 12 | $body-color: #4d4d4d; //text color 13 | $title-color: #29abe2; //titles color 14 | $color-for-bg: #fff; //in this case, white 15 | $border: #e6e6e6; 16 | $error: #c1272d; 17 | // === cols === 18 | -------------------------------------------------------------------------------- /generic/templates/registration/registration_form.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% load i18n %} 3 | {% block meta_title %}S'inscrire{% endblock %} 4 | {% block meta_description %}Inscrivez-vous sur le site afin de participer à l'expérience d'UXperiment. Contribuez à l'évolution des sites en partageant votre expérience.{% endblock %} 5 | 6 | {% block content %} 7 |Inscrivez-vous sur le site afin de participer à UXperiment
9 |Contribuez à l'évolution des sites en partageant votre expérience
10 | 15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /generic/templates/registration/login.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% load i18n %} 3 | 4 | {% block content %} 5 |Bonjour / Hello / Ayo / Ola !
7 |Authentifiez vous et venez nous rejoindre !
8 | 14 |{% trans "Forgot password" %}? {% trans "Reset it" %}!
15 |{% trans "Not member" %}? {% trans "Register" %}!
16 | {% endblock %} 17 | -------------------------------------------------------------------------------- /generic/static/sass/_form.scss: -------------------------------------------------------------------------------- 1 | input, textarea { 2 | padding: 4px; 3 | display: inline-block; 4 | width: 560px; 5 | -webkit-border-radius: 0; 6 | -moz-border-radius: 0; 7 | border-radius: 0; 8 | border: 1px solid $border; 9 | vertical-align: top; 10 | &:invalid { 11 | border: 2px solid #ff0000; 12 | } 13 | } 14 | input:focus:required, 15 | textarea:focus:required:invalid { 16 | border: 1px solid #f00; 17 | } 18 | label { 19 | display: inline-block; 20 | width: 150px; 21 | } 22 | input[type="submit"] { 23 | padding: 5px 10px; 24 | margin: 0 0 0 153px; 25 | background: $secondary-color; 26 | color: #fff; 27 | border: none; 28 | width: auto; 29 | } 30 | input[type="file"] { 31 | width: 430px; 32 | } 33 | .errorlist { 34 | margin: 0 0 0 153px; 35 | padding: 0; 36 | li { 37 | list-style-type: none; 38 | color: $error; 39 | } 40 | } 41 | form { 42 | p { 43 | margin: 0 0 10px; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /pages/forms.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | from django import forms 4 | from django.utils.translation import ugettext as _ 5 | 6 | 7 | class ContactForm(forms.Form): 8 | subject = forms.CharField(min_length=3, error_messages={ 9 | 'min_length': _('3 characters minimum required.'), 10 | 'required': _('A subject is required.') 11 | }, widget=forms.TextInput(attrs={'placeholder': _('Subject') + '*'})) 12 | sender = forms.EmailField(error_messages={ 13 | 'invalid': _('A valid email address is required'), 14 | 'required': _('An email is required.') 15 | }, widget=forms.TextInput(attrs={'placeholder': _('Email address' + '*')})) 16 | message = forms.CharField(min_length=8, error_messages={ 17 | 'min_length': _('8 characters minimum required.'), 18 | 'required': _('A message is required.') 19 | }, widget=forms.Textarea(attrs={'placeholder': _('Message') + '*'})) 20 | -------------------------------------------------------------------------------- /generic/static/config.rb: -------------------------------------------------------------------------------- 1 | # Require any additional compass plugins here. 2 | 3 | # Set this to the root of your project when deployed: 4 | http_path = "/" 5 | css_dir = "css" 6 | sass_dir = "sass" 7 | images_dir = "images" 8 | javascripts_dir = "js" 9 | 10 | # You can select your preferred output style here (can be overridden via the command line): 11 | # output_style = :expanded or :nested or :compact or :compressed 12 | 13 | # To enable relative paths to assets via compass helper functions. Uncomment: 14 | # relative_assets = true 15 | 16 | # To disable debugging comments that display the original location of your selectors. Uncomment: 17 | # line_comments = false 18 | 19 | 20 | # If you prefer the indented syntax, you might want to regenerate this 21 | # project again passing --syntax sass, or you can uncomment this: 22 | # preferred_syntax = :sass 23 | # and then run: 24 | # sass-convert -R --from scss --to sass sass scss && rm -rf sass && mv scss sass 25 | -------------------------------------------------------------------------------- /uxperiment/config.rb: -------------------------------------------------------------------------------- 1 | # Require any additional compass plugins here. 2 | 3 | # Set this to the root of your project when deployed: 4 | http_path = "/" 5 | css_dir = "stylesheets" 6 | sass_dir = "sass" 7 | images_dir = "images" 8 | javascripts_dir = "javascripts" 9 | 10 | # You can select your preferred output style here (can be overridden via the command line): 11 | # output_style = :expanded or :nested or :compact or :compressed 12 | 13 | # To enable relative paths to assets via compass helper functions. Uncomment: 14 | # relative_assets = true 15 | 16 | # To disable debugging comments that display the original location of your selectors. Uncomment: 17 | # line_comments = false 18 | 19 | 20 | # If you prefer the indented syntax, you might want to regenerate this 21 | # project again passing --syntax sass, or you can uncomment this: 22 | # preferred_syntax = :sass 23 | # and then run: 24 | # sass-convert -R --from scss --to sass sass scss && rm -rf sass && mv scss sass 25 | -------------------------------------------------------------------------------- /generic/tests.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from django.core.urlresolvers import reverse 4 | from django.test import TransactionTestCase 5 | 6 | from django.contrib.auth.models import User 7 | 8 | 9 | class RegistrationTest(TransactionTestCase): 10 | "Registration tests." 11 | 12 | def test_register(self): 13 | self.assertEquals(User.objects.filter(username='johndoe').count(), 0) 14 | response = self.client.get(reverse('registration_register')) 15 | self.assertEquals(response.status_code, 200) 16 | self.assertTemplateUsed(response, 'registration/registration_form.html') 17 | self.client.post(reverse('registration_register'), { 18 | 'username': 'johndoe', 19 | 'email': 'john@doe.org', 20 | 'password1': 'doepsswd', 21 | 'password2': 'doepsswd', 22 | }, follow=True) 23 | self.assertEquals(response.status_code, 200) 24 | self.assertEquals(User.objects.filter(username='johndoe').count(), 1) 25 | -------------------------------------------------------------------------------- /uxperiment/settings/dev.py: -------------------------------------------------------------------------------- 1 | from .base import * 2 | 3 | # Debug 4 | DEBUG = True 5 | TEMPLATE_DEBUG = DEBUG 6 | 7 | # Installed apps for dev only 8 | INSTALLED_APPS += ( 9 | 'debug_toolbar', 10 | ) 11 | 12 | # Dev only middlewares 13 | MIDDLEWARE_CLASSES += ( 14 | 'debug_toolbar.middleware.DebugToolbarMiddleware', 15 | ) 16 | 17 | # Email 18 | EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' 19 | 20 | # DJT 21 | INTERNAL_IPS = ('127.0.0.1',) 22 | DEBUG_TOOLBAR_CONFIG = {'INTERCEPT_REDIRECTS': False} 23 | DEBUG_TOOLBAR_PANELS = ( 24 | 'debug_toolbar.panels.version.VersionDebugPanel', 25 | 'debug_toolbar.panels.timer.TimerDebugPanel', 26 | 'debug_toolbar.panels.settings_vars.SettingsVarsDebugPanel', 27 | 'debug_toolbar.panels.headers.HeaderDebugPanel', 28 | 'debug_toolbar.panels.request_vars.RequestVarsDebugPanel', 29 | 'debug_toolbar.panels.template.TemplateDebugPanel', 30 | 'debug_toolbar.panels.sql.SQLDebugPanel', 31 | 'debug_toolbar.panels.signals.SignalDebugPanel', 32 | 'debug_toolbar.panels.logger.LoggingPanel', 33 | ) 34 | -------------------------------------------------------------------------------- /uxperiment/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for uxperiment project. 3 | 4 | This module contains the WSGI application used by Django's development server 5 | and any production WSGI deployments. It should expose a module-level variable 6 | named ``application``. Django's ``runserver`` and ``runfcgi`` commands discover 7 | this application via the ``WSGI_APPLICATION`` setting. 8 | 9 | Usually you will have the standard Django WSGI application here, but it also 10 | might make sense to replace the whole Django WSGI application with a custom one 11 | that later delegates to the Django one. For example, you could introduce WSGI 12 | middleware here, or combine a Django application with an application of another 13 | framework. 14 | 15 | """ 16 | import os 17 | 18 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "uxperiment.settings.production") 19 | 20 | # This application object is used by any WSGI server configured to use this 21 | # file. This includes Django's development server, if the WSGI_APPLICATION 22 | # setting points here. 23 | from django.core.wsgi import get_wsgi_application 24 | application = get_wsgi_application() 25 | 26 | # Apply WSGI middleware here. 27 | # from helloworld.wsgi import HelloWorldApplication 28 | # application = HelloWorldApplication(application) 29 | -------------------------------------------------------------------------------- /generic/static/sass/_grid.scss: -------------------------------------------------------------------------------- 1 | /* Choose a grid width, the number of columns and the margin between columns. The result of the following equation has to be an integer, not a fraction: (width - (columns - 1) * col_margin) / columns = N */ 2 | $width: 960px; /* total with of page */ 3 | // $columns: 24; /* number of columns */ 4 | // $col_margin: 0; /* margin between columns */ /* math magic */ 5 | // $col_width: ($width - ($col_margin * ($columns - 1))) / $columns; 6 | // $col_total_width: $col_width + $col_margin; /* create row div */ 7 | // @mixin row() { 8 | // float: left; 9 | // clear: both; 10 | // width: $width; 11 | // } /* create a column div */ 12 | // @mixin col($n: 1) { 13 | // float: left; 14 | // @include span($n); 15 | // } /* make an element span n columns */ 16 | // @mixin span($n: 1) { 17 | // width: ($n * $col_width) + (($n - 1) * $col_margin); 18 | // @if $n == $columns { margin-right: 0; } 19 | // @else { margin-right: $col_margin; } 20 | // } /* the last column in a row needs this */ 21 | // @mixin last() { margin-right: 0; } /* prepend n blank columns */ 22 | // @mixin prepend($n: 1) { margin-left: $col_total_width * $n } /* append n blank columns */ 23 | // @mixin append($n: 1) { margin-right: $col_total_width * $n + $col_margin } -------------------------------------------------------------------------------- /websites/models.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import hashlib 4 | import os 5 | 6 | from django.db import models 7 | from django.utils.translation import ugettext as _ 8 | from django.contrib.auth.models import User 9 | 10 | 11 | def website_upload_to(instance, filename): 12 | return os.path.join("websites", "%s.jpg" % hashlib.sha1(instance.url).hexdigest()) 13 | 14 | class Website(models.Model): 15 | 16 | REQUEST_COMMENT = 'comment' 17 | REQUEST_IMPROVE = 'improve' 18 | REQUEST_DEBUG = 'debug' 19 | 20 | REQUEST_CHOICES = ( 21 | (REQUEST_COMMENT, _(u"Comment")), 22 | (REQUEST_IMPROVE, _(u"Enhancement suggestion")), 23 | (REQUEST_DEBUG, _(u"Problem or bug")), 24 | ) 25 | 26 | submitter = models.ForeignKey(User, null=True) 27 | url = models.URLField(max_length=255, unique=True) 28 | title = models.CharField(max_length=255) 29 | description = models.CharField(max_length=255, null=True) 30 | picture = models.ImageField(upload_to=website_upload_to, null=True, blank=True) 31 | request_type = models.CharField(max_length=30, choices=REQUEST_CHOICES) 32 | date = models.DateTimeField(auto_now_add=True) 33 | 34 | def __unicode__(self): 35 | return unicode(self.title) 36 | 37 | class Meta: 38 | ordering = ('-date',) 39 | -------------------------------------------------------------------------------- /generic/static/sass/_layout.scss: -------------------------------------------------------------------------------- 1 | .container { 2 | margin: 0 auto; 3 | width: $width; 4 | } 5 | header { 6 | margin: 0 0 20px; 7 | border-top: 3px solid $secondary-color; 8 | .header-block { 9 | position: relative; 10 | } 11 | nav { 12 | margin: 40px 0 0; 13 | } 14 | } 15 | .main-container { 16 | margin-bottom: 70px; 17 | } 18 | footer { 19 | background: #f2f2f2; 20 | .footer-block { 21 | padding: 30px 0 20px; 22 | border-top: 1px solid #e6e6e6; 23 | background: url(../img/bg-footer.png) right 23px no-repeat; 24 | nav { 25 | margin: 5px 40px 0 0; 26 | } 27 | } 28 | } 29 | 30 | .col3 { 31 | margin: 0 50px 70px 0; 32 | width: 270px; 33 | img { 34 | padding: 10px; 35 | margin: 0 0 10px; 36 | border: 1px solid #e6e6e6; 37 | } 38 | &:last-child { 39 | margin: 0; 40 | } 41 | h2 { 42 | text-align: center; 43 | font-size: 18px; 44 | } 45 | } 46 | .col4 { 47 | margin: 0 20px 0 0; 48 | width: 220px; 49 | text-align: center; 50 | &:last-child { 51 | margin: 0; 52 | } 53 | img { 54 | margin: 0 0 25px; 55 | } 56 | h3 { 57 | margin: 0; 58 | font-family: $special-font-stack; 59 | font-size: 17px; 60 | line-height: 20px; 61 | span { 62 | display: block; 63 | font-family: $default-font-stack; 64 | font-size: 14px; 65 | color: #999; 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /uxperiment/utils.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | from django.core.mail import send_mass_mail 3 | from django.conf import settings 4 | from django.template.loader import get_template 5 | from django.utils.translation import get_language, ugettext as _ 6 | 7 | 8 | from django.template import Context 9 | 10 | 11 | def send_message(confirm, data): 12 | send_mass_mail((build_user_email(confirm, data['sender']), 13 | build_admin_email(confirm, data))) 14 | 15 | 16 | def build_user_email(confirm, recipient): 17 | """ Build user message in form of send_mail """ 18 | subjects = ( 19 | ('suggest', _("Confirmation de votre proposition sur UXperiment")), 20 | ('contact', _("Commentaire sur UXperiment")), 21 | ('signin', _("Confirmation d'inscription sur UXperiment")), 22 | ) 23 | subject = dict(subjects).get(confirm) 24 | lang = get_language()[0:2] 25 | message = get_template('mails/%s/%s.txt' % (lang, confirm))\ 26 | .render(Context()) 27 | 28 | return subject, message, settings.EMAIL_HOST_USER, [recipient] 29 | 30 | 31 | def build_admin_email(confirm, data): 32 | """ Build admin message in form of send_mail """ 33 | subjects = ( 34 | ('suggest', _("Nouvelle proposition de site sur UXperiment")), 35 | ('contact', _("Nouveau contact sur UXperiment")), 36 | ) 37 | subject = dict(subjects).get(confirm) 38 | message = get_template('mails/admin_%s.txt' % confirm).render(Context(dict( 39 | data=data 40 | ))) 41 | return subject, message, settings.EMAIL_HOST_USER, [settings.EMAIL_RECIPIENT] 42 | -------------------------------------------------------------------------------- /pages/templates/pages/contact.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% load i18n %} 3 | {% load url from future %} 4 | {% block meta_title %}{% trans "Contact" %}{% endblock %} 5 | {% block meta_description %} 6 | {% trans "UXperiment is a collaborative platform. We're listening your remerks to make to service better. Don't hesitate to contact us, event you just want to say hello ;)" %} 7 | {% endblock %} 8 | 9 | {% block content %} 10 |12 | {% trans "UXperiment is a mariage between websites & their user experience. Here, you are the user." %} 13 |
14 |15 | {% trans "We're open to any remark, suggestion, contact enquiry, collaboration & beer offering." %} 16 | {% trans "For the last kind of request, note we're always ready to sacrifice for the common good." %} 17 |
18 |19 | {% trans "For other cases, we'll be happy to provide you with an appropriate answer anyway." %} 20 |
21 | 36 | {% endblock %} 37 | -------------------------------------------------------------------------------- /websites/utils.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from django.forms import URLField 4 | from django.utils.translation import ugettext as _ 5 | 6 | from models import Website 7 | 8 | from bs4 import BeautifulSoup 9 | import requests 10 | 11 | import re 12 | 13 | 14 | def get_url_informations(url): 15 | """Get informations about a url""" 16 | 17 | error_invalid = False, {'error': _(u'Invalid URL')} 18 | error_exist = False, {'error': _(u'This URL has already been submitted')} 19 | error_connect = False, {'error': _(u'Failed at opening the URL')} 20 | 21 | # Check url is valid 22 | try: 23 | url_field = URLField() 24 | clean_url = url_field.clean(url) 25 | except: 26 | return error_invalid 27 | 28 | # Check url exist 29 | if exist_url(clean_url): 30 | return error_exist 31 | 32 | # Get informations 33 | req = requests.get(clean_url) 34 | if req.status_code == 200: 35 | final_url = req.url 36 | soup = BeautifulSoup(req.text) 37 | title = soup.title.string 38 | description = soup.findAll('meta', 39 | attrs={'name': re.compile("^description$", re.I)})[0].get('content') 40 | else: 41 | return error_connect 42 | 43 | # Check final url exist if different from clean url 44 | if final_url != clean_url: 45 | if exist_url(final_url): 46 | return error_exist 47 | 48 | return True, { 49 | 'url': final_url, 50 | 'title': title, 51 | 'description': description, 52 | } 53 | 54 | 55 | def exist_url(url): 56 | """Check url exist""" 57 | return Website.objects.filter(url__exact=url).exists() 58 | -------------------------------------------------------------------------------- /websites/templates/websites/suggest.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% load i18n %} 3 | {% block meta_title %}{% trans "Suggest a website" %}{% endblock %} 4 | {% block meta_description %}{% trans "Suggest a site to the community to share your experience on this website." %} {% trans "How? Leave a comment to tell us what you think, point out issues you would met on the website and propose new features or enhancements to improve user experience on it." %}{% endblock %} 5 | 6 | {% block content %} 7 |{% trans "Suggest a site to the community to share your experience on this website." %}
9 |{% trans "How? Leave a comment to tell us what you think, point out issues you would met on the website and propose new features or enhancements to improve user experience on it." %}
10 | {% if errors %} 11 |{% trans "Please correct the errors highlighted below." %}
12 | {% endif %} 13 | 33 | {% endblock %} 34 | -------------------------------------------------------------------------------- /generic/static/sass/_typo.scss: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'museo_300regular'; 3 | src: url('../fonts/museo300-regular-webfont.eot'); 4 | src: url('../fonts/museo300-regular-webfont.eot?#iefix') format('embedded-opentype'), 5 | url('../fonts/museo300-regular-webfont.woff') format('woff'), 6 | url('../fonts/museo300-regular-webfont.ttf') format('truetype'), 7 | url('../fonts/museo300-regular-webfont.svg#museo_300regular') format('svg'); 8 | font-weight: normal; 9 | font-style: normal; 10 | } 11 | 12 | @font-face { 13 | font-family: 'museo_700regular'; 14 | src: url('../fonts/museo700-regular-webfont.eot'); 15 | src: url('../fonts/museo700-regular-webfont.eot?#iefix') format('embedded-opentype'), 16 | url('../fonts/museo700-regular-webfont.woff') format('woff'), 17 | url('../fonts/museo700-regular-webfont.ttf') format('truetype'), 18 | url('../fonts/museo700-regular-webfont.svg#museo_700regular') format('svg'); 19 | font-weight: normal; 20 | font-style: normal; 21 | } 22 | 23 | html { 24 | font-size: 100%; 25 | } 26 | body { 27 | font-family: $default-font-stack; 28 | font-size: 0.813em; 29 | font-weight: 400; 30 | // line-height: 1.06em; 31 | color: $body-color; 32 | } 33 | 34 | h1 { 35 | margin: 0 0 0.972em; 36 | font-weight: 300; 37 | font-size: 2.250em ; 38 | span { 39 | font-weight: 800; 40 | } 41 | } 42 | h2 { 43 | margin: 0 0 0.682em; 44 | font-weight: 600; 45 | font-size: 1.375em; 46 | } 47 | h3 { 48 | margin: 0 0 1.250em; 49 | font-weight: 600; 50 | font-size: 1em; 51 | } 52 | a { 53 | color: $body-color; 54 | text-decoration: underline; 55 | &:hover { color: $links;} 56 | } 57 | 58 | nav { 59 | font-size: 1em; 60 | } 61 | input { 62 | font-size: 0.938em; 63 | } 64 | .chapo { 65 | font-style: italic; 66 | } -------------------------------------------------------------------------------- /websites/templates/websites/index.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% load gravatar i18n %} 3 | {% load imagefit %} 4 | {% block meta_title %}{% trans "Suggested websites" %}{% endblock %} 5 | {% block meta_description %}{% trans "Discover suggested websites and contribute to tests 6 | on these sites by sharing your experience." %}{% endblock %} 7 | 8 | {% block content %} 9 |{% trans "Suggest a site to the community to share your experience on this website." %}
11 |{% trans "How? Leave a comment to tell us what you think, point out issues you would met on the website and propose new features or enhancements to improve user experience on it." %}
12 | {% if websites %} 13 |
18 | {% trans "submitted on" %} {{ website.date|date:"d F Y" }}
19 | {% if website.submitter %}
20 | {% trans "by" %} {{ website.submitter.username }}
21 | {% endif %}
22 |
{% trans "No suggested website yet." %}
32 |{% trans "Suggest a website" %}
33 | {% endif %} 34 | {% endblock %} 35 | -------------------------------------------------------------------------------- /pages/views.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | import codecs 4 | import markdown 5 | 6 | from django.contrib import messages 7 | from django.http import Http404 8 | from django.shortcuts import render, redirect 9 | from django.utils.translation import get_language, ugettext as _ 10 | from django.views.decorators.csrf import csrf_protect 11 | 12 | from uxperiment.utils import send_message 13 | 14 | from pages.forms import ContactForm 15 | from utils import resolve_markdown_path 16 | 17 | 18 | def dashboard(request): 19 | return render(request, 'dashboard.html') 20 | 21 | 22 | @csrf_protect 23 | def contact(request): 24 | """ Contact form 25 | Display and proceed contact form submission 26 | """ 27 | form = ContactForm(request.POST or None) 28 | if form.is_valid(): 29 | send_message('contact', form.cleaned_data) 30 | return redirect('confirm_contact') 31 | 32 | return render(request, 'pages/contact.html', {'form': form}) 33 | 34 | 35 | def confirm_contact(request): 36 | """ Contact form confirmation """ 37 | return render(request, 'pages/confirm_contact.html') 38 | 39 | 40 | def markdown_page(request, slug): 41 | """ 42 | Computes markdown file path, converts its contents to html and renders it. 43 | Otherwise, if the file doesn't exist, the view returns a 404. 44 | """ 45 | filename = resolve_markdown_path(slug, get_language()) 46 | if not filename: 47 | raise Http404 48 | try: 49 | input_file = codecs.open(filename, mode="r", encoding="utf-8") 50 | content = input_file.readlines() 51 | except IOError: 52 | # TODO: Shouldn't we log these kinds of errors? 53 | messages.error(request, _(u"Unable to render page, sorry.")) 54 | finally: 55 | input_file.close() 56 | return render(request, 'pages/markdown.html', { 57 | 'html': markdown.markdown("\n".join(content[2:])), 58 | 'title': content[0].replace("\n", ''), 59 | }) 60 | -------------------------------------------------------------------------------- /websites/views.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import json 4 | 5 | from django.contrib import messages 6 | from django.contrib.auth.decorators import login_required 7 | from django.http import HttpResponse, Http404 8 | from django.shortcuts import render, redirect 9 | from django.utils.translation import ugettext as _ 10 | 11 | from websites.utils import get_url_informations 12 | from websites.forms import SuggestForm 13 | from models import Website 14 | from uxperiment.utils import send_message 15 | 16 | 17 | def index(request): 18 | """ Websites index. 19 | """ 20 | return render(request, 'websites/index.html', { 21 | 'websites': Website.objects.all(), 22 | }) 23 | 24 | 25 | @login_required 26 | def suggest(request): 27 | """ Suggest form 28 | Display and proceed suggest a website form submission 29 | """ 30 | form = SuggestForm( 31 | request.POST or None, 32 | request.FILES or None, 33 | initial=dict(url='http://') 34 | ) 35 | 36 | if form.is_valid(): 37 | website = form.save(commit=False) 38 | website.submitter = request.user 39 | website.save() 40 | send_message('suggest', { 41 | 'website': website.url, 42 | 'username': request.user.username, 43 | 'sender': request.user.email 44 | }) 45 | messages.success(request, _('Thanks for your proposition.')) 46 | return redirect('websites_index') 47 | 48 | return render(request, 'websites/suggest.html', {'form': form}) 49 | 50 | 51 | def informations(request): 52 | """ Get informations about a website. 53 | """ 54 | if not request.is_ajax(): 55 | raise Http404("This view should be called in ajax") 56 | success = False 57 | status = 400 58 | infos = {'error': _(u'Invalid request')} 59 | url = request.GET.get('url', False) 60 | if url: 61 | success, infos = get_url_informations(url) 62 | status = 200 if success else 409 63 | return HttpResponse(json.dumps(infos), 64 | content_type="application/json", status=status) 65 | -------------------------------------------------------------------------------- /websites/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import datetime 3 | from south.db import db 4 | from south.v2 import SchemaMigration 5 | from django.db import models 6 | 7 | 8 | class Migration(SchemaMigration): 9 | 10 | def forwards(self, orm): 11 | # Adding model 'Website' 12 | db.create_table('websites_website', ( 13 | ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), 14 | ('url', self.gf('django.db.models.fields.URLField')(unique=True, max_length=255)), 15 | ('title', self.gf('django.db.models.fields.CharField')(max_length=255)), 16 | ('description', self.gf('django.db.models.fields.CharField')(max_length=255, null=True)), 17 | ('picture', self.gf('django.db.models.fields.files.ImageField')(max_length=100, null=True)), 18 | ('request_type', self.gf('django.db.models.fields.CharField')(max_length=30)), 19 | ('date', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), 20 | )) 21 | db.send_create_signal('websites', ['Website']) 22 | 23 | 24 | def backwards(self, orm): 25 | # Deleting model 'Website' 26 | db.delete_table('websites_website') 27 | 28 | 29 | models = { 30 | 'websites.website': { 31 | 'Meta': {'object_name': 'Website'}, 32 | 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), 33 | 'description': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}), 34 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 35 | 'picture': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True'}), 36 | 'request_type': ('django.db.models.fields.CharField', [], {'max_length': '30'}), 37 | 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}), 38 | 'url': ('django.db.models.fields.URLField', [], {'unique': 'True', 'max_length': '255'}) 39 | } 40 | } 41 | 42 | complete_apps = ['websites'] -------------------------------------------------------------------------------- /uxperiment/urls.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from django.conf.urls import patterns, include, url 4 | from django.conf import settings 5 | from django.conf.urls.i18n import i18n_patterns 6 | from django.contrib import admin 7 | from django import views as django_views 8 | 9 | from generic import views as generic_views 10 | from pages import views as pages_views 11 | from websites import views as websites_views 12 | from registration.backends.default import urls as registration_urls 13 | from imagefit import urls as imagefit_urls 14 | 15 | admin.autodiscover() 16 | 17 | urlpatterns = i18n_patterns('', 18 | url(r'^$', pages_views.dashboard, 19 | name='homepage'), 20 | url(r'^i18n/(?P
20 | {% trans "This original project intends to let users discuss and share their experience about websites" %}
22 |
25 | 27 | {% trans "Once registered, submit a website and tell the world how you've experienced it, and how it could be enhanced." %} 28 | {% trans "Other users then may engage a discussion about it." %} 29 |
30 |
33 | {% trans "Search for already reviewed websites, add your comments & experience, suggest enhancements and report problems." %}
35 |
42 |
49 |
56 |
63 |
25 |
26 |
27 | Les serveurs du site www.uxperiment.fr sont hébergés en France par OVH. 7 | OVH, SAS au capital de 500 000€ 8 | RCS Roubaix – Tourcoing 424 761 419 00011 9 | Code APE 6202A 10 | N° TVA : FR 22 424 761 419 11 | Siège social : 2 rue Kellermann - 59100 Roubaix - France.
12 | 13 |Le site web www.uxperiment.fr fait l'objet d'une déclaration à la CNIL (Commission Nationale de l'Informatique et des Libertés) sous le numéro 1619285.
16 | 17 |Conformément à la loi n° 78-17 du 6 janvier 1978 modifiée, relative à l'informatique, aux fichiers et aux libertés, vous disposez d'un droit d'accès, de modification, de rectification et de suppression, pour toute information vous concernant en vous adressant à :
Martinez Amanda 20 | 41 rue du chasselas 21 | 34980 St Gély du fesc 22 | Email : contact@uxperiment.fr
23 | 24 |Afin de faciliter l’utilisation des informations, l’utilisateur est informé que UXperiment utilise des cookies. Tout utilisateur a la faculté de s’y opposer en désactivant l’option dans les paramètres de son terminal prévu à cet effet.
25 | 26 |UXperiment peut être amené à implanter un cookie dans l’ordinateur de l’utilisateur. Un cookie ne permet pas à UXperiment de l’identifier ; en revanche, il enregistre des informations relatives à la navigation de l’ordinateur de l’utilisateur sur le site www.uxperiment.fr (les pages que l’utilisateur a consultées, la date et l'heure de la consultation, etc.) que UXperiment pourra lire lors des visites ultérieures de l’utilisateur. La durée de conservation de ces informations dans l’ordinateur de l’utilisateur est de 1(un) an. 29 | UXperiment informe l’utilisateur qu’il peut s’opposer à l'enregistrement de "cookies" en configurant son navigateur de la manière suivante :
Pour Mozilla firefox : 32 | Choisissez le menu "outil " puis "Options" 33 | Cliquez sur l'icône "vie privée" 34 | Repérez le menu "cookie" et sélectionnez les options qui vous conviennent. 35 | Pour Microsoft Internet Explorer 6.0 : 36 | Choisissez le menu "Outils" (ou "Tools"), puis "Options Internet" (ou "Internet Options"). 37 | Cliquez sur l'onglet "Confidentialité" (ou "Confidentiality") 38 | Sélectionnez le niveau souhaité à l'aide du curseur. 39 | Pour Microsoft Internet Explorer 5 : 40 | Choisissez le menu "Outils" (ou "Tools"), puis "Options Internet" (ou "Internet Options"). 41 | Cliquez sur l'onglet "Sécurité" (ou "Security") 42 | Sélectionnez "Internet" puis "Personnaliser le niveau" (ou "CustomLevel") 43 | Repérez la rubrique "cookies" et choisissez l'option qui vous convient. 44 | Pour Netscape 6.X et 7. X : 45 | Choisissez le menu "Edition">"Préférences" 46 | Confidentialité et Sécurité 47 | Cookies. 48 | Pour Opéra 6.0 et au-delà : 49 | Choisissez le menu "Fichier">"Préférences" 50 | Vie Privée.
51 | 52 |Les informations, fournies par UXperiment sur le site www.uxperiment.fr, le sont à titre indicatif. UXperiment ne saurait garantir l'exactitude, la complétude, l'actualité des informations diffusées sur son site. 55 | En conséquence, l'utilisateur reconnaît utiliser ces informations sous sa responsabilité exclusive. UXperiment met tout en œuvre pour offrir aux utilisateurs des informations et/ou des outils disponibles et vérifiés, mais ne saurait être tenu pour responsable des erreurs, d'une absence de disponibilité des informations et/ou de la présence d'un virus sur son site.
56 | 57 |L'accès à la contribution nécessite la création d'un compte, accessible au moyen d'un login et d'un mot de passe. Afin de créer ce compte, l’internaute doit remplir un formulaire en renseignant un certain nombre de champs obligatoires (mot de passe, adresse e‐mail valide, ...). L'accès est subordonné à la transmission de l'ensemble des informations demandées, notamment une adresse email valide, qui permet l'échange d'informations liées au site.
60 | 61 |Le client est seul responsable de la confidentialité et de l'utilisation de ses identifiants (login et mot de passe de son compte). Il est également seul responsable de toute connexion au site ou transmission de données effectuées en utilisant son compte et qui seront réputées avoir été effectuées par le client lui‐même ou sous sa responsabilité, notamment si le client prend le risque de pré‐enregistrer ses identifiants sur son ordinateur, permettant ainsi la connexion automatique au site via son compte. Le compte du client peut être résilié en cas d’utilisation non conforme aux présentes et ce, quelque soit la personne l’ayant utilisé. Le client s'engage à ne pas révéler ses identifiants à un tiers.
64 | 65 |Nous autorisons l'audience du site l'utilisation de l'ensemble des informations présentes sur ce site au téléchargement, reproduction, impression sous réserve de : 68 | 69 | - n’utiliser de telles informations qu’à des fins personnelles et en aucune manière à des fins commerciales 70 | 71 | - ne pas modifier de telles informations
72 | 73 |L'administrateur se réserve le droit de supprimer tout contenu illicite, de suspendre l’accès aux outils communautaires de tout client agissant en violation des présentes. En sa qualité d’auteur potentiel, le client est informé qu’il est susceptible de voir sa responsabilité tant civile que pénale engagée pour les contenus publiés sous sa responsabilité sur le site. 76 | 77 | En sa qualité d’hébergeur de données, l'administrateur fera ses meilleurs efforts pour retirer, dès la connaissance de son caractère manifestement illicite (texte diffamatoire, fichier contrefaisant…), toute donnée présente sur le site et conserve, conformément aux obligations légales, toute information de nature à permettre l’identification de l’auteur incriminé. 78 | 79 | En tout état de cause, les clients sont invités à signaler tout contenu ou fichier susceptible de présenter un caractère illicite au support client du site à l'adresse mail suivante : contact@uxperiment.fr.
80 | 81 |Le client choisit librement de procéder à une publication de ses contributions sur le site. Il déclare disposer de tous les droits afférents à ces contributions et garantit à ce titre l'administrateur contre tout recours éventuel de tiers. 84 | 85 | En choisissant de procéder à une publication, le client permet de mettre gracieusement la contribution concernée à disposition des internautes via le site et cède expressément à www.uxperiment.fr tous droits de propriété intellectuelle nécessaires à une telle publication, notamment le droit de reproduction, de représentation, pour le monde entier et pour la durée des droits attachés aux contributions publiées.
86 | 87 |L’ensemble des informations accessibles via ce site sont fournies en l’état. 90 | UXperiment ne donne aucune garantie, explicite ou implicite, et n’assume aucune responsabilité relative à l’utilisation de ces informations. 91 | 92 | UXperiment n’est responsable ni de l’exactitude, ni des erreurs, ni des omissions contenues sur ce site. 93 | 94 | L’utilisateur est seul responsable de l’utilisation de telles informations. 95 | 96 | UXperiment se réserve le droit de modifier à tout moment les présentes notamment en actualisant ce site. 97 | 98 | UXperiment ne pourra être responsable pour quel que dommage que ce soit tant direct qu’indirect, résultant d’une information contenue sur ce site. 99 | 100 | UXperiment ne peut être tenu responsable des problèmes liés à la bonne consultation de ce site ainsi que les dégâts causés par virus, hacking, piratage ou toute utilisation malveillante du réseau Internet. 101 | 102 | Pour toute remarque sur le fonctionnement du site, vous pouvez envoyer un mail à contact@uxperiment.fr.
103 | 104 |Les liens hypertextes mis en place dans le cadre du site www.uxperiment.fr en direction d'autres ressources présentes sur le réseau Internet ont fait l'objet d'une autorisation préalable, expresse et écrite. 107 | En activant un lien hypertexte, l'internaute reconnaît qu'il change de site et que des lors, l'ensemble des informations disponible sur le site auxquels il a accès ne relève plus des conditions générales d’utilisation.
108 | -------------------------------------------------------------------------------- /generic/static/css/styles.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'museo_300regular'; 3 | src: url("../fonts/museo300-regular-webfont.eot"); 4 | src: url("../fonts/museo300-regular-webfont.eot?#iefix") format("embedded-opentype"), url("../fonts/museo300-regular-webfont.woff") format("woff"), url("../fonts/museo300-regular-webfont.ttf") format("truetype"), url("../fonts/museo300-regular-webfont.svg#museo_300regular") format("svg"); 5 | font-weight: normal; 6 | font-style: normal; } 7 | 8 | @font-face { 9 | font-family: 'museo_700regular'; 10 | src: url("../fonts/museo700-regular-webfont.eot"); 11 | src: url("../fonts/museo700-regular-webfont.eot?#iefix") format("embedded-opentype"), url("../fonts/museo700-regular-webfont.woff") format("woff"), url("../fonts/museo700-regular-webfont.ttf") format("truetype"), url("../fonts/museo700-regular-webfont.svg#museo_700regular") format("svg"); 12 | font-weight: normal; 13 | font-style: normal; } 14 | 15 | html { 16 | font-size: 100%; } 17 | 18 | body { 19 | font-family: "Open Sans", Arial, sans-serif; 20 | font-size: 0.813em; 21 | font-weight: 400; 22 | color: #4d4d4d; } 23 | 24 | h1 { 25 | margin: 0 0 0.972em; 26 | font-weight: 300; 27 | font-size: 2.250em; } 28 | h1 span { 29 | font-weight: 800; } 30 | 31 | h2 { 32 | margin: 0 0 0.682em; 33 | font-weight: 600; 34 | font-size: 1.375em; } 35 | 36 | h3 { 37 | margin: 0 0 1.250em; 38 | font-weight: 600; 39 | font-size: 1em; } 40 | 41 | a { 42 | color: #4d4d4d; 43 | text-decoration: underline; } 44 | a:hover { 45 | color: #29abe2; } 46 | 47 | nav { 48 | font-size: 1em; } 49 | 50 | input { 51 | font-size: 0.938em; } 52 | 53 | .chapo { 54 | font-style: italic; } 55 | 56 | /* Choose a grid width, the number of columns and the margin between columns. The result of the following equation has to be an integer, not a fraction: (width - (columns - 1) * col_margin) / columns = N */ 57 | /* total with of page */ 58 | .container { 59 | margin: 0 auto; 60 | width: 960px; } 61 | 62 | header { 63 | margin: 0 0 20px; 64 | border-top: 3px solid #29abe2; } 65 | header .header-block { 66 | position: relative; } 67 | header nav { 68 | margin: 40px 0 0; } 69 | 70 | .main-container { 71 | margin-bottom: 70px; } 72 | 73 | footer { 74 | background: #f2f2f2; } 75 | footer .footer-block { 76 | padding: 30px 0 20px; 77 | border-top: 1px solid #e6e6e6; 78 | background: url(../img/bg-footer.png) right 23px no-repeat; } 79 | footer .footer-block nav { 80 | margin: 5px 40px 0 0; } 81 | 82 | .col3 { 83 | margin: 0 50px 70px 0; 84 | width: 270px; } 85 | .col3 img { 86 | padding: 10px; 87 | margin: 0 0 10px; 88 | border: 1px solid #e6e6e6; } 89 | .col3:last-child { 90 | margin: 0; } 91 | .col3 h2 { 92 | text-align: center; 93 | font-size: 18px; } 94 | 95 | .col4 { 96 | margin: 0 20px 0 0; 97 | width: 220px; 98 | text-align: center; } 99 | .col4:last-child { 100 | margin: 0; } 101 | .col4 img { 102 | margin: 0 0 25px; } 103 | .col4 h3 { 104 | margin: 0; 105 | font-family: "museo_700regular", Arial, sans-serif; 106 | font-size: 17px; 107 | line-height: 20px; } 108 | .col4 h3 span { 109 | display: block; 110 | font-family: "Open Sans", Arial, sans-serif; 111 | font-size: 14px; 112 | color: #999; } 113 | 114 | input, textarea { 115 | padding: 4px; 116 | display: inline-block; 117 | width: 560px; 118 | -webkit-border-radius: 0; 119 | -moz-border-radius: 0; 120 | border-radius: 0; 121 | border: 1px solid #e6e6e6; 122 | vertical-align: top; } 123 | input:invalid, textarea:invalid { 124 | border: 2px solid #ff0000; } 125 | 126 | input:focus:required, 127 | textarea:focus:required:invalid { 128 | border: 1px solid #f00; } 129 | 130 | label { 131 | display: inline-block; 132 | width: 150px; } 133 | 134 | input[type="submit"] { 135 | padding: 5px 10px; 136 | margin: 0 0 0 153px; 137 | background: #29abe2; 138 | color: #fff; 139 | border: none; 140 | width: auto; } 141 | 142 | input[type="file"] { 143 | width: 430px; } 144 | 145 | .errorlist { 146 | margin: 0 0 0 153px; 147 | padding: 0; } 148 | .errorlist li { 149 | list-style-type: none; 150 | color: #c1272d; } 151 | 152 | form p { 153 | margin: 0 0 10px; } 154 | 155 | /*Floats*/ 156 | .fl { 157 | float: left; } 158 | 159 | .fr { 160 | float: right; } 161 | 162 | /*Clearing floats*/ 163 | .clear { 164 | clear: both; 165 | display: block; 166 | overflow: hidden; 167 | visibility: hidden; 168 | width: 0; 169 | height: 0; } 170 | 171 | .clearfix:before, 172 | .clearfix:after { 173 | content: ""; 174 | display: table; } 175 | 176 | .clearfix:after { 177 | clear: both; } 178 | 179 | .clearfix { 180 | *zoom: 1; } 181 | 182 | ul { 183 | margin: 0; } 184 | 185 | #logo { 186 | margin: 35px 0 0; } 187 | 188 | .btn-subscribe { 189 | position: absolute; 190 | top: 0; 191 | right: 0; 192 | margin: 0 0 15px; 193 | padding: 5px 15px; 194 | background: #29abe2; 195 | color: white; 196 | font-weight: 600; } 197 | .btn-subscribe a { 198 | color: white; 199 | text-decoration: none; } 200 | .btn-subscribe a:first-child { 201 | padding: 0 10px 0 0; } 202 | .btn-subscribe a:last-child { 203 | padding: 0 0 0 10px; } 204 | 205 | nav li { 206 | margin: 0 15px 0 0; } 207 | nav li:last-child { 208 | margin: 0; } 209 | nav li:last-child:after { 210 | content: ""; } 211 | nav li:last-child a { 212 | padding: 0; } 213 | nav li:after { 214 | content: "|"; } 215 | nav a { 216 | padding: 0 15px 0 0; 217 | color: #4d4d4d; 218 | text-transform: uppercase; 219 | text-decoration: none; 220 | font-weight: 600; } 221 | nav a:hover { 222 | color: #29abe2; } 223 | 224 | .home-illustration { 225 | height: 430px; 226 | background: url(../img/home-illustration.jpg) center bottom no-repeat, url(../img/bg-home-illustration.jpg) 0 0 repeat-x; } 227 | 228 | .illustration-title { 229 | margin: 0; 230 | padding: 70px 0 0; 231 | text-transform: uppercase; 232 | font-size: 30px; } 233 | .illustration-title span { 234 | display: block; 235 | font-weight: 700; 236 | font-size: 36px; } 237 | 238 | .home-title { 239 | margin: 70px 0 60px; 240 | text-align: center; 241 | font-size: 36px; } 242 | 243 | .home-with-bg { 244 | padding: 0 0 75px; 245 | background: #f2f2f2; 246 | border-top: 1px solid #e6e6e6; } 247 | 248 | .link-form { 249 | margin: 20px 0 0 153px; } 250 | .link-form + .link-form { 251 | margin-top: 0px; } 252 | 253 | ul.websites { 254 | padding: 0; 255 | margin: 40px 0px; } 256 | ul.websites > li { 257 | display: inline-block; 258 | width: 255px; 259 | height: 260px; 260 | margin: 0 40px 25px 0; 261 | padding: 10px; 262 | -webkit-box-shadow: 0px 0px 5px #333333; 263 | -moz-box-shadow: 0px 0px 5px #333333; 264 | box-shadow: 0px 0px 5px #333333; } 265 | ul.websites > li > h3 { 266 | margin: 0; } 267 | ul.websites > li > h3 > a { 268 | color: #29abe2; 269 | font-size: 1.5em; 270 | font-weight: 400; 271 | text-decoration: none; 272 | font-family: "Open Sans", Arial, sans-serif; } 273 | ul.websites > li > .info { 274 | margin: 0; 275 | color: #999; 276 | font-style: italic; 277 | height: 40px; } 278 | ul.websites > li > img { 279 | margin: 5px 0; } 280 | ul.websites > li > a { 281 | text-decoration: none; } 282 | 283 | ul.messages { 284 | padding: 0 !important; 285 | margin: 0 !important; 286 | list-style-type: none; } 287 | ul.messages .info, ul.messages .error, ul.messages .success, ul.messages .warning { 288 | padding: 8px 15px; } 289 | ul.messages .info { 290 | background: #F2F7FF; 291 | color: #84B0F6; } 292 | ul.messages .error { 293 | background: #FCE2E2; 294 | color: #F66; } 295 | ul.messages .success { 296 | background: #F2FEF2; 297 | color: #7FBA7F; } 298 | ul.messages .warning { 299 | background: #FFF0D2; 300 | color: #F93; } 301 | 302 | body.error > #content { 303 | background: none no-repeat center 100px; 304 | min-height: 400px; 305 | padding-bottom: 100px; 306 | margin-bottom: 30px; } 307 | body.error > #content h1 { 308 | font-size: 3em; 309 | text-transform: uppercase; 310 | margin: 0; } 311 | body.error > #content h2 { 312 | font-size: 3em; 313 | text-transform: uppercase; } 314 | body.error > #content a { 315 | background: #29abe2; 316 | color: white; 317 | text-decoration: none; 318 | padding: 10px 20px; 319 | font-size: 1.3em; } 320 | body.error > #content a:before { 321 | content: "> "; } 322 | 323 | body.error404 > #content { 324 | background-image: url("../img/error404.png"); } 325 | 326 | body.error500 > #content { 327 | background-image: url("../img/error500.png"); } 328 | -------------------------------------------------------------------------------- /generic/locale/fr/LC_MESSAGES/django.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR