--- /dev/null
+VERSION = $(shell dpkg-parsechangelog | sed -n 's/^Version: //p')
+DIST = $(shell dpkg-parsechangelog | sed -n 's/^Distribution: //p')
+
+all: build
+
+build:
+
+install:
+ install -m 0755 -d $(DESTDIR)/usr/sbin
+ install -m 0755 auf-refer $(DESTDIR)/usr/sbin/
+ install -m 0755 -d $(DESTDIR)/etc/auf-refer
+ install -m 0644 *.conf $(DESTDIR)/etc/auf-refer/
+ install -m 0755 -d $(DESTDIR)/var/lib/auf-refer
+
+clean:
+
+test:
+ debuild -I.git -I*.ex -b -us -uc && sudo debi
+
+release:
+ debuild -I.git -I*.ex -tc && debrelease --dput $(DIST)-test
+
--- /dev/null
+Pré-requis : avoir accès à un site web servant les référentiels AuF.
+Par défaut il faut avoir accès à http://intranet.auf/ et donc au RPV.
+Mais ce paquet peut aussi servir à mettre en place un tel site web.
+
+Ce paquet effectuera une copie puis une mise à jour automatique des
+référentiels AuF sélectionnés.
+
+La sélection des référentiels se fait avec la commande "auf-refer".
+La copie sera déposée dans "/var/lib/auf-refer/" au format JSON.
+
+La mise à jour sera effectuée automatiquement chaque jour à 7h et à 13h.
+On peut aussi la forcer manuellement avec "sudo auf-refer -u".
+
+Le processus de mise à jour est optimisé pour ne faire un téléchargement
+que s'il y a eu des changements depuis le téléchargement précédent.
+
+ -- Progfou <jean-christophe.andre@auf.org> Thu, 16 Jul 2009 04:40:39 +0700
--- /dev/null
+Alias /auf-refer/ /var/lib/auf-refer/
+<Location /auf-refer>
+ Order deny,allow
+ Deny from All
+ Allow from 127.0.0.0/255.0.0.0
+ Allow from 10.0.0.0/255.0.0.0
+ Options Indexes
+ <IfModule mod_mime.c>
+ AddType application/json .json
+ AddCharset UTF-8 .json
+ </IfModule>
+</Location>
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""Copie et mise à jour des référentiels AuF.
+
+Copyright ©2009 Agence universitaire de la Francophonie
+Licence : GPL version 3
+Auteur : Progfou <jean-christophe.andre@auf.org>
+
+Dépendances Debian : python >= 2.5, python-simplejson
+"""
+
+PROG_NAME = 'auf-refer'
+RUN_USER = 'auf-refer'
+DIR_BASE = '/var/lib/auf-refer/'
+URL_BASE = 'http://intranet.auf/auf-refer/'
+
+f = file('/etc/auf-refer/auf-refer.conf')
+lines = filter(lambda l: not l.startswith('#'), f.readlines())
+config = dict(map(lambda l: map(lambda s: s.strip(), l.split('=')), lines))
+
+URL_BASE = config.get('URL_BASE', URL_BASE).rstrip('/') + '/'
+
+__all__ = ( 'RUN_USER', 'DIR_BASE', 'URL_BASE' )
+
+USAGE = """Usages (à lancer en tant que "root", par exemple via "sudo") :
+ auf-refer [-f] -a <ref> - copie un nouveau référentiel
+ auf-refer -d <ref> - supprime un référentiel
+ auf-refer [-f] -u - met à jour les référentiels
+ auf-refer -l - liste les référentiels copiés
+ auf-refer -L - liste les référentiels disponibles
+ auf-refer [-f] -A - copie tous les référentiels disponibles
+
+L'option -f permet de forcer le rechargement à travers un proxy/cache.
+"""
+
+TIME_FORMAT = '%a, %d %b %Y %H:%M:%S GMT'
+
+from sys import argv, exit, stderr
+from getopt import getopt, GetoptError
+from pwd import getpwnam
+from os import getuid, setgid, setuid, listdir, utime, unlink
+from os.path import join, exists, getmtime
+from time import gmtime, strftime
+from calendar import timegm
+from urllib2 import Request, urlopen, HTTPError, URLError
+from cStringIO import StringIO
+from gzip import GzipFile
+from simplejson import loads
+
+def update_referentiel(referentiel, force=False):
+ headers = {}
+ headers['Accept-Encoding'] = 'x-gzip'
+ if force:
+ headers['Pragma'] = 'no-cache'
+ filename = join(DIR_BASE, referentiel)
+ if exists(filename):
+ # n'effectuer le chargement qu'en cas de nouvelle version
+ mtime = gmtime(getmtime(filename))
+ headers['If-Modified-Since'] = strftime(TIME_FORMAT, mtime)
+ else:
+ # fichier vide à date très ancienne pour déclencher la synchro
+ try:
+ switch_user()
+ file(filename, 'a').close()
+ except IOError, msg:
+ raise RuntimeError, \
+ u"La création du référentiel a été refusée : %s" % msg
+ utime(filename, (0, 0))
+ url = URL_BASE + referentiel
+ req = Request(url, None, headers)
+ try:
+ u = urlopen(req)
+ except HTTPError, e:
+ if e.code == 304:
+ return
+ raise RuntimeError, \
+ u"L'URL suivante renvoie un code d'erreur %s :\n %s" \
+ % (e.code, url)
+ except URLError:
+ raise RuntimeError, u"L'URL suivante est inaccessible :\n %s" % url
+ i = u.info()
+ if referentiel.endswith('.json') and i.type != 'application/json':
+ u.close()
+ raise RuntimeError, \
+ u"Le type des données chargées n'est pas JSON mais '%s'." % i.type
+ data = u.read()
+ if i.get('content-encoding') == 'x-gzip':
+ data = GzipFile('', 'r', 0, StringIO(data)).read()
+ u.close()
+ if referentiel.endswith('.json'):
+ try:
+ loads(data, encoding='utf-8')
+ except ValueError:
+ raise RuntimeError, u"Les données ne sont pas au format JSON."
+ # si on est arrivé jusqu'ici c'est que tout va bien... on enregistre !
+ try:
+ switch_user()
+ f = file(filename, 'wb')
+ except IOError, msg:
+ raise RuntimeError, \
+ u"L'écriture du référentiel a été refusée : %s" % msg
+ f.write(data)
+ f.close()
+ # on fixe la date donnée par le serveur, le cas échéant
+ mtime = i.getdate('last-modified')
+ if mtime:
+ mtime = timegm(mtime)
+ utime(filename, (mtime, mtime))
+
+def add_referentiel(referentiel, force=False):
+ if referentiel in listdir(DIR_BASE):
+ raise RuntimeError, \
+ u"Le référentiel '%s' avait déjà été ajouté." % referentiel
+ update_referentiel(referentiel, force)
+
+def delete_referentiel(referentiel):
+ if not referentiel in listdir(DIR_BASE):
+ raise RuntimeError, u"Le référentiel '%s' est absent." % referentiel
+ try:
+ switch_user()
+ unlink(join(DIR_BASE, referentiel))
+ except IOError, msg:
+ raise RuntimeError, \
+ u"La suppression du référentiel '%s' a été refusée :\n %s" \
+ % (referentiel, msg)
+
+def update_referentiels(force=False):
+ error_messages = []
+ for referentiel in listdir(DIR_BASE):
+ try:
+ update_referentiel(referentiel, force)
+ except Exception, msg:
+ error_messages.append(unicode(msg))
+ if error_messages:
+ raise RuntimeError, u'\n'.join(error_messages)
+
+def list_referentiels():
+ for referentiel in listdir(DIR_BASE):
+ print referentiel
+
+def get_referentiels_available(force=False):
+ referentiel = 'auf-refer.json'
+ filename = join(DIR_BASE, referentiel)
+ if not exists(filename):
+ update_referentiel(referentiel, force)
+ try:
+ f = open(filename, 'rb')
+ except IOError:
+ raise RuntimeError, u"La liste des référentiels est indisponible."
+ try:
+ referentiels = loads(f.read(), encoding='utf-8')
+ except ValueError:
+ raise RuntimeError, \
+ u"La liste des référentiels n'est pas au format JSON.\n" \
+ u"Essayez les options -f et -u pour la mettre à jour."
+ f.close()
+ return referentiels
+
+def list_referentiels_available(force=False):
+ referentiels = get_referentiels_available(force)
+ for referentiel in sorted(referentiels):
+ print "%-16s : %s" % (referentiel, referentiels[referentiel])
+
+def add_referentiels_available(force=False):
+ referentiels = get_referentiels_available(force)
+ referentiels = set(referentiels) - set(listdir(DIR_BASE))
+ for referentiel in referentiels:
+ update_referentiel(referentiel, force)
+
+_user_switched = False
+def switch_user(username=RUN_USER):
+ global _user_switched
+ if _user_switched:
+ return
+ try:
+ pw = getpwnam(username)
+ except KeyError:
+ raise RuntimeError, u"L'utilisateur '%s' n'existe pas." % username
+ try:
+ setgid(pw.pw_gid)
+ setuid(pw.pw_uid)
+ except OSError:
+ raise RuntimeError, \
+ u"Impossible de basculer vers l'utilisateur '%s'.\n" \
+ u"Réessayez avec 'sudo' !" % username
+ _user_switched = True
+
+if __name__ == '__main__':
+ # interdiction formelle de tourner sous 'root'
+ if getuid() == 0:
+ switch_user()
+
+ try:
+ opts, args = getopt(argv[1:], 'hfa:d:ulLA', ['help', 'force',
+ 'add=', 'delete=', 'update', 'list',
+ 'list-available', 'add-available'])
+ except GetoptError:
+ print USAGE
+ exit(1)
+
+ force = False
+ for opt, arg in opts:
+ if opt in ('-h', '--help'):
+ print USAGE
+ exit(0)
+ elif opt in ('-f', '--force'):
+ force = True
+ else:
+ try:
+ if opt in ('-a', '--add'):
+ add_referentiel(arg, force=force)
+ elif opt in ('-d', '--delete'):
+ delete_referentiel(arg)
+ elif opt in ('-u', '--update'):
+ update_referentiels(force=force)
+ elif opt in ('-l', '--list'):
+ list_referentiels()
+ elif opt in ('-L', '--list-available'):
+ list_referentiels_available(force=force)
+ elif opt in ('-A', '--add-available'):
+ add_referentiels_available(force=force)
+ except RuntimeError, msg:
+ print >>stderr, u'%s' % msg
+
+ if not opts:
+ print USAGE
+ exit(0)
+
--- /dev/null
+URL_BASE=http://intranet.auf/auf-refer
--- /dev/null
+.TH AUF-REFER 8 "25 juin 2009"
+.\"
+.\" Some roff macros, for reference:
+.\" .nh disable hyphenation
+.\" .hy enable hyphenation
+.\" .ad l left justify
+.\" .ad b justify to both left and right margins
+.\" .nf disable filling
+.\" .fi enable filling
+.\" .br insert line break
+.\" .sp <n> insert n+1 empty lines
+.\" for manpage-specific macros, see man(7)
+.SH NAME
+auf-refer \- outil de copie et mise à jour des réferentiels AuF
+.SH SYNOPSIS
+\fBauf-refer\fP [\fB-f\fP] \fB-a\fP \fIreferentiel\fP
+.br
+\fBauf-refer\fP \fB-d\fP \fIreferentiel\fP
+.br
+\fBauf-refer\fP \fB-h\fP | \fB-l\fP
+.br
+\fBauf-refer\fP [\fB-f\fP] \fB-u\fP | \fB-L\fP | \fB-A\fP
+.SH DESCRIPTION
+Cette page de manuel documente brièvement la commande \fBauf-refer\fP.
+.PP
+.SH OPTIONS
+Ce programme suit la syntaxe habituelle d'une ligne de commande GNU,
+avec des options longues commençant par deux tirets (`-').
+.TP
+.B \-h, \-\-help
+Montre un résumé des options.
+.TP
+.B \-L, \-\-list-available
+Liste les référentiels disponibles. Cette liste est obtenue depuis un référentiel spécial nommé \fBauf-refer.json\fP. L'option \fB-f\fP permet de forcer le chargement à travers un proxy/cache.
+.TP
+.B \-A, \-\-add-available
+Copie tous les référentiels disponibles. Il seront ensuite mis à jour, soit automatiquement à 7h et 13h (en heure locale), soit manuellement avec l'option \fB-u\fP. L'option \fB-f\fP permet de forcer le chargement à travers un proxy/cache.
+.TP
+.B \-a, \-\-add
+Copie un nouveau référentiel. Il sera ensuite mis à jour, soit automatiquement à 7h et 13h (en heure locale), soit manuellement avec l'option \fB-u\fP. L'option \fB-f\fP permet de forcer le chargement à travers un proxy/cache.
+.TP
+.B \-l, \-\-list
+Liste les référentiel copiés.
+.TP
+.B \-u, \-\-update
+Met à jour les référentiels immédiatement. L'option \fB-f\fP permet de forcer le chargement à travers un proxy/cache.
+.TP
+.B \-d, \-\-delete
+Supprime un référentiel.
+.SH FILES
+.TP
+.B /etc/auf-refer/auf-refer.conf
+Fichier de configuration de cet outil.
+.br
+On y trouvera en particulier l'option suivante :
+.TP
+.B URL_BASE
+URL de base pour la copie des référentiels. Par défaut cette URL est positionnée sur \fBhttp://intranet.auf/auf-refer\fP.
+.SH AUTHOR
+L'outil auf-refer a été écrit par Progfou <jean-christophe.andre@auf.org>.
+.PP
+Cette page de manuel a été écrite par Progfou <jean-christophe.andre@auf.org>,
+pour le projet Debian (mais peut être utilisé par d'autres).
--- /dev/null
+auf-refer (0.5) jaunty; urgency=low
+
+ * Le projet "auf-referentiels" devient "auf-refer", comprend qui peut... ;-)
+
+ -- Progfou <jean-christophe.andre@auf.org> Thu, 16 Jul 2009 05:08:44 +0700
+
+auf-refer (0.4) jaunty; urgency=low
+
+ * On n'impose plus la configuration Apache (sur remarque de Thomas).
+ * Suppression de la configuration via debconf (sur remarque de Thomas).
+ * Documentation du fichier de configuration dans la page de manuel.
+ * Nettoyage (effectif) des copies de référentiels en cas de purge.
+
+ -- Progfou <jean-christophe.andre@auf.org> Thu, 25 Jun 2009 15:44:01 +0700
+
+auf-refer (0.3) jaunty; urgency=low
+
+ * Reformulation de quelques messages d'erreurs.
+ * Meilleur support des erreurs sur la liste des référentiels.
+ * Ajout des informations MIME pour JSON dans la configuration Apache.
+ * Ajout d'une option -A pour copier tous les référentiels d'un coup.
+
+ -- Progfou <jean-christophe.andre@auf.org> Thu, 25 Jun 2009 14:38:36 +0700
+
+auf-refer (0.2) jaunty; urgency=low
+
+ * Utilisation d'un compte (et groupe) dédié : auf-refer
+ * Création de postinst/postrm et adaptation du cron.d en conséquence.
+ * Ajout du choix de l'URL de base via debconf et changement de la
+ valeur par défaut pour http://intranet.auf/auf-refer/
+ * Installation d'un fichier de configuration pour Apache 2.x.
+ * Création d'une page de manuel et mise à jour du README.
+
+ -- Progfou <jean-christophe.andre@auf.org> Thu, 25 Jun 2009 09:51:44 +0700
+
+auf-refer (0.1) jaunty; urgency=low
+
+ * L'outil est fonctionnel, allons-y pour un empaquetage Debian.
+
+ -- Progfou <jean-christophe.andre@auf.org> Tue, 23 Jun 2009 12:41:52 +0700
+
--- /dev/null
+Source: auf-refer
+Section: auf
+Priority: optional
+Maintainer: Progfou <jean-christophe.andre@auf.org>
+Build-Depends: cdbs, debhelper (>= 5.0.0)
+Standards-Version: 3.7.3
+Homepage: http://git.auf.org/?p=auf-poste-client;a=tree;f=auf-refer
+
+Package: auf-refer
+Architecture: all
+Depends: ${misc:Depends}, adduser, python (>= 2.5), python-simplejson
+Provides: auf-referentiels
+Replaces: auf-referentiels
+Conflicts: auf-referentiels
+Description: outil de copie et mise à jour des réferentiels AuF
+ Ce paquet fournit un outil permettant de copier puis de mettre régulièrement
+ à jour une sélection des référentiels AuF.
--- /dev/null
+This package was debianized by Progfou <jean-christophe.andre@auf.org> on
+Tue, 23 Jun 2009 12:59:04 +0700
+
+It was downloaded from http://git.auf.org/ (projet auf-poste-client)
+
+Upstream Author:
+
+ Progfou <jean-christophe.andre@auf.org>
+
+Copyright Holder:
+
+ Copyright (C) 2009 Agence universitaire de la Francophonie
+ http://www.auf.org/
+
+License:
+
+ This package is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This package is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this package; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+On Debian systems, the complete text of the GNU General
+Public License can be found in `/usr/share/common-licenses/GPL'.
+
+The Debian packaging is (C) 2009, Progfou <jean-christophe.andre@auf.org> and
+is licensed under the GPL, see above.
+
--- /dev/null
+0 7,13 * * * auf-refer [ -x /usr/sbin/auf-refer ] && /usr/sbin/auf-refer -u
--- /dev/null
+usr/sbin
+etc/auf-refer
+var/lib/auf-refer
--- /dev/null
+auf-refer source: maintainer-not-full-name Progfou
+auf-refer: maintainer-not-full-name Progfou
+auf-refer: unknown-section auf
--- /dev/null
+debian/auf-refer.8
--- /dev/null
+#!/bin/sh
+
+set -e
+
+if getent passwd auf-referentiels >/dev/null ; then
+ deluser --quiet --system auf-referentiels
+ delgroup --quiet --system auf-referentiels
+fi
+
+if [ -d /usr/share/auf-referentiels ] ; then
+ mv /usr/share/auf-referentiels /var/lib/auf-refer
+fi
+
+if ! getent passwd auf-refer >/dev/null ; then
+ adduser --disabled-password --quiet --system \
+ --home /var/lib/auf-refer --no-create-home \
+ --group auf-refer
+fi
+
+if [ -d /var/lib/auf-refer ] ; then
+ chown -R auf-refer:auf-refer /var/lib/auf-refer
+ chmod 0755 /var/lib/auf-refer
+fi
+
+#DEBHELPER#
+
+exit 0
--- /dev/null
+#!/bin/sh
+
+set -e
+
+#DEBHELPER#
+
+if [ "$1" = "purge" ] ; then
+ rm -rf /var/lib/auf-refer
+ deluser --quiet --system auf-refer
+ delgroup --quiet --system auf-refer
+fi
+
+exit 0
--- /dev/null
+#!/usr/bin/make -f
+
+DEB_MAKE_INSTALL_TARGET=install DESTDIR=$(DEB_DESTDIR)
+include /usr/share/cdbs/1/rules/debhelper.mk
+include /usr/share/cdbs/1/class/makefile.mk
+include /usr/share/cdbs/1/rules/utils.mk