--- a/src/egonomy/__init__.py Mon Mar 17 16:18:45 2014 +0100
+++ b/src/egonomy/__init__.py Fri Mar 21 16:25:21 2014 +0100
@@ -1,4 +1,4 @@
-VERSION = (0, 8, 9, "final", 1)
+VERSION = (0, 9, 0, "final", 0)
VERSION_STR = unicode(".".join(map(lambda i:"%02d" % (i,), VERSION[:2])))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/egonomy/auth/__init__.py Fri Mar 21 16:25:21 2014 +0100
@@ -0,0 +1,31 @@
+from django.conf import settings
+from django.utils.crypto import get_random_string
+
+from egonomy.utils import unix_time, encodeAES, decodeAES
+
+
+def get_egonomy_token(request):
+
+ if request.user.is_authenticated():
+ sessionid = request.session.session_key
+ salt = get_random_string(length=getattr(settings, 'EGONOMY_SALT_LENGTH', 12))
+
+ return encodeAES("|".join([sessionid,salt]))
+ else:
+ return None
+
+#TODO : check
+def parse_egonomy_token(token):
+
+ #retore padding if needed
+ token += "=" * ((4 - len(token) % 4) % 4)
+ decoded_token = decodeAES(str(token))
+ sessionid, salt = decoded_token.split("|")
+
+ return {'sessionid': sessionid, 'salt': salt}
+
+
+def clean_egonomy_username(username, is_internal):
+ prefix = settings.EGONOMY_USER_PREFIX
+ return (prefix if ( prefix not in username and not is_internal) else "") + username
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/egonomy/auth/backends.py Fri Mar 21 16:25:21 2014 +0100
@@ -0,0 +1,56 @@
+# -*- coding: utf-8 -*-
+'''
+Created on Mar 19, 2014
+
+@author: ymh
+'''
+
+import logging
+
+from django.conf import settings
+from django.contrib.auth import get_user_model
+import requests
+
+from egonomy.auth import clean_egonomy_username
+
+
+logger = logging.getLogger(__name__)
+
+class EgonomyBackend(object):
+ """
+ Authenticate against egonomy.
+ """
+
+ def authenticate(self, username=None, password=None):
+
+
+ User = get_user_model()
+ login_url = getattr(settings, "EGONOMY_LOGIN_URL", None)
+
+ if not login_url:
+ return None
+
+ logger.debug("EgonomyBackend.authenticate Calling %s" % login_url)
+ res_login = requests.post(login_url, data={'user_name': username, 'user_password': password, 'login':'true'})
+
+ logger.debug("EgonomyBackend.authenticate Response received %s" % res_login.text)
+
+ try:
+ res_json = res_login.json()
+ except:
+ return None
+
+ if res_json.get("success", False):
+ username = clean_egonomy_username(username, False)
+ user, _ = User.objects.get_or_create(**{
+ User.USERNAME_FIELD: username
+ })
+ return user
+ return None
+
+ def get_user(self, user_id):
+ User = get_user_model()
+ try:
+ return User.objects.get(pk=user_id)
+ except User.DoesNotExist:
+ return None
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/egonomy/auth/middleware.py Fri Mar 21 16:25:21 2014 +0100
@@ -0,0 +1,84 @@
+# -*- coding: utf-8 -*-
+'''
+Created on Mar 19, 2014
+
+@author: ymh
+'''
+import logging
+
+from django.conf import settings
+from django.contrib import auth
+from django.contrib.auth import get_user_model
+from django.core.exceptions import ImproperlyConfigured
+import requests
+
+from egonomy.auth import clean_egonomy_username
+from django.http.response import HttpResponseBadRequest
+
+
+logger = logging.getLogger(__name__)
+
+class EgonomyUserTokenMiddleware(object):
+
+ parameter = (getattr(settings, "EGONOMY_TOKEN_NAME", None) or "egonomytoken")
+
+ def process_request(self, request):
+ if not hasattr(request, 'user'):
+ raise ImproperlyConfigured(
+ "The Egonomy user token auth middleware requires the"
+ " authentication middleware to be installed. Edit your"
+ " MIDDLEWARE_CLASSES setting to insert"
+ " 'django.contrib.auth.middleware.AuthenticationMiddleware'"
+ " before the EgonomyUserTokenMiddleware class.")
+
+ logger.debug("EgonomyUserTokenMiddleware called")
+ token = request.POST.get(self.parameter,request.GET.get(self.parameter,None))
+ if not token:
+ return
+
+ logger.debug("EgonomyUserTokenMiddleware token found %s" % token)
+
+ token_check_url = getattr(settings, "EGONOMY_TOKEN_CHECK_URL", None)
+ if not token_check_url:
+ return
+
+ res_check = requests.get(token_check_url, params={self.parameter:token})
+ logger.debug("EgonomyUserTokenMiddleware json raw %s" % res_check.text)
+ res_json = res_check.json()
+
+ logger.debug("EgonomyUserTokenMiddleware json %s" % res_json )
+ if not res_json.get('success', False):
+ return
+
+ username = res_json.get('username', None)
+ if not username :
+ return HttpResponseBadRequest("Empty username")
+
+ #"namespace" username
+ username = clean_egonomy_username(username, res_json.get('external', True))
+ # If the user is already authenticated and that user is the user we are
+ # getting passed in the headers, then the correct user is already
+ # persisted in the session and we don't need to continue.
+ if request.user.is_authenticated() and request.user.get_username() == username:
+ return
+ else:
+ auth.logout(request)
+
+ # create user if not known
+ # login user
+ UserModel = get_user_model()
+
+ # Note that this could be accomplished in one try-except clause, but
+ # instead we use get_or_create when creating unknown users since it has
+ # built-in safeguards for multiple threads.
+ user, _ = UserModel.objects.get_or_create(**{
+ UserModel.USERNAME_FIELD: username
+ })
+
+ if user:
+ user.backend = 'django.contrib.auth.backends.ModelBackend'
+ # User is valid. Set request.user and persist user in the session
+ # by logging the user in.
+ request.user = user
+
+ auth.login(request, user)
--- a/src/egonomy/config.py.tmpl Mon Mar 17 16:18:45 2014 +0100
+++ b/src/egonomy/config.py.tmpl Fri Mar 21 16:25:21 2014 +0100
@@ -151,4 +151,11 @@
EMAIL_HOST = '%(email_host)s'
EMAIL_HOST_USER = '%(email_host_user)s'
EMAIL_HOST_PASSWORD = '%(email_host_password)s'
-EMAIL_PORT = %(email_port)d
+EMAIL_PORT = %(email_port)d
+
+EGONOMY_URL = '#'
+EGONOMY_LOGIN_URL =''
+EGONOMY_SALT_LENGTH = 12
+EGONOMY_TOKEN_NAME = 'egonomytoken'
+EGONOMY_TOKEN_CHECK_URL = ''
+
--- a/src/egonomy/settings.py Mon Mar 17 16:18:45 2014 +0100
+++ b/src/egonomy/settings.py Fri Mar 21 16:25:21 2014 +0100
@@ -102,6 +102,7 @@
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
+ 'egonomy.auth.middleware.EgonomyUserTokenMiddleware'
# Uncomment the next line for simple clickjacking protection:
# 'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
@@ -182,11 +183,24 @@
}
}
+AUTHENTICATION_BACKENDS = (
+ 'django.contrib.auth.backends.ModelBackend',
+ 'egonomy.auth.backends.EgonomyBackend',
+)
+
HAYSTACK_SIGNAL_PROCESSOR = 'egonomy.search_indexes.EgonomySignalProcessor'
ACCOUNT_ACTIVATION_DAYS = 7
TASTYPIE_DEFAULT_FORMATS = ['json']
+EGONOMY_URL = '#'
+EGONOMY_LOGIN_URL =''
+EGONOMY_SALT_LENGTH = 12
+EGONOMY_TOKEN_NAME = 'egonomytoken'
+EGONOMY_TOKEN_CHECK_URL = ''
+
+EGONOMY_USER_PREFIX = 'egonomy:'
+
from .config import * #@UnusedWildImport
if not "SRC_BASE_URL" in locals():
--- a/src/egonomy/templates/egonomy_all_collections.html Mon Mar 17 16:18:45 2014 +0100
+++ b/src/egonomy/templates/egonomy_all_collections.html Fri Mar 21 16:25:21 2014 +0100
@@ -1,4 +1,4 @@
-{% extends "egonomy_newbase.html" %}
+{% extends "egonomy_base.html" %}
{% load static %}
{% load i18n %}
{% load thumbnail %}
--- a/src/egonomy/templates/egonomy_all_fragments.html Mon Mar 17 16:18:45 2014 +0100
+++ b/src/egonomy/templates/egonomy_all_fragments.html Fri Mar 21 16:25:21 2014 +0100
@@ -1,4 +1,4 @@
-{% extends "egonomy_newbase.html" %}
+{% extends "egonomy_base.html" %}
{% load static %}
{% load i18n %}
{% load thumbnail %}
--- a/src/egonomy/templates/egonomy_all_pictures.html Mon Mar 17 16:18:45 2014 +0100
+++ b/src/egonomy/templates/egonomy_all_pictures.html Fri Mar 21 16:25:21 2014 +0100
@@ -1,4 +1,4 @@
-{% extends "egonomy_newbase.html" %}
+{% extends "egonomy_base.html" %}
{% load static %}
{% load i18n %}
{% load thumbnail %}
--- a/src/egonomy/templates/egonomy_annotate_picture.html Mon Mar 17 16:18:45 2014 +0100
+++ b/src/egonomy/templates/egonomy_annotate_picture.html Fri Mar 21 16:25:21 2014 +0100
@@ -1,4 +1,4 @@
-{% extends "egonomy_newbase.html" %}
+{% extends "egonomy_base.html" %}
{% load static %}
{% load absstatic %}
{% load i18n %}
--- a/src/egonomy/templates/egonomy_base.html Mon Mar 17 16:18:45 2014 +0100
+++ b/src/egonomy/templates/egonomy_base.html Fri Mar 21 16:25:21 2014 +0100
@@ -1,68 +1,150 @@
{% load static %}
{% load i18n %}
-{#% load analytics %#}
<!DOCTYPE html>
-<html lang="fr">
- {% block head %}
- <head>
- <meta charset="utf-8" />
- <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
- <title>TagItAll by eGonomy » {% block title %}Base{% endblock %}</title>
- {% block css_declaration %}{% endblock %}
- {% block css_import %}
- <link rel="stylesheet" href="{% static 'egonomy/css/egonomy.css' %}" />
- {% endblock %}
- {% block css_page %}{% endblock %}
- {% block js_import %}
- <script type="text/javascript" src="{% static 'egonomy/lib/jquery.min.js' %}"></script>
- {% endblock %}
- {% block js_inline %}
- <script type="text/javascript">
- $(function() {
- $(".search-type").change(function() {
- $(".search-form").attr("action", $(this).val());
- if ($(".search-field").val()) {
- $(".search-form").submit();
- }
- });
- });
- </script>
- {% endblock %}
- </head>
+<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
+<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
+<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
+<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
+{% block head %}
+<head>
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="description" content="eGonomy">
+ <title>TagItAll by eGonomy » {% block title %}Base{% endblock %}</title>
+ {% block css_declaration %}{% endblock %}
+ {% block css_import %}
+ <link rel="stylesheet" href="{% static 'egonomy/css/reset.css' %}" />
+ <link rel="stylesheet" href="{% static 'egonomy/css/fonts.css' %}" />
+ <link rel="stylesheet" href="{% static 'egonomy/css/style.css' %}" />
{% endblock %}
- <body>
- <div class="header-wrap fullwidth">
+ {% block css_page %}{% endblock %}
+</head>
+{% endblock %}
+<body>
+ <div class="popin-wrap">
+ {% if current_user_collection_list %}
+ <div id="add-to-collection" class="popin popin-new-collection box-shadow">
<header>
- <h1 class="column column-third"><a href="{% url 'home' %}">TagItAll {% trans "by" %} eGonomy</a></h1>
- <form class="search-form column column-third" action="{% if search_fragment %}{% url 'all_fragments' %}{% else %}{% url 'all_pictures' %}{% endif %}" method="GET">
- <input class="search-field" type="search" placeholder="{% trans 'Search' %}" id="id_search" name="search"/>
- <select class="search-type">
- <option value="{% url 'all_pictures' %}"{% if not search_fragment %} selected{% endif %}>Images</option>
- <option value="{% url 'all_fragments' %}"{% if search_fragment %} selected{% endif %}>Fragments</option>
- </select>
- <input type="hidden" value="all" name="field">
- </form>
- <nav class="column column-third">
- {% if user.is_authenticated %}
- <a href="{% url 'user_fragments' username=user %}">{{ user.username }}</a> : <a href="{% url 'logout' %}?next={% url 'home' %}">{% trans "Log out" %}</a>
- {% else %}
- <a href="{% url 'login' %}">{% trans "Log in" %}</a>
- {% endif %}
- </nav>
+ <h2>{% trans "Add to the collection" %}</h2>
+ <a href="#" class="close-popin"></a>
</header>
+ <section>
+ <form class="ajax-form" action="{% url 'add_item' %}" method="POST">
+ <p>
+ <label for="collection-name">{% trans "Add to" %} :</label>
+ <label class="styled-select">
+ <select name="collection-pk" id="collection-pk">
+ {% for c in current_user_collection_list %}
+ <option value="{{ c.pk }}">{{ c.title }}</option>
+ {% endfor %}
+ </select>
+ </label>
+ </p>
+ <p>
+ <label class="block" for="item-description">{% trans "Image comment" %} :</label>
+ <textarea name="item-description" id="item-description"></textarea>
+ </p>
+ <div class="buttons">
+ <a href="#" class="btn close-popin">{% trans "Cancel" %}</a>
+ <input class="btn" type="submit" value="{% trans 'Submit' %}">
+ </div>
+ <input class="item-type" name="item-type" type="hidden" value="">
+ <input class="item-id" name="item-id" type="hidden" value="">{% csrf_token %}
+ </form>
+ </section>
</div>
- <div class="main-wrap fullwidth">
- <div class="main">
- {% block content %}
- {% endblock %}
- <footer class="fullwidth">
- <ul class="footer-list">
- <li>© IRI 2013</li>
- <li>v{{ VERSION }}</li>
+ <div class="popin additem-success box-shadow">
+ <h2>{% trans "The item was successfully added to the collection" %}</h2>
+ <h2><a class="collection-url" href="#">{% trans "See the collection" %}</a></h2>
+ </div>
+ <div class="popin additem-error box-shadow">
+ <h2>{% trans "An error occurred while adding the item to the collection" %}</h2>
+ </div>
+ {% endif %}
+ {% block popins %}{% endblock %}
+ </div>
+ <div class="wrap">
+ <header class="clearfix">
+ <h1><a href="{% url 'home' %}">egonomy</a></h1>
+ <div class="col-right">
+ <ul class="head-login clearfix">
+ <li>
+ <form id="search-form" action="{% if search_fragment %}{% url 'all_fragments' %}{% else %}{% url 'all_pictures' %}{% endif %}" method="GET">
+ <p>
+ <input id="search-field" type="text" placeholder="{% trans 'Search' %}" name="search"/>
+ <label class="styled-select">
+ <select id="search-type">
+ <option value="{% url 'all_pictures' %}"{% if not search_fragment %} selected{% endif %}>Images</option>
+ <option value="{% url 'all_fragments' %}"{% if search_fragment %} selected{% endif %}>Fragments</option>
+ </select>
+ </label>
+ <input type="hidden" value="all" name="field">
+ </p>
+ </form>
+ </li>
+ {% if user.is_authenticated %}
+ <li class="hello-user">{% trans "Hello" %} <a href="{% url 'auth_password_change' %}">{{ user.username }}</a>
+ <li><span class="dot-6"></span></li>
+ <li><a href="{% url 'logout' %}?next={% url 'home' %}">{% trans "Log out" %}</a></li>
+ {% else %}
+ <li class="hello-user"><a href="{% url 'login' %}">{% trans "Log in" %}</a></li>
+ {% endif %}
+ </ul>
+ <nav>
+ <ul class="nav clearfix">
+ <li><a href="{% url 'all_pictures' %}" {% if all_pictures %}class="active"{% endif %}>{% trans "explore" %}</a></li>
+ <li><span class="dot-10"></span></li>
+ <li><a href="{% url 'all_collections' %}" {% if all_collections %}class="active"{% endif %}>{% trans "collect" %}</a></li>
+ {% if EGONOMY_URL %}
+ <li><span class="dot-10"></span></li>
+ <li><a href="{{ EGONOMY_URL }}" target="_blank">Egonomy</a></li>
+ {% endif %}
</ul>
- </footer>
+ {% if user.is_authenticated %}
+ <ul class="sub-nav clearfix">
+ <li><a href="{% url 'user_collections' username=user %}" {% if user_collections %}class="active"{% endif %}>{% trans "my collections" %}</a></li>
+ <li><span class="dot-6"></span></li>
+ <li><a href="{% url 'user_fragments' username=user %}" {% if user_fragments %}class="active"{% endif %}>{% trans "my fragments" %}</a></li>
+ <!--li><span class="dot-6"></span></li>
+ <li><a href="#">mon profil</a></li-->
+ </ul>
+ {% endif %}
+ </nav>
</div>
- </div>
- {#% analytics %#}
- </body>
-</html>
+ </header>
+ <section>
+ {% block content %}
+ {% endblock %}
+ </section>
+ <footer class="clearfix">
+ <!--h6>EGONOMY est un projet de l’IRI et de la réunion des Musées Nationaux</h6-->
+ <p>© IRI 2013 - v{{ VERSION }}</p>
+ </footer>
+ </div><!-- /.wrap -->
+ {% block js_common %}
+ <script type="text/javascript" src="{% static 'egonomy/lib/jquery.min.js' %}"></script>
+ <script type="text/javascript" src="{% static 'egonomy/js/masonry.min.js' %}"></script>
+ <script type="text/javascript" src="{% static 'egonomy/js/main.js' %}"></script>
+ {% endblock %}
+ <script type="text/javascript">
+ $(function() {
+ $("#search-type").change(function() {
+ $("#search-form").attr("action", $(this).val());
+ if ($("#search-field").val()) {
+ $("#search-form").submit();
+ }
+ });
+ });
+ </script>
+ {% block js_page %}
+ {% endblock %}
+<script>
+(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+(i[r].q=i[r].q||[]).push(arguments)},
+i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+ga('create', 'UA-30064213-3', 'iri-research.org');
+ga('send', 'pageview');
+</script>
+</body>
+</html>
\ No newline at end of file
--- a/src/egonomy/templates/egonomy_create_fragment.html Mon Mar 17 16:18:45 2014 +0100
+++ b/src/egonomy/templates/egonomy_create_fragment.html Fri Mar 21 16:25:21 2014 +0100
@@ -1,4 +1,4 @@
-{% extends "egonomy_newbase.html" %}
+{% extends "egonomy_base.html" %}
{% load static %}
{% load i18n %}
{% load thumbnail %}
--- a/src/egonomy/templates/egonomy_home.html Mon Mar 17 16:18:45 2014 +0100
+++ b/src/egonomy/templates/egonomy_home.html Fri Mar 21 16:25:21 2014 +0100
@@ -1,4 +1,4 @@
-{% extends "egonomy_newbase.html" %}
+{% extends "egonomy_base.html" %}
{% load static %}
{% load i18n %}
{% load thumbnail %}
--- a/src/egonomy/templates/egonomy_newbase.html Mon Mar 17 16:18:45 2014 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,150 +0,0 @@
-{% load static %}
-{% load i18n %}
-<!DOCTYPE html>
-<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
-<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
-<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
-<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
-{% block head %}
-<head>
- <meta charset="utf-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
- <meta name="description" content="eGonomy">
- <title>TagItAll by eGonomy » {% block title %}Base{% endblock %}</title>
- {% block css_declaration %}{% endblock %}
- {% block css_import %}
- <link rel="stylesheet" href="{% static 'egonomy/css/reset.css' %}" />
- <link rel="stylesheet" href="{% static 'egonomy/css/fonts.css' %}" />
- <link rel="stylesheet" href="{% static 'egonomy/css/style.css' %}" />
- {% endblock %}
- {% block css_page %}{% endblock %}
-</head>
-{% endblock %}
-<body>
- <div class="popin-wrap">
- {% if current_user_collection_list %}
- <div id="add-to-collection" class="popin popin-new-collection box-shadow">
- <header>
- <h2>{% trans "Add to the collection" %}</h2>
- <a href="#" class="close-popin"></a>
- </header>
- <section>
- <form class="ajax-form" action="{% url 'add_item' %}" method="POST">
- <p>
- <label for="collection-name">{% trans "Add to" %} :</label>
- <label class="styled-select">
- <select name="collection-pk" id="collection-pk">
- {% for c in current_user_collection_list %}
- <option value="{{ c.pk }}">{{ c.title }}</option>
- {% endfor %}
- </select>
- </label>
- </p>
- <p>
- <label class="block" for="item-description">{% trans "Image comment" %} :</label>
- <textarea name="item-description" id="item-description"></textarea>
- </p>
- <div class="buttons">
- <a href="#" class="btn close-popin">{% trans "Cancel" %}</a>
- <input class="btn" type="submit" value="{% trans 'Submit' %}">
- </div>
- <input class="item-type" name="item-type" type="hidden" value="">
- <input class="item-id" name="item-id" type="hidden" value="">{% csrf_token %}
- </form>
- </section>
- </div>
- <div class="popin additem-success box-shadow">
- <h2>{% trans "The item was successfully added to the collection" %}</h2>
- <h2><a class="collection-url" href="#">{% trans "See the collection" %}</a></h2>
- </div>
- <div class="popin additem-error box-shadow">
- <h2>{% trans "An error occurred while adding the item to the collection" %}</h2>
- </div>
- {% endif %}
- {% block popins %}{% endblock %}
- </div>
- <div class="wrap">
- <header class="clearfix">
- <h1><a href="{% url 'home' %}">egonomy</a></h1>
- <div class="col-right">
- <ul class="head-login clearfix">
- <li>
- <form id="search-form" action="{% if search_fragment %}{% url 'all_fragments' %}{% else %}{% url 'all_pictures' %}{% endif %}" method="GET">
- <p>
- <input id="search-field" type="text" placeholder="{% trans 'Search' %}" name="search"/>
- <label class="styled-select">
- <select id="search-type">
- <option value="{% url 'all_pictures' %}"{% if not search_fragment %} selected{% endif %}>Images</option>
- <option value="{% url 'all_fragments' %}"{% if search_fragment %} selected{% endif %}>Fragments</option>
- </select>
- </label>
- <input type="hidden" value="all" name="field">
- </p>
- </form>
- </li>
- {% if user.is_authenticated %}
- <li class="hello-user">{% trans "Hello" %} <a href="{% url 'auth_password_change' %}">{{ user.username }}</a>
- <li><span class="dot-6"></span></li>
- <li><a href="{% url 'logout' %}?next={% url 'home' %}">{% trans "Log out" %}</a></li>
- {% else %}
- <li class="hello-user"><a href="{% url 'login' %}">{% trans "Log in" %}</a></li>
- {% endif %}
- </ul>
- <nav>
- <ul class="nav clearfix">
- <li><a href="{% url 'all_pictures' %}" {% if all_pictures %}class="active"{% endif %}>{% trans "explore" %}</a></li>
- <li><span class="dot-10"></span></li>
- <li><a href="{% url 'all_collections' %}" {% if all_collections %}class="active"{% endif %}>{% trans "collect" %}</a></li>
- <!--li><span class="dot-10"></span></li>
- <li><a href="#">créer</a></li>
- <li><span class="dot-10"></span></li>
- <li><a href="">mon profil</a></li-->
- </ul>
- {% if user.is_authenticated %}
- <ul class="sub-nav clearfix">
- <li><a href="{% url 'user_collections' username=user %}" {% if user_collections %}class="active"{% endif %}>{% trans "my collections" %}</a></li>
- <li><span class="dot-6"></span></li>
- <li><a href="{% url 'user_fragments' username=user %}" {% if user_fragments %}class="active"{% endif %}>{% trans "my fragments" %}</a></li>
- <!--li><span class="dot-6"></span></li>
- <li><a href="#">mon profil</a></li-->
- </ul>
- {% endif %}
- </nav>
- </div>
- </header>
- <section>
- {% block content %}
- {% endblock %}
- </section>
- <footer class="clearfix">
- <!--h6>EGONOMY est un projet de l’IRI et de la réunion des Musées Nationaux</h6-->
- <p>© IRI 2013 - v{{ VERSION }}</p>
- </footer>
- </div><!-- /.wrap -->
- {% block js_common %}
- <script type="text/javascript" src="{% static 'egonomy/lib/jquery.min.js' %}"></script>
- <script type="text/javascript" src="{% static 'egonomy/js/masonry.min.js' %}"></script>
- <script type="text/javascript" src="{% static 'egonomy/js/main.js' %}"></script>
- {% endblock %}
- <script type="text/javascript">
- $(function() {
- $("#search-type").change(function() {
- $("#search-form").attr("action", $(this).val());
- if ($("#search-field").val()) {
- $("#search-form").submit();
- }
- });
- });
- </script>
- {% block js_page %}
- {% endblock %}
-<script>
-(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
-(i[r].q=i[r].q||[]).push(arguments)},
-i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
-})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
-ga('create', 'UA-30064213-3', 'iri-research.org');
-ga('send', 'pageview');
-</script>
-</body>
-</html>
\ No newline at end of file
--- a/src/egonomy/templates/egonomy_view_collection.html Mon Mar 17 16:18:45 2014 +0100
+++ b/src/egonomy/templates/egonomy_view_collection.html Fri Mar 21 16:25:21 2014 +0100
@@ -1,4 +1,4 @@
-{% extends "egonomy_newbase.html" %}
+{% extends "egonomy_base.html" %}
{% load static %}
{% load i18n %}
--- a/src/egonomy/templates/egonomy_view_fragment.html Mon Mar 17 16:18:45 2014 +0100
+++ b/src/egonomy/templates/egonomy_view_fragment.html Fri Mar 21 16:25:21 2014 +0100
@@ -1,4 +1,4 @@
-{% extends "egonomy_newbase.html" %}
+{% extends "egonomy_base.html" %}
{% load static %}
{% load i18n %}
{% load thumbnail %}
--- a/src/egonomy/templates/registration/activate.html Mon Mar 17 16:18:45 2014 +0100
+++ b/src/egonomy/templates/registration/activate.html Fri Mar 21 16:25:21 2014 +0100
@@ -1,4 +1,4 @@
-{% extends "egonomy_newbase.html" %}
+{% extends "egonomy_base.html" %}
{% load i18n %}
{% block content %}
--- a/src/egonomy/templates/registration/activation_complete.html Mon Mar 17 16:18:45 2014 +0100
+++ b/src/egonomy/templates/registration/activation_complete.html Fri Mar 21 16:25:21 2014 +0100
@@ -1,4 +1,4 @@
-{% extends "egonomy_newbase.html" %}
+{% extends "egonomy_base.html" %}
{% load i18n %}
{% block content %}
--- a/src/egonomy/templates/registration/login.html Mon Mar 17 16:18:45 2014 +0100
+++ b/src/egonomy/templates/registration/login.html Fri Mar 21 16:25:21 2014 +0100
@@ -1,4 +1,4 @@
-{% extends "egonomy_newbase.html" %}
+{% extends "egonomy_base.html" %}
{% load static %}
{% load i18n %}
--- a/src/egonomy/templates/registration/password_change_done.html Mon Mar 17 16:18:45 2014 +0100
+++ b/src/egonomy/templates/registration/password_change_done.html Fri Mar 21 16:25:21 2014 +0100
@@ -1,4 +1,4 @@
-{% extends "egonomy_newbase.html" %}
+{% extends "egonomy_base.html" %}
{% load i18n %}
{% block content %}
--- a/src/egonomy/templates/registration/password_change_form.html Mon Mar 17 16:18:45 2014 +0100
+++ b/src/egonomy/templates/registration/password_change_form.html Fri Mar 21 16:25:21 2014 +0100
@@ -1,4 +1,4 @@
-{% extends "egonomy_newbase.html" %}
+{% extends "egonomy_base.html" %}
{% load i18n %}
{% block content %}
--- a/src/egonomy/templates/registration/password_reset_complete.html Mon Mar 17 16:18:45 2014 +0100
+++ b/src/egonomy/templates/registration/password_reset_complete.html Fri Mar 21 16:25:21 2014 +0100
@@ -1,4 +1,4 @@
-{% extends "egonomy_newbase.html" %}
+{% extends "egonomy_base.html" %}
{% load i18n %}
{% block content %}
--- a/src/egonomy/templates/registration/password_reset_confirm.html Mon Mar 17 16:18:45 2014 +0100
+++ b/src/egonomy/templates/registration/password_reset_confirm.html Fri Mar 21 16:25:21 2014 +0100
@@ -1,4 +1,4 @@
-{% extends "egonomy_newbase.html" %}
+{% extends "egonomy_base.html" %}
{% load i18n %}
{% block content %}
--- a/src/egonomy/templates/registration/password_reset_done.html Mon Mar 17 16:18:45 2014 +0100
+++ b/src/egonomy/templates/registration/password_reset_done.html Fri Mar 21 16:25:21 2014 +0100
@@ -1,4 +1,4 @@
-{% extends "egonomy_newbase.html" %}
+{% extends "egonomy_base.html" %}
{% load i18n %}
{% block content %}
--- a/src/egonomy/templates/registration/password_reset_form.html Mon Mar 17 16:18:45 2014 +0100
+++ b/src/egonomy/templates/registration/password_reset_form.html Fri Mar 21 16:25:21 2014 +0100
@@ -1,4 +1,4 @@
-{% extends "egonomy_newbase.html" %}
+{% extends "egonomy_base.html" %}
{% load i18n %}
{% block content %}
--- a/src/egonomy/templates/registration/registration_complete.html Mon Mar 17 16:18:45 2014 +0100
+++ b/src/egonomy/templates/registration/registration_complete.html Fri Mar 21 16:25:21 2014 +0100
@@ -1,4 +1,4 @@
-{% extends "egonomy_newbase.html" %}
+{% extends "egonomy_base.html" %}
{% load i18n %}
{% block content %}
--- a/src/egonomy/templates/registration/registration_form.html Mon Mar 17 16:18:45 2014 +0100
+++ b/src/egonomy/templates/registration/registration_form.html Fri Mar 21 16:25:21 2014 +0100
@@ -1,4 +1,4 @@
-{% extends "egonomy_newbase.html" %}
+{% extends "egonomy_base.html" %}
{% load i18n %}
{% block content %}
--- a/src/egonomy/urls.py Mon Mar 17 16:18:45 2014 +0100
+++ b/src/egonomy/urls.py Fri Mar 21 16:25:21 2014 +0100
@@ -39,6 +39,8 @@
# login logout view
url(r'^login/', 'django.contrib.auth.views.login', name='login'),
url(r'^logout/', 'django.contrib.auth.views.logout', name='logout'),
+ url(r'^ajax-login/', 'egonomy.views.ajax_login', name='ajax_login'),
+ url(r'^check-egonomy-token/(?P<token>[\w\d\-_=]*)$', 'egonomy.views.check_egonomy_token', name='check_egonomy_token'),
(r'^api/', include('egonomy.api.urls')),
(r'^accounts/', include('registration.backends.default.urls')),
)
--- a/src/egonomy/utils/__init__.py Mon Mar 17 16:18:45 2014 +0100
+++ b/src/egonomy/utils/__init__.py Fri Mar 21 16:25:21 2014 +0100
@@ -0,0 +1,30 @@
+import base64
+import datetime
+import hashlib
+
+from Crypto.Cipher import AES # encryption library
+from django.conf import settings
+import pytz
+
+
+def unix_time(dt):
+ epoch = datetime.datetime.utcfromtimestamp(0).replace(tzinfo=pytz.UTC)
+ delta = dt - epoch
+ return delta.total_seconds()
+
+BLOCK_SIZE = 32
+# the character used for padding--with a block cipher such as AES, the value
+# you encrypt must be a multiple of BLOCK_SIZE in length. This character is
+# used to ensure that your value is always a multiple of BLOCK_SIZE
+PADDING = '{'
+
+# one-liner to sufficiently pad the text to be encrypted
+pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING
+
+# create a cipher object using the random secret
+cipher = AES.new(hashlib.md5(settings.SECRET_KEY).hexdigest())
+
+# one-liners to encrypt/encode and decrypt/decode a string
+# encrypt with AES, encode with base64
+encodeAES = lambda s: base64.urlsafe_b64encode(cipher.encrypt(pad(s)))
+decodeAES = lambda e: cipher.decrypt(base64.urlsafe_b64decode(e)).rstrip(PADDING)
--- a/src/egonomy/utils/context_processors.py Mon Mar 17 16:18:45 2014 +0100
+++ b/src/egonomy/utils/context_processors.py Fri Mar 21 16:25:21 2014 +0100
@@ -1,5 +1,13 @@
+from django.conf import settings
+
import egonomy
+from egonomy.auth import get_egonomy_token
+
def egonomy_context(request):
- return {'VERSION': egonomy.get_version() }
+ egonomy_url = getattr(settings, 'EGONOMY_URL', '#')
+ egonomy_token = get_egonomy_token(request)
+ egonomy_token_name = ( getattr(settings, 'EGONOMY_TOKEN_NAME', 'egonomytoken') or 'egonomytoken')
+ return {'VERSION': egonomy.get_version(), 'EGONOMY_URL': "%s?%s=%s" % (egonomy_url, egonomy_token_name, egonomy_token) if egonomy_token else egonomy_url }
+
--- a/src/egonomy/views.py Mon Mar 17 16:18:45 2014 +0100
+++ b/src/egonomy/views.py Fri Mar 21 16:25:21 2014 +0100
@@ -1,34 +1,42 @@
from datetime import datetime
+import json
+import logging
+import os
+import subprocess
+from unicodedata import normalize
+import uuid
+
from django.conf import settings
+from django.contrib.auth import authenticate, login, get_user_model, SESSION_KEY, \
+ load_backend, BACKEND_SESSION_KEY
from django.contrib.auth.decorators import login_required
-from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.core.paginator import Paginator, InvalidPage, EmptyPage
from django.core.urlresolvers import reverse
from django.db.models.aggregates import Max
-from django.http.response import HttpResponseForbidden, HttpResponse
+from django.http.response import HttpResponseForbidden, HttpResponse, \
+ HttpResponseBadRequest
from django.shortcuts import get_object_or_404, render_to_response, redirect
from django.template import RequestContext
+from django.utils.importlib import import_module
from django.utils.translation import ugettext as _
-from egonomy.models import ImageMetadata, Image, Fragment, ImageInfo, Collection,\
+from django.views.decorators.csrf import csrf_exempt
+from haystack.query import RelatedSearchQuerySet
+import requests
+from sorl.thumbnail import default, get_thumbnail
+from sorl.thumbnail.images import ImageFile
+
+from egonomy.auth import parse_egonomy_token
+from egonomy.models import ImageMetadata, Image, Fragment, ImageInfo, Collection, \
CollectionItem
from egonomy.search_indexes import QueryParser
from egonomy.search_indexes.paginator import SearchPaginator
from egonomy.search_indexes.query import ModelRelatedSearchQuerySet
from egonomy.utils.queries import cache_generics
-from haystack.query import RelatedSearchQuerySet
-from sorl.thumbnail import default, get_thumbnail
-from sorl.thumbnail.images import ImageFile
-from unicodedata import normalize
-import json
-import os
-import requests
-import subprocess
-import uuid
+
-import logging
logger = logging.getLogger(__name__)
-
+User = get_user_model()
def home(request):
@@ -366,7 +374,7 @@
frg.image = img
frg.coordinates = frg_path
# We build the svg xml
- file_path = os.path.join(settings.MEDIA_ROOT, str(img.info.image_file))
+ filepath = os.path.join(settings.MEDIA_ROOT, str(img.info.image_file))
image_file = default.kvstore.get_or_set(ImageFile(img.info.image_file))
ratio = int(100 * frg.ratio * image_file.ratio)
svg = '<svg preserveAspectRatio="none" width="' + str(ratio) + 'px" height="100px" viewBox="' + frg.viewbox +'" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">\n\
@@ -375,10 +383,10 @@
<path d="' + frg_path + '" />\n\
</clipPath>\n\
</defs>\n\
- <image xlink:href="' + file_path + '" x="0" y="0" preserveAspectRatio="none" width="1" height="1" opacity=".1"/>\n\
- <image xlink:href="' + file_path + '" x="0" y="0" preserveAspectRatio="none" width="1" height="1" clip-path="url(#fragment-clip)"/>\n\
+ <image xlink:href="' + filepath + '" x="0" y="0" preserveAspectRatio="none" width="1" height="1" opacity=".1"/>\n\
+ <image xlink:href="' + filepath + '" x="0" y="0" preserveAspectRatio="none" width="1" height="1" clip-path="url(#fragment-clip)"/>\n\
</svg>'
- # We save the svg file
+ # We save the svg filepath
uid = str(uuid.uuid1())
svg_file_path = os.path.join(settings.BATIK_RASTERIZER_TEMP_FOLDER, uid + '.svg')
svg_file = open(svg_file_path,'w')
@@ -675,7 +683,7 @@
try:
col_pk = int(col_pk)
except:
- return HttpResponse("Collection number invalid.", status=400)
+ return HttpResponse("Collection number invalid.", status_code=400)
col = get_object_or_404(Collection.objects.select_related('author'), pk=col_pk)
# We check if the current user is the collection's author
if col.author != request.user:
@@ -692,10 +700,10 @@
try:
item_id = int(item_id)
except:
- return HttpResponse("Fragment number invalid.", status=400)
+ return HttpResponse("Fragment number invalid.", status_code=400)
item = get_object_or_404(Fragment, pk=item_id)
else:
- return HttpResponse("item-type must be 'image' or 'fragment'.", status=400)
+ return HttpResponse("item-type must be 'image' or 'fragment'.", status_code=400)
col_item = CollectionItem()
col_item.collection = col
@@ -729,7 +737,7 @@
try:
col_pk = int(col_pk)
except:
- return HttpResponse("Collection number invalid.", status=400)
+ return HttpResponse("Collection number invalid.", status_code=400)
col = get_object_or_404(Collection.objects.select_related('author'), pk=col_pk)
# We check if the current user is the collection's author
if col.author != request.user:
@@ -740,7 +748,7 @@
# Test item's pk
if not item_pk:
- return HttpResponse("item_pk must be set.", status=400)
+ return HttpResponse("item_pk must be set.", status_code=400)
# Get item
item = get_object_or_404(CollectionItem, pk=item_pk)
# Everything has been checked, we can delete the item
@@ -764,7 +772,7 @@
try:
col_pk = int(col_pk)
except:
- return HttpResponse("Collection number invalid.", status=400)
+ return HttpResponse("Collection number invalid.", status_code=400)
col = get_object_or_404(Collection.objects.select_related('author'), pk=col_pk)
# We check if the current user is the collection's author
if col.author != request.user:
@@ -775,11 +783,11 @@
# Test item's pk
if not item_pk:
- return HttpResponse("item_pk must be set.", status=400)
+ return HttpResponse("item_pk must be set.", status_code=400)
# Get item
item = get_object_or_404(CollectionItem, pk=item_pk)
if item.collection != col:
- return HttpResponse("Item and collection are not related.", status=400)
+ return HttpResponse("Item and collection are not related.", status_code=400)
# Everything has been checked, we can modify and save the item
item.description = description
item.save()
@@ -787,8 +795,6 @@
# It is an ajax call, we juste return "ok"
return HttpResponse("modifyok")
-
-
@login_required
def import_collection(request):
@@ -855,3 +861,91 @@
+@csrf_exempt
+def ajax_login(request):
+ if request.method == 'POST':
+ username = request.POST.get('username', '').strip()
+ password = request.POST.get('password', '').strip()
+ if username and password:
+ # Test username/password combination
+ user = authenticate(username=username, password=password)
+ # Found a match
+ if user is not None:
+ # User is active
+ if user.is_active:
+ # Officially log the user in
+ login(request, user)
+ data = {'success': True}
+ else:
+ data = {'success': False, 'error': 'User is not active'}
+ else:
+ data = {'success': False, 'error': 'Wrong username and/or password'}
+
+ return HttpResponse(json.dumps(data), mimetype='application/json')
+
+ # Request method is not POST or one of username or password is missing
+ return HttpResponseBadRequest()
+
+
+
+def check_egonomy_token(request, token):
+
+ logger.debug("TOKEN : " + token)
+ if not token:
+ return HttpResponseBadRequest("token must be provided")
+
+ token_items = parse_egonomy_token(token)
+
+ session_key = token_items.get('sessionid', None)
+ salt = token_items.get('salt', None)
+
+ error_msg = None
+
+ if len(token_items) != 2:
+ error_msg = "Bad token size"
+ elif not session_key:
+ error_msg = 'No session id in token'
+ elif not salt or len(salt) != getattr(settings, 'EGONOMY_SALT_LENGTH', 12):
+ error_msg = 'Bad token format'
+
+ if error_msg:
+ return HttpResponseBadRequest("Bad token format : %s" % error_msg)
+
+ res_msg = {}
+
+ #get session
+ engine = import_module(settings.SESSION_ENGINE)
+ session = engine.SessionStore(session_key)
+
+ user_id = session.get(SESSION_KEY)
+ auth_backend = load_backend(session.get(BACKEND_SESSION_KEY))
+
+ if session.get_expiry_age() < 0:
+ res_msg['success'] = False
+ res_msg['message'] = "Token expired"
+ elif not user_id or not auth_backend:
+ res_msg['success'] = False
+ res_msg['message'] = "no user"
+ else:
+ user = None
+ try:
+ user = auth_backend.get_user(user_id)
+ except:
+ pass
+
+ if not user:
+ res_msg['success'] = False
+ res_msg['message'] = "user unknown"
+ else:
+ username = getattr(user,User.USERNAME_FIELD)
+ res_msg['success'] = True
+ res_msg['message'] = ""
+ res_msg['username'] = username.replace(settings.EGONOMY_USER_PREFIX,"")
+ res_msg['external'] = username.startswith(settings.EGONOMY_USER_PREFIX)
+
+ return HttpResponse(json.dumps(res_msg), mimetype='application/json')
+
+
+
+
+
--- a/virtualenv/res/lib/lib_create_env.py Mon Mar 17 16:18:45 2014 +0100
+++ b/virtualenv/res/lib/lib_create_env.py Fri Mar 21 16:25:21 2014 +0100
@@ -17,8 +17,8 @@
URLS = {
#'': {'setup': '', 'url':'', 'local':''},
'DISTRIBUTE': {'setup': 'distribute', 'url':'http://pypi.python.org/packages/source/d/distribute/distribute-0.6.31.tar.gz', 'local':"distribute-0.6.31.tar.gz", 'install': {'method': 'pip', 'option_str': None, 'dict_extra_env': None}},
- 'DJANGO': {'setup': 'django', 'url': 'https://www.djangoproject.com/download/1.5/tarball/', 'local':"Django-1.5.tar.gz", 'install': {'method': 'pip', 'option_str': None, 'dict_extra_env': None}},
- 'DJANGO-EXTENSIONS': { 'setup': 'django-extensions', 'url':'https://github.com/django-extensions/django-extensions/archive/1.0.2.tar.gz', 'local':"django-extensions-1.0.2.tar.gz", 'install': {'method': 'pip', 'option_str': None, 'dict_extra_env': None}},
+ 'DJANGO': {'setup': 'django', 'url': 'https://www.djangoproject.com/download/1.6.2/tarball/', 'local':"Django-1.6.2.tar.gz", 'install': {'method': 'pip', 'option_str': None, 'dict_extra_env': None}},
+ 'DJANGO-EXTENSIONS': { 'setup': 'django-extensions', 'url':'https://github.com/django-extensions/django-extensions/archive/1.3.3.tar.gz', 'local':"django-extensions-1.3.3.tar.gz", 'install': {'method': 'pip', 'option_str': None, 'dict_extra_env': None}},
'DJANGO-REGISTRATION': { 'setup': 'django-registration', 'url':'https://bitbucket.org/ubernostrum/django-registration/downloads/django-registration-1.0.tar.gz', 'local':"django-registration-1.0.tar.gz", 'install': {'method': 'easy_install', 'option_str': '-Z', 'dict_extra_env': None}},
'SOUTH': { 'setup': 'South', 'url':'http://www.aeracode.org/releases/south/south-0.7.5.tar.gz', 'local':"south-0.7.5.tar.gz", 'install': {'method': 'pip', 'option_str': None, 'dict_extra_env': None}},
'SORL_THUMBNAIL' : { 'setup': 'sorl-thumbnail', 'url':'https://github.com/sorl/sorl-thumbnail/archive/master.tar.gz', 'local':"sorl-thumbnail-v11.12.tar.gz", 'install': {'method': 'pip', 'option_str': None, 'dict_extra_env': None}},
@@ -38,7 +38,7 @@
'PYTZ' : {'setup': 'pytz', 'url':'http://pypi.python.org/packages/source/p/pytz/pytz-2012j.tar.gz', 'local' : 'pytz-2012j.tar.gz', 'install': {'method': 'pip', 'option_str': None, 'dict_extra_env': None}},
# dependencies for Tastypie : mimeparse>=0.1.3, python-dateutil>=2.1, lxml, PyYAML (not necessary but we never know), python-digest
'MIMEPARSE' : {'setup':'mimeparse', 'url':'http://pypi.python.org/packages/source/m/mimeparse/mimeparse-0.1.3.tar.gz', 'local': 'mimeparse-0.1.3.tar.gz', 'install' : {'method':'pip', 'option_str': None, 'dict_extra_env': None}},
- 'SIX' : {'setup':'six', 'url':'http://pypi.python.org/packages/source/s/six/six-1.2.0.tar.gz', 'local': 'six-1.2.0.tar.gz', 'install' : {'method':'pip', 'option_str': None, 'dict_extra_env': None}},
+ 'SIX' : {'setup':'six', 'url':'https://pypi.python.org/packages/source/s/six/six-1.6.1.tar.gz', 'local': 'six-1.6.1.tar.gz', 'install' : {'method':'pip', 'option_str': None, 'dict_extra_env': None}},
'PYTHON-DATEUTIL' : {'setup':'python-dateutil', 'url':'http://pypi.python.org/packages/source/p/python-dateutil/python-dateutil-2.1.tar.gz', 'local': 'python-dateutil-2.1.tar.gz', 'install' : {'method':'pip', 'option_str': None, 'dict_extra_env': None}},
'PYYAML' : {'setup':'pyyaml', 'url':'http://pypi.python.org/packages/source/P/PyYAML/PyYAML-3.10.tar.gz', 'local': 'PyYAML-3.10.tar.gz', 'install' : {'method':'pip', 'option_str': None, 'dict_extra_env': None}},
'PYTHON-DIGEST' : {'setup':'python-digest', 'url':'http://pypi.python.org/packages/source/p/python-digest/python-digest-1.7.tar.gz', 'local': 'python-digest-1.7.tar.gz', 'install' : {'method':'pip', 'option_str': None, 'dict_extra_env': None}},
@@ -46,6 +46,7 @@
'ISODATE' : {'setup': 'isodate', 'url': 'https://github.com/gweis/isodate/archive/0.4.9.tar.gz', 'local': 'isodate-0.4.9.tar.gz', 'install': {'method':'pip', 'option_str': None, 'dict_extra_env': None}},
'HTML5LIB' : {'setup': 'html5lib', 'url': 'https://html5lib.googlecode.com/files/html5lib-0.95.tar.gz', 'local': 'html5lib-0.95.tar.gz', 'install': {'method':'pip', 'option_str': None, 'dict_extra_env': None}},
'RDFLIB' : {'setup': 'rdflib', 'url': 'https://nodeload.github.com/RDFLib/rdflib/tar.gz/master', 'local': 'rdflib-2.4.0.tar.gz', 'install': {'method':'pip', 'option_str': None, 'dict_extra_env': None}},
+ 'PYCRYPTO' : {'setup': 'pycrypto', 'url': 'http://ftp.dlitz.net/pub/dlitz/crypto/pycrypto/pycrypto-2.6.1.tar.gz', 'local': 'pycrypto-2.6.1.tar.gz', 'install': {'method':'pip', 'option_str': None, 'dict_extra_env': None}},
}
if system_str == 'Windows':
@@ -300,7 +301,12 @@
extra_env = {}
if 'TMPDIR' not in extra_env:
- extra_env['TMPDIR'] = os.path.abspath(tmp_dir)
+ extra_env['TMPDIR'] = os.path.abspath(tmp_dir)
+ if system_str == 'Darwin':
+ archflags = extra_env.get('ARCHFLAGS', '')
+ if '-Wno-error=unused-command-line-argument-hard-error-in-future' not in archflags:
+ archflags += " -Wno-error=unused-command-line-argument-hard-error-in-future"
+ extra_env['ARCHFLAGS'] = archflags.strip()
#isinstance(lst, (list, tuple))
if key not in ignore_packages:
logger.notify("install %s with method %s" % (key, repr(method)))
Binary file virtualenv/res/src/Django-1.5.tar.gz has changed
Binary file virtualenv/res/src/Django-1.6.2.tar.gz has changed
Binary file virtualenv/res/src/django-extensions-1.0.2.tar.gz has changed
Binary file virtualenv/res/src/django-extensions-1.3.3.tar.gz has changed
Binary file virtualenv/res/src/pycrypto-2.6.1.tar.gz has changed
Binary file virtualenv/res/src/six-1.2.0.tar.gz has changed
Binary file virtualenv/res/src/six-1.6.1.tar.gz has changed
--- a/virtualenv/web/res/res_create_env.py Mon Mar 17 16:18:45 2014 +0100
+++ b/virtualenv/web/res/res_create_env.py Fri Mar 21 16:25:21 2014 +0100
@@ -28,6 +28,7 @@
'ISODATE',
'HTML5LIB',
'RDFLIB',
+ 'PYCRYPTO',
]
#if system_str == "Linux" and 'PIL' in INSTALLS: