Merge branch 'Kerl/ldap' into 'master'
The end of Clipper GestioCOF fetches the clipper accounts from an LDAP database and doesn't need to store clippers in a table anymore. You need to run migrations to apply this patch The default behaviour is not to fetch data from the LDAP because you may not have access to it. To test over a ldap database server or in production, you need to set `settings.LDAP_SERVER_URL` to the correct value. Fixes #13 See merge request !140
This commit is contained in:
commit
1060a0a368
17 changed files with 158 additions and 162 deletions
|
@ -9,10 +9,6 @@ For the full list of settings and their values, see
|
|||
https://docs.djangoproject.com/en/1.8/ref/settings/
|
||||
"""
|
||||
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
||||
import os
|
||||
|
||||
|
@ -162,6 +158,8 @@ AUTHENTICATION_BACKENDS = (
|
|||
'kfet.backends.GenericTeamBackend',
|
||||
)
|
||||
|
||||
# LDAP_SERVER_URL = 'ldaps://ldap.spi.ens.fr:636'
|
||||
|
||||
# EMAIL_HOST="nef.ens.fr"
|
||||
|
||||
RECAPTCHA_PUBLIC_KEY = "DUMMY"
|
||||
|
|
|
@ -4,10 +4,6 @@
|
|||
Fichier principal de configuration des urls du projet GestioCOF
|
||||
"""
|
||||
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import autocomplete_light
|
||||
|
||||
from django.conf import settings
|
||||
|
@ -61,7 +57,8 @@ urlpatterns = [
|
|||
name='password_change_done'),
|
||||
# Inscription d'un nouveau membre
|
||||
url(r'^registration$', gestioncof_views.registration),
|
||||
url(r'^registration/clipper/(?P<login_clipper>[\w-]+)$',
|
||||
url(r'^registration/clipper/(?P<login_clipper>[\w-]+)/'
|
||||
r'(?P<fullname>.*)$',
|
||||
gestioncof_views.registration_form2, name="clipper-registration"),
|
||||
url(r'^registration/user/(?P<username>.+)$',
|
||||
gestioncof_views.registration_form2, name="user-registration"),
|
||||
|
|
|
@ -1,18 +1,23 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
from __future__ import unicode_literals
|
||||
from ldap3 import Connection
|
||||
|
||||
from django import shortcuts
|
||||
from django.http import Http404
|
||||
from django.db.models import Q
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from gestioncof.models import CofProfile, Clipper
|
||||
from django.conf import settings
|
||||
|
||||
from gestioncof.models import CofProfile
|
||||
from gestioncof.decorators import buro_required
|
||||
|
||||
|
||||
class Clipper(object):
|
||||
def __init__(self, clipper, fullname):
|
||||
self.clipper = clipper
|
||||
self.fullname = fullname
|
||||
|
||||
|
||||
@buro_required
|
||||
def autocomplete(request):
|
||||
if "q" not in request.GET:
|
||||
|
@ -25,37 +30,51 @@ def autocomplete(request):
|
|||
queries = {}
|
||||
bits = q.split()
|
||||
|
||||
queries['members'] = CofProfile.objects.filter(Q(is_cof=True))
|
||||
queries['users'] = User.objects.filter(Q(profile__is_cof=False))
|
||||
queries['clippers'] = Clipper.objects
|
||||
# Fetching data from User and CofProfile tables
|
||||
queries['members'] = CofProfile.objects.filter(is_cof=True)
|
||||
queries['users'] = User.objects.filter(profile__is_cof=False)
|
||||
for bit in bits:
|
||||
queries['members'] = queries['members'].filter(
|
||||
Q(user__first_name__icontains=bit)
|
||||
| Q(user__last_name__icontains=bit)
|
||||
| Q(user__username__icontains=bit)
|
||||
| Q(login_clipper__icontains=bit))
|
||||
Q(user__first_name__icontains=bit)
|
||||
| Q(user__last_name__icontains=bit)
|
||||
| Q(user__username__icontains=bit)
|
||||
| Q(login_clipper__icontains=bit))
|
||||
queries['users'] = queries['users'].filter(
|
||||
Q(first_name__icontains=bit)
|
||||
| Q(last_name__icontains=bit)
|
||||
| Q(username__icontains=bit))
|
||||
queries['clippers'] = queries['clippers'].filter(
|
||||
Q(fullname__icontains=bit)
|
||||
| Q(username__icontains=bit))
|
||||
Q(first_name__icontains=bit)
|
||||
| Q(last_name__icontains=bit)
|
||||
| Q(username__icontains=bit))
|
||||
queries['members'] = queries['members'].distinct()
|
||||
queries['users'] = queries['users'].distinct()
|
||||
usernames = list(queries['members'].values_list('login_clipper',
|
||||
flat='True')) \
|
||||
+ list(queries['users'].values_list('profile__login_clipper',
|
||||
flat='True'))
|
||||
queries['clippers'] = queries['clippers'] \
|
||||
.exclude(username__in=usernames).distinct()
|
||||
# add clippers
|
||||
|
||||
# Clearing redundancies
|
||||
usernames = (
|
||||
set(queries['members'].values_list('login_clipper', flat='True'))
|
||||
| set(queries['users'].values_list('profile__login_clipper',
|
||||
flat='True'))
|
||||
)
|
||||
|
||||
# Fetching data from the SPI
|
||||
if hasattr(settings, 'LDAP_SERVER_URL'):
|
||||
# Fetching
|
||||
ldap_query = '(|{:s})'.format(''.join(
|
||||
['(cn=*{bit:s}*)(uid=*{bit:s}*)'.format(**{"bit": bit})
|
||||
for bit in bits]
|
||||
))
|
||||
with Connection(settings.LDAP_SERVER_URL) as conn:
|
||||
conn.search(
|
||||
'dc=spi,dc=ens,dc=fr', ldap_query,
|
||||
attributes=['uid', 'cn']
|
||||
)
|
||||
queries['clippers'] = conn.entries
|
||||
# Clearing redundancies
|
||||
queries['clippers'] = [
|
||||
Clipper(clipper.uid, clipper.cn)
|
||||
for clipper in queries['clippers']
|
||||
if str(clipper.uid) not in usernames
|
||||
]
|
||||
|
||||
# Resulting data
|
||||
data.update(queries)
|
||||
|
||||
options = 0
|
||||
for query in queries.values():
|
||||
options += len(query)
|
||||
data['options'] = options
|
||||
data['options'] = sum(len(query) for query in queries)
|
||||
|
||||
return shortcuts.render(request, "autocomplete_user.html", data)
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import autocomplete_light
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
autocomplete_light.register(
|
||||
User, search_fields=('username', 'first_name', 'last_name'),
|
||||
autocomplete_js_attributes={'placeholder': 'membre...'})
|
||||
attrs={'placeholder': 'membre...'}
|
||||
)
|
||||
|
|
17
gestioncof/migrations/0009_delete_clipper.py
Normal file
17
gestioncof/migrations/0009_delete_clipper.py
Normal file
|
@ -0,0 +1,17 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('gestioncof', '0008_py3'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.DeleteModel(
|
||||
name='Clipper',
|
||||
),
|
||||
]
|
|
@ -1,9 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models
|
||||
from django.dispatch import receiver
|
||||
from django.contrib.auth.models import User
|
||||
|
@ -264,15 +260,6 @@ class SurveyAnswer(models.Model):
|
|||
self.survey.title)
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class Clipper(models.Model):
|
||||
username = models.CharField("Identifiant", max_length=20)
|
||||
fullname = models.CharField("Nom complet", max_length=200)
|
||||
|
||||
def __str__(self):
|
||||
return "Clipper %s" % self.username
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class CalendarSubscription(models.Model):
|
||||
token = models.UUIDField()
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
{% if clippers %}
|
||||
<li class="autocomplete-header">Utilisateurs <tt>clipper</tt></li>
|
||||
{% for clipper in clippers %}{% if forloop.counter < 5 %}
|
||||
<li class="autocomplete-value"><a href="{% url 'clipper-registration' clipper.username %}">{{ clipper|highlight_clipper:q }}</a></li>
|
||||
<li class="autocomplete-value"><a href="{% url 'clipper-registration' clipper.clipper clipper.fullname %}">{{ clipper|highlight_clipper:q }}</a></li>
|
||||
{% elif forloop.counter == 5 %}<li class="autocomplete-more">...</a>{% endif %}{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
$(document).ready(function() {
|
||||
$('input#search_autocomplete').yourlabsAutocomplete({
|
||||
url: '{% url 'gestioncof.autocomplete.autocomplete' %}',
|
||||
minimumCharacters: 1,
|
||||
minimumCharacters: 3,
|
||||
id: 'search_autocomplete',
|
||||
choiceSelector: 'li:has(a)',
|
||||
placeholder: "Chercher un utilisateur par nom, prénom ou identifiant clipper",
|
||||
|
|
|
@ -43,7 +43,7 @@ def highlight_user(user, q):
|
|||
@register.filter
|
||||
def highlight_clipper(clipper, q):
|
||||
if clipper.fullname:
|
||||
text = "%s (<tt>%s</tt>)" % (clipper.fullname, clipper.username)
|
||||
text = "%s (<tt>%s</tt>)" % (clipper.fullname, clipper.clipper)
|
||||
else:
|
||||
text = clipper.username
|
||||
text = clipper.clipper
|
||||
return highlight_text(text, q)
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import unicodecsv
|
||||
import uuid
|
||||
from datetime import timedelta
|
||||
|
@ -25,7 +21,7 @@ from gestioncof.models import Event, EventRegistration, EventOption, \
|
|||
from gestioncof.models import EventCommentField, EventCommentValue, \
|
||||
CalendarSubscription
|
||||
from gestioncof.shared import send_custom_mail
|
||||
from gestioncof.models import CofProfile, Clipper, Club
|
||||
from gestioncof.models import CofProfile, Club
|
||||
from gestioncof.decorators import buro_required, cof_required
|
||||
from gestioncof.forms import UserProfileForm, EventStatusFilterForm, \
|
||||
SurveyForm, SurveyStatusFilterForm, RegistrationUserForm, \
|
||||
|
@ -321,11 +317,10 @@ def registration_set_ro_fields(user_form, profile_form):
|
|||
|
||||
|
||||
@buro_required
|
||||
def registration_form2(request, login_clipper=None, username=None):
|
||||
def registration_form2(request, login_clipper=None, username=None, fullname=None):
|
||||
events = Event.objects.filter(old=False).all()
|
||||
member = None
|
||||
if login_clipper:
|
||||
clipper = get_object_or_404(Clipper, username=login_clipper)
|
||||
try: # check if the given user is already registered
|
||||
member = User.objects.get(username=login_clipper)
|
||||
username = member.username
|
||||
|
@ -336,8 +331,8 @@ def registration_form2(request, login_clipper=None, username=None):
|
|||
user_form = RegistrationUserForm(initial={
|
||||
'username': login_clipper,
|
||||
'email': "%s@clipper.ens.fr" % login_clipper})
|
||||
if clipper.fullname:
|
||||
bits = clipper.fullname.split(" ")
|
||||
if fullname:
|
||||
bits = fullname.split(" ")
|
||||
user_form.fields['first_name'].initial = bits[0]
|
||||
if len(bits) > 1:
|
||||
user_form.fields['last_name'].initial = " ".join(bits[1:])
|
||||
|
@ -412,12 +407,12 @@ def registration(request):
|
|||
try:
|
||||
member = User.objects.get(username=username)
|
||||
user_form = RegistrationUserForm(request_dict, instance=member)
|
||||
except User.DoesNotExist:
|
||||
try:
|
||||
clipper = Clipper.objects.get(username=username)
|
||||
login_clipper = clipper.username
|
||||
except Clipper.DoesNotExist:
|
||||
if member.profile.login_clipper:
|
||||
login_clipper = member.profile.login_clipper
|
||||
else:
|
||||
user_form.force_long_username()
|
||||
except User.DoesNotExist:
|
||||
user_form.force_long_username()
|
||||
else:
|
||||
user_form.force_long_username()
|
||||
|
||||
|
|
|
@ -1,16 +1,23 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (absolute_import, division,
|
||||
print_function, unicode_literals)
|
||||
from builtins import *
|
||||
import ldap3
|
||||
|
||||
from django.shortcuts import render
|
||||
from django.http import Http404
|
||||
from django.db.models import Q
|
||||
from gestioncof.models import User, Clipper
|
||||
from django.conf import settings
|
||||
|
||||
from gestioncof.models import User
|
||||
from kfet.decorators import teamkfet_required
|
||||
from kfet.models import Account
|
||||
|
||||
|
||||
class Clipper(object):
|
||||
def __init__(self, clipper, fullname):
|
||||
self.clipper = clipper
|
||||
self.fullname = fullname
|
||||
|
||||
|
||||
@teamkfet_required
|
||||
def account_create(request):
|
||||
if "q" not in request.GET:
|
||||
|
@ -25,58 +32,67 @@ def account_create(request):
|
|||
queries = {}
|
||||
search_words = q.split()
|
||||
|
||||
# Fetching data from User, CofProfile and Account tables
|
||||
queries['kfet'] = Account.objects
|
||||
queries['users_cof'] = User.objects.filter(Q(profile__is_cof = True))
|
||||
queries['users_notcof'] = User.objects.filter(Q(profile__is_cof = False))
|
||||
queries['clippers'] = Clipper.objects
|
||||
queries['users_cof'] = User.objects.filter(profile__is_cof = True)
|
||||
queries['users_notcof'] = User.objects.filter(profile__is_cof = False)
|
||||
|
||||
for word in search_words:
|
||||
queries['kfet'] = queries['kfet'].filter(
|
||||
Q(cofprofile__user__username__icontains = word)
|
||||
| Q(cofprofile__user__first_name__icontains = word)
|
||||
| Q(cofprofile__user__last_name__icontains = word)
|
||||
)
|
||||
Q(cofprofile__user__username__icontains = word)
|
||||
| Q(cofprofile__user__first_name__icontains = word)
|
||||
| Q(cofprofile__user__last_name__icontains = word)
|
||||
)
|
||||
queries['users_cof'] = queries['users_cof'].filter(
|
||||
Q(username__icontains = word)
|
||||
| Q(first_name__icontains = word)
|
||||
| Q(last_name__icontains = word)
|
||||
)
|
||||
Q(username__icontains = word)
|
||||
| Q(first_name__icontains = word)
|
||||
| Q(last_name__icontains = word)
|
||||
)
|
||||
queries['users_notcof'] = queries['users_notcof'].filter(
|
||||
Q(username__icontains = word)
|
||||
| Q(first_name__icontains = word)
|
||||
| Q(last_name__icontains = word)
|
||||
)
|
||||
queries['clippers'] = queries['clippers'].filter(
|
||||
Q(username__icontains = word)
|
||||
| Q(fullname__icontains = word)
|
||||
)
|
||||
Q(username__icontains = word)
|
||||
| Q(first_name__icontains = word)
|
||||
| Q(last_name__icontains = word)
|
||||
)
|
||||
|
||||
# Clearing redundancies
|
||||
queries['kfet'] = queries['kfet'].distinct()
|
||||
|
||||
usernames = list( \
|
||||
usernames = set(
|
||||
queries['kfet'].values_list('cofprofile__user__username', flat=True))
|
||||
queries['kfet'] = [
|
||||
(account, account.cofprofile.user)
|
||||
for account in queries['kfet']
|
||||
]
|
||||
|
||||
queries['kfet'] = [ (account, account.cofprofile.user) \
|
||||
for account in queries['kfet'] ]
|
||||
|
||||
queries['users_cof'] = \
|
||||
queries['users_cof'] = \
|
||||
queries['users_cof'].exclude(username__in=usernames).distinct()
|
||||
queries['users_notcof'] = \
|
||||
queries['users_notcof'] = \
|
||||
queries['users_notcof'].exclude(username__in=usernames).distinct()
|
||||
|
||||
usernames += list( \
|
||||
usernames |= set(
|
||||
queries['users_cof'].values_list('username', flat=True))
|
||||
usernames += list( \
|
||||
usernames |= set(
|
||||
queries['users_notcof'].values_list('username', flat=True))
|
||||
|
||||
queries['clippers'] = \
|
||||
queries['clippers'].exclude(username__in=usernames).distinct()
|
||||
# Fetching data from the SPI
|
||||
if hasattr(settings, 'LDAP_SERVER_URL'):
|
||||
# Fetching
|
||||
ldap_query = '(|{:s})'.format(''.join(
|
||||
['(cn=*{bit:s}*)(uid=*{bit:s}*)'.format(**{"bit": bit}) for bit in bits]
|
||||
))
|
||||
with Connection(settings.LDAP_SERVER_URL) as conn:
|
||||
conn.search(
|
||||
'dc=spi,dc=ens,dc=fr', ldap_query,
|
||||
attributes=['uid', 'cn']
|
||||
)
|
||||
queries['clippers'] = conn.entries
|
||||
# Clearing redundancies
|
||||
queries['clippers'] = [
|
||||
Clipper(clipper.uid, clipper.cn)
|
||||
for clipper in queries['clippers']
|
||||
if str(clipper.uid) not in usernames
|
||||
]
|
||||
|
||||
# Resulting data
|
||||
data.update(queries)
|
||||
|
||||
options = 0
|
||||
for query in queries.values():
|
||||
options += len(query)
|
||||
data['options'] = options
|
||||
data['options'] = sum([len(query) for query in queries])
|
||||
|
||||
return render(request, "kfet/account_create_autocomplete.html", data)
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
<li class="user_category"><span class="text">Utilisateurs clipper</span></li>
|
||||
{% for clipper in clippers %}
|
||||
<li>
|
||||
<a href="{% url "kfet.account.create.fromclipper" clipper.username %}">
|
||||
<a href="{% url "kfet.account.create.fromclipper" clipper.clipper clipper.fullname%}">
|
||||
{{ clipper|highlight_clipper:q }}
|
||||
</a>
|
||||
</li>
|
||||
|
|
|
@ -35,7 +35,8 @@ urlpatterns = [
|
|||
name = 'kfet.account.create_special'),
|
||||
url(r'^accounts/new/user/(?P<username>.+)$', views.account_create_ajax,
|
||||
name = 'kfet.account.create.fromuser'),
|
||||
url(r'^accounts/new/clipper/(?P<login_clipper>.+)$', views.account_create_ajax,
|
||||
url(r'^accounts/new/clipper/(?P<login_clipper>[\w-]+)/(?P<fullname>.*)$',
|
||||
views.account_create_ajax,
|
||||
name = 'kfet.account.create.fromclipper'),
|
||||
url(r'^accounts/new/empty$', views.account_create_ajax,
|
||||
name = 'kfet.account.create.empty'),
|
||||
|
|
|
@ -22,7 +22,7 @@ from django.db.models import F, Sum, Prefetch, Count, Func
|
|||
from django.db.models.functions import Coalesce
|
||||
from django.utils import timezone
|
||||
from django.utils.crypto import get_random_string
|
||||
from gestioncof.models import CofProfile, Clipper
|
||||
from gestioncof.models import CofProfile
|
||||
from kfet.decorators import teamkfet_required
|
||||
from kfet.models import (Account, Checkout, Article, Settings, AccountNegative,
|
||||
CheckoutStatement, GenericTeamToken, Supplier, SupplierArticle, Inventory,
|
||||
|
@ -222,19 +222,20 @@ def account_form_set_readonly_fields(user_form, cof_form):
|
|||
cof_form.fields['login_clipper'].widget.attrs['readonly'] = True
|
||||
cof_form.fields['is_cof'].widget.attrs['disabled'] = True
|
||||
|
||||
def get_account_create_forms(request=None, username=None, login_clipper=None):
|
||||
def get_account_create_forms(request=None, username=None, login_clipper=None,
|
||||
fullname=None):
|
||||
user = None
|
||||
clipper = None
|
||||
clipper = False
|
||||
if login_clipper and (login_clipper == username or not username):
|
||||
# à partir d'un clipper
|
||||
# le user associé à ce clipper ne devrait pas encore exister
|
||||
clipper = get_object_or_404(Clipper, username = login_clipper)
|
||||
clipper = True
|
||||
try:
|
||||
# Vérification que clipper ne soit pas déjà dans User
|
||||
user = User.objects.get(username=login_clipper)
|
||||
# Ici, on nous a menti, le user existe déjà
|
||||
username = user.username
|
||||
clipper = None
|
||||
clipper = False
|
||||
except User.DoesNotExist:
|
||||
# Clipper (sans user déjà existant)
|
||||
|
||||
|
@ -242,9 +243,9 @@ def get_account_create_forms(request=None, username=None, login_clipper=None):
|
|||
user_initial = {
|
||||
'username' : login_clipper,
|
||||
'email' : "%s@clipper.ens.fr" % login_clipper}
|
||||
if clipper.fullname:
|
||||
if fullname:
|
||||
# Prefill du nom et prénom
|
||||
names = clipper.fullname.split()
|
||||
names = fullname.split()
|
||||
# Le premier, c'est le prénom
|
||||
user_initial['first_name'] = names[0]
|
||||
if len(names) > 1:
|
||||
|
@ -308,8 +309,11 @@ def get_account_create_forms(request=None, username=None, login_clipper=None):
|
|||
|
||||
@login_required
|
||||
@teamkfet_required
|
||||
def account_create_ajax(request, username=None, login_clipper=None):
|
||||
forms = get_account_create_forms(request=None, username=username, login_clipper=login_clipper)
|
||||
def account_create_ajax(request, username=None, login_clipper=None,
|
||||
fullname=None):
|
||||
forms = get_account_create_forms(
|
||||
request=None, username=username, login_clipper=login_clipper,
|
||||
fullname=fullname)
|
||||
return render(request, "kfet/account_create_form.html", {
|
||||
'account_form' : forms['account_form'],
|
||||
'cof_form' : forms['cof_form'],
|
||||
|
|
|
@ -17,4 +17,5 @@ asgi-redis==0.14.0
|
|||
statistics==1.0.3.5
|
||||
future==0.15.2
|
||||
django-widget-tweaks==1.4.1
|
||||
ldap3
|
||||
git+https://github.com/Aureplop/channels.git#egg=channels
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
if __name__ == "__main__":
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cof.settings")
|
||||
|
||||
from gestioncof.models import Clipper
|
||||
current = {}
|
||||
print("[ FETCHING ]")
|
||||
for clipper in Clipper.objects.all():
|
||||
current[clipper.username] = clipper
|
||||
print("[ SYNCING ]")
|
||||
for line in sys.stdin:
|
||||
bits = line.split(":")
|
||||
username = bits[0]
|
||||
fullname = bits[4]
|
||||
if username in current:
|
||||
clipper = current[username]
|
||||
if clipper.fullname != fullname:
|
||||
clipper.fullname = fullname
|
||||
clipper.save()
|
||||
print("Updated", username)
|
||||
else:
|
||||
clipper = Clipper(username=username, fullname=fullname)
|
||||
clipper.save()
|
||||
print("Created", username)
|
||||
print("[ DONE ]")
|
|
@ -1,2 +0,0 @@
|
|||
#!/bin/sh
|
||||
ssh cof@sas.eleves.ens.fr ypcat passwd | python sync_clipper.py
|
Loading…
Reference in a new issue