Merge branch 'test' into dev
authorEric Mc Sween <eric.mcsween@auf.org>
Thu, 5 Apr 2012 20:28:05 +0000 (16:28 -0400)
committerEric Mc Sween <eric.mcsween@auf.org>
Thu, 5 Apr 2012 20:28:05 +0000 (16:28 -0400)
15 files changed:
auf_savoirs_en_partage/chercheurs/admin.py
auf_savoirs_en_partage/chercheurs/forms.py
auf_savoirs_en_partage/chercheurs/migrations/0027_personne_user.py
auf_savoirs_en_partage/chercheurs/models.py
auf_savoirs_en_partage/chercheurs/views.py
auf_savoirs_en_partage/rappels/admin.py
auf_savoirs_en_partage/rappels/management/__init__.py [new file with mode: 0644]
auf_savoirs_en_partage/rappels/management/commands/__init__.py [new file with mode: 0644]
auf_savoirs_en_partage/rappels/management/commands/envoyer_rappels.py [new file with mode: 0644]
auf_savoirs_en_partage/rappels/migrations/0004_auto__add_field_rappeluser_date_demande_envoi__chg_field_rappeluser_da.py [new file with mode: 0644]
auf_savoirs_en_partage/rappels/models.py
auf_savoirs_en_partage/savoirs/management/__init__.py [new file with mode: 0644]
auf_savoirs_en_partage/savoirs/management/commands/__init__.py [new file with mode: 0644]
auf_savoirs_en_partage/savoirs/management/commands/sep_export_aiu_hedbib.py [new file with mode: 0644]
auf_savoirs_en_partage/savoirs/models.py

index fb74efb..20e727e 100644 (file)
@@ -25,6 +25,8 @@ class ChercheurAdmin(admin.ModelAdmin):
     actions = ('remove_from_group', 'export_as_ods', 'export_as_csv')
     search_fields = ('nom', 'prenom')
 
+    exclude = ('user',)
+
     def lookup_allowed(self, lookup, value):
         return lookup in ['genre', 'statut', 'membre_reseau_institutionnel', 
                           'membre_instance_auf', 'discipline', 'region', 'pays', 
@@ -53,7 +55,7 @@ class ChercheurAdmin(admin.ModelAdmin):
         return actions
 
     def queryset(self, request):
-        return ChercheurAdminQuerySet(Chercheur)
+        return ChercheurAdminQuerySet(Chercheur).filter(actif=True)
 
     def get_object(self, request, object_id):
         """On doit réimplémenter cette méthode à cause de ce qu'on fait avec "initial" dans la méthode queryset()."""
@@ -62,6 +64,8 @@ class ChercheurAdmin(admin.ModelAdmin):
         except Chercheur.DoesNotExist:
             return None
 
+    def has_add_permission(self, request, obj=None):
+        return False
 
     def export_as_csv(self, request, queryset):
         return export(queryset, 'csv')
@@ -101,6 +105,9 @@ admin.site.register(ChercheurVoir, ChercheurVoirAdmin)
 
 class ChercheurAdminQuerySet(ChercheurQuerySet):
 
+    def delete(self):
+        self.update(actif=False)
+
     def filter(self, *args, **kwargs):
         """Gère des filtres supplémentaires pour l'admin.
            
index 81f24e4..204d7f3 100644 (file)
@@ -135,6 +135,13 @@ class ChercheurForm(forms.ModelForm):
         existing = Chercheur.objects.filter(courriel=courriel, actif=True)
         if self.instance and self.instance.id:
             existing = existing.exclude(id=self.instance.id)
+
+        else:
+            # Nouveau chercheur
+            user = User.objects.filter(is_active=True, email=courriel)
+            if user.count():
+                raise forms.ValidationError('Il existe déjà une fiche pour cette adresse électronique')
+
         if existing.count():
             raise forms.ValidationError('Il existe déjà une fiche pour cette adresse électronique')
         return courriel
index 331f747..202930f 100644 (file)
@@ -11,10 +11,12 @@ class Migration(DataMigration):
 
     def forwards(self, orm):
         for personne in orm.Personne.objects.filter(actif=1):
-            user = orm['auth.User'].objects.get(email=personne.courriel)
-            personne.user = user
-            personne.save()
-
+            try:
+                user = orm['auth.User'].objects.get(email=personne.courriel)
+                personne.user = user
+                personne.save()
+            except:
+                pass
 
     def backwards(self, orm):
         for personne in orm.Personne.objects.filter(actif=1):
index 5b107c4..0ee9dab 100644 (file)
@@ -9,6 +9,7 @@ from django.db import models
 from django.db.models import Q
 from django.utils.encoding import smart_str
 from django.utils.hashcompat import sha_constructor
+from django.db.models.signals import post_save
 from djangosphinx.models import SphinxSearch
 
 from savoirs.models import Discipline, SEPManager, SEPSphinxQuerySet, SEPQuerySet, Search
@@ -52,6 +53,10 @@ class Personne(models.Model):
 
         super(Personne, self).save(*args, **kwargs)
 
+    def delete(self):
+        self.actif = False
+        self.save()
+
     @property
     def civilite(self):
         if self.genre == 'm':
@@ -68,6 +73,21 @@ class Personne(models.Model):
     def courriel_display(self):
         return self.courriel.replace(u'@', u' (à) ')
 
+
+def change_personne_courriel(sender, **kwargs):
+    user = kwargs['instance']
+    try:
+        if user.chercheur:
+            if user.email != user.chercheur.courriel:
+                chercheur = user.chercheur
+                chercheur.courriel = user.email
+                chercheur.save()
+    except:
+        pass
+
+post_save.connect(change_personne_courriel, sender=User)
+
+
 class ChercheurQuerySet(SEPQuerySet):
 
     def filter_groupe(self, groupe):
index 1e2d32a..f70662a 100644 (file)
@@ -91,10 +91,11 @@ def activation(request, id_base36, token):
                 password = form.cleaned_data['password']
                 email = chercheur.courriel
                 chercheur.actif = True
-                chercheur.save()
                 user = get_django_user_for_email(email)
                 user.set_password(password)
                 user.save()
+                chercheur.user = user
+                chercheur.save()
 
                 # Auto-login
                 auth_login(request, authenticate(username=email, password=password))
index 702018b..ddb7a3d 100644 (file)
@@ -8,7 +8,7 @@ from rappels import actions
 
 
 class ChercheurRappelAdmin(ChercheurAdmin):
-    list_display = ['__unicode__', 'last_login']
+    list_display = ['__unicode__', 'last_login', 'dernier_rappel']
     list_editable = []
 
     actions = [actions.rappel]
@@ -59,7 +59,11 @@ admin.site.register(RappelModele, RappelModeleAdmin)
 
 
 class RappelUserAdmin(admin.ModelAdmin):
-    readonly_fields = ['date_envoi', 'rappel', 'user']
-    list_display = ['date_envoi', 'rappel', 'user']
+    readonly_fields = ['date_envoi', 'date_demande_envoi', 'rappel', 'user']
+    list_display = ['date_envoi_clean', 'date_demande_envoi_clean', 'rappel', 'user']
     list_filter = ['rappel']
+
+    def has_add_permission(self, obj):
+        return False
+
 admin.site.register(RappelUser, RappelUserAdmin)
diff --git a/auf_savoirs_en_partage/rappels/management/__init__.py b/auf_savoirs_en_partage/rappels/management/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/auf_savoirs_en_partage/rappels/management/commands/__init__.py b/auf_savoirs_en_partage/rappels/management/commands/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/auf_savoirs_en_partage/rappels/management/commands/envoyer_rappels.py b/auf_savoirs_en_partage/rappels/management/commands/envoyer_rappels.py
new file mode 100644 (file)
index 0000000..424f4a9
--- /dev/null
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+
+import datetime
+
+from django.core.management.base import BaseCommand
+from django.template import Context, Template
+from django.core.mail import EmailMessage
+from django.conf import settings
+
+from rappels.models import RappelUser
+
+
+class Command(BaseCommand):
+    help = "Envoi des courriels de rappels par tranche de 300"
+
+    def handle(self, *args, **kwargs):
+
+        logs = RappelUser.objects.filter(date_envoi=None).order_by('date_demande_envoi')[0:300]
+
+        for log in logs:
+
+            template = Template(log.rappel.contenu)
+            domaine = settings.SITE_DOMAIN
+            message = template.render(Context({
+                'chercheur': log.user.chercheur.prenom_nom,
+                'domaine': domaine,
+                'date_limite': log.rappel.date_limite
+            }))
+            email = EmailMessage(log.rappel.sujet,
+                                 message,
+                                 settings.CONTACT_EMAIL,
+                                 [log.user.email])
+            email.send()
+
+            log.date_envoi = datetime.datetime.today()
+            log.save()
diff --git a/auf_savoirs_en_partage/rappels/migrations/0004_auto__add_field_rappeluser_date_demande_envoi__chg_field_rappeluser_da.py b/auf_savoirs_en_partage/rappels/migrations/0004_auto__add_field_rappeluser_date_demande_envoi__chg_field_rappeluser_da.py
new file mode 100644 (file)
index 0000000..537ff17
--- /dev/null
@@ -0,0 +1,91 @@
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        
+        # Adding field 'RappelUser.date_demande_envoi'
+        db.add_column('rappels_rappeluser', 'date_demande_envoi', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, null=True, blank=True), keep_default=False)
+
+        # Changing field 'RappelUser.date_envoi'
+        db.alter_column('rappels_rappeluser', 'date_envoi', self.gf('django.db.models.fields.DateTimeField')(null=True))
+
+
+    def backwards(self, orm):
+        
+        # Deleting field 'RappelUser.date_demande_envoi'
+        db.delete_column('rappels_rappeluser', 'date_demande_envoi')
+
+        # User chose to not deal with backwards NULL issues for 'RappelUser.date_envoi'
+        raise RuntimeError("Cannot reverse this migration. 'RappelUser.date_envoi' and its values cannot be restored.")
+
+
+    models = {
+        'auth.group': {
+            'Meta': {'object_name': 'Group'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '80', 'unique': 'True'}),
+            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+        },
+        'auth.permission': {
+            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
+            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+        },
+        'auth.user': {
+            'Meta': {'object_name': 'User'},
+            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+            'username': ('django.db.models.fields.CharField', [], {'max_length': '30', 'unique': 'True'})
+        },
+        'contenttypes.contenttype': {
+            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+        },
+        'rappels.rappel': {
+            'Meta': {'object_name': 'Rappel'},
+            'contenu': ('django.db.models.fields.TextField', [], {}),
+            'date_cible': ('django.db.models.fields.DateField', [], {}),
+            'date_creation': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'date_limite': ('django.db.models.fields.DateField', [], {}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'sujet': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'user_creation': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+        },
+        'rappels.rappelmodele': {
+            'Meta': {'object_name': 'RappelModele'},
+            'contenu': ('django.db.models.fields.TextField', [], {}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'nom': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'sujet': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        'rappels.rappeluser': {
+            'Meta': {'ordering': "['-date_envoi']", 'object_name': 'RappelUser'},
+            'date_demande_envoi': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'null': 'True', 'blank': 'True'}),
+            'date_envoi': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'rappel': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rappels.Rappel']"}),
+            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+        }
+    }
+
+    complete_apps = ['rappels']
index b4979fc..5b6b48f 100644 (file)
@@ -23,7 +23,8 @@ class Rappel(models.Model):
 class RappelUser(models.Model):
     rappel = models.ForeignKey(Rappel, verbose_name="rappel")
     user = models.ForeignKey(User, verbose_name="utilisateur")
-    date_envoi = models.DateTimeField("date de l'envoi", auto_now_add=True)
+    date_demande_envoi = models.DateTimeField("date de la demande de l'envoi", null=True, auto_now_add=True)
+    date_envoi = models.DateTimeField("date de l'envoi", null=True)
 
     class Meta:
         verbose_name = "Trace d'un rappel"
@@ -33,27 +34,11 @@ class RappelUser(models.Model):
     def __unicode__(self):
         return "%s - %s" % (self.rappel.sujet, self.user)
 
-    def save(self, *args, **kwargs):
-        super(RappelUser, self).save(*args, **kwargs)
-
-        # Envoi du courriel...
-        from django.template import Context, Template
-        from django.core.mail import EmailMessage
-        from django.conf import settings
-
-        template = Template(self.rappel.contenu)
-        domaine = settings.SITE_DOMAIN
-        message = template.render(Context({
-            'chercheur': self.user.chercheur.prenom_nom,
-            'domaine': domaine,
-            'date_limite': self.rappel.date_limite
-        }))
-        email = EmailMessage(self.rappel.sujet,
-                             message,
-                             settings.CONTACT_EMAIL,
-                             [self.user.email],
-                             settings.ADMINS_SEP)
-        email.send()
+    def date_demande_envoi_clean(self):
+        return self.date_demande_envoi or ''
+
+    def date_envoi_clean(self):
+        return self.date_envoi or 'Pas envoyé'
 
 
 class RappelModele(models.Model):
@@ -87,3 +72,10 @@ class ChercheurRappel(Chercheur):
     def last_login(self):
         return self.user.last_login
     last_login.short_description = "Dernière connexion"
+
+    def dernier_rappel(self):
+        try:
+            return self.user.rappeluser_set.all()[0].date_envoi
+        except:
+            return "Aucun rappel envoyé"
+    dernier_rappel.short_description = 'Dernier rappel'
diff --git a/auf_savoirs_en_partage/savoirs/management/__init__.py b/auf_savoirs_en_partage/savoirs/management/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/auf_savoirs_en_partage/savoirs/management/commands/__init__.py b/auf_savoirs_en_partage/savoirs/management/commands/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/auf_savoirs_en_partage/savoirs/management/commands/sep_export_aiu_hedbib.py b/auf_savoirs_en_partage/savoirs/management/commands/sep_export_aiu_hedbib.py
new file mode 100644 (file)
index 0000000..a87d907
--- /dev/null
@@ -0,0 +1,44 @@
+# encoding: utf-8
+
+import csv
+
+from django.core.management.base import BaseCommand
+from django.db.models import Q
+from django import db
+
+from auf_savoirs_en_partage.savoirs.models import Record
+
+
+class Command(BaseCommand):
+
+    def handle(self, *args, **kwargs):
+        writer = csv.writer(self.stdout)
+        writer.writerow([
+            'Titre', 'Auteur', 'Description', 'Date de modification', 'URI',
+            'Source', 'Collaborateurs', 'Sujet', 'Éditeur', 'Type',
+            'Format', 'Langue', 'Disciplines', 'Thématiques', 'Pays', 'Régions'
+        ])
+        for record in Record.objects.filter(
+            Q(title__contains='unversité') |
+            Q(title__contains='universitaire') |
+            Q(subject__contains='université') |
+            Q(subject__contains='universitaire')
+        ):
+            writer.writerow([x.encode('utf-8') for x in [
+                record.title,
+                record.creator,
+                record.description,
+                record.modified,
+                record.uri,
+                record.source,
+                record.contributor,
+                record.subject,
+                record.publisher,
+                record.type,
+                record.format,
+                record.language,
+                ', '.join(d.nom for d in record.disciplines.all()),
+                ', '.join(t.nom for t in record.thematiques.all()),
+                ', '.join(p.nom for p in record.pays.all()),
+                ', '.join(r.nom for r in record.regions.all())
+            ]])
index b7503a7..ec22245 100644 (file)
@@ -948,7 +948,7 @@ class Search(models.Model):
             actualites=actualites.order_by('-date').filter_type('actu'),
             appels=actualites.order_by('-date').filter_type('appels'),
             evenements=evenements.order_by('-debut'),
-            ressources=ressources.order_by('-id'),
+            ressources=ressources.order_by('-modified'),
             chercheurs=chercheurs.order_by('-date_modification'),
             groupes=groupes.order_by('nom'),
             sites=sites.order_by('-date_maj'),