Outil de copie et mise à jour des réferentiels AuF.
authorProgfou <jean-christophe.andre@auf.org>
Tue, 23 Jun 2009 06:04:51 +0000 (13:04 +0700)
committerProgfou <jean-christophe.andre@auf.org>
Tue, 23 Jun 2009 07:22:23 +0000 (14:22 +0700)
Makefile [new file with mode: 0644]
README [new file with mode: 0644]
auf-referentiels [new file with mode: 0755]
debian/auf-referentiels.dirs [new file with mode: 0644]
debian/changelog [new file with mode: 0644]
debian/compat [new file with mode: 0644]
debian/control [new file with mode: 0644]
debian/copyright [new file with mode: 0644]
debian/cron.d [new file with mode: 0644]
debian/rules [new file with mode: 0755]

diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..6ce7fa8
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,20 @@
+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-referentiels $(DESTDIR)/usr/sbin/
+       install -m 0755 -d $(DESTDIR)/usr/share/auf-referentiels
+
+clean:
+
+test:
+       debuild -I.git -I*.ex -b -us -uc && sudo debi
+
+release:
+       debuild -I.git -I*.ex -tc && debrelease --dput $(DIST)-test
+
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..6ac31ec
--- /dev/null
+++ b/README
@@ -0,0 +1,17 @@
+Pré-requis :
+- avoir accès au RPV, en particulier à http://intranet.auf/
+
+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 dans "/etc/auf-referentiels.conf".
+
+La copie sera déposée dans "/usr/share/auf-referentiels/" au format JSON.
+
+La mise à jour sera effectuée automatiquement chaque jour à 7h et à 13h.
+On peut aussi la forcer manuellement avec "sudo update-auf-referentiels".
+
+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>  Tue, 23 Jun 2009 12:58:21 +0700
diff --git a/auf-referentiels b/auf-referentiels
new file mode 100755 (executable)
index 0000000..685c8a2
--- /dev/null
@@ -0,0 +1,164 @@
+#!/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
+"""
+
+URL_BASE = 'http://intranet.auf/cgi-bin/auf/'
+DIR_BASE = '/usr/share/auf-referentiels/'
+
+__all__ = ( 'URL_BASE', 'DIR_BASE' )
+
+USAGE = """Usages (à lancer en tant que "root", par exemple via "sudo") :
+  update-auf-referentiels -a <ref> - copie un nouveau référentiel
+  update-auf-referentiels -d <ref> - supprime un référentiel
+  update-auf-referentiels -u       - met à jour les référentiels
+  update-auf-referentiels -l       - liste les référentiels copiés
+  update-auf-referentiels -L       - liste 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 os import 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
+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:
+            file(filename, 'a').close()
+        except IOError:
+            raise RuntimeError, u"Écriture refusée, réessayez avec 'sudo' !"
+        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"Impossible d'ouvrir l'URL '%s'." % url
+    i = u.info()
+    if referentiel.endswith('.json') and i.type != 'application/json':
+        u.close()
+        raise RuntimeError, u"Le type 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:
+        f = file(filename, 'wb')
+    except IOError:
+        raise RuntimeError, u"Écriture refusée, réessayez avec 'sudo' !"
+    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 referentiels_list():
+    referentiels = []
+    for referentiel in listdir(DIR_BASE):
+        if referentiel.endswith('.json'):
+            referentiels.append(referentiel)
+    return referentiels
+
+def add_referentiel(referentiel, force=False):
+    if referentiel in referentiels_list():
+        raise RuntimeError, \
+            u"Référentiel '%s' déjà ajouté auparavant." % referentiel
+    update_referentiel(referentiel, force)
+
+def delete_referentiel(referentiel):
+    if not referentiel in referentiels_list():
+        raise RuntimeError, u"Référentiel '%s' absent." % referentiel
+    unlink(join(DIR_BASE, referentiel))
+
+def update_referentiels(force=False):
+    for referentiel in referentiels_list():
+        update_referentiel(referentiel, force)
+
+def list_referentiels():
+    for referentiel in referentiels_list():
+        print referentiel
+
+def list_referentiels_available():
+    referentiel = 'referentiels.json'
+    filename = join(DIR_BASE, referentiel)
+    if not exists(filename):
+        update_referentiel(referentiel)
+    try:
+        f = open(filename, 'rb')
+    except IOError:
+        raise RuntimeError, u"Liste des référentiels indisponible."
+    referentiels = loads(f.read(), encoding='utf-8')
+    f.close()
+    for referentiel in sorted(referentiels):
+        print "%-16s : %s" % (referentiel, referentiels[referentiel])
+
+if __name__ == '__main__':
+    try:
+        opts, args = getopt(argv[1:], 'hfa:d:ulL', ['help', 'force',
+            'add=', 'delete=', 'update', 'list', 'list-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()
+            except RuntimeError, msg:
+                print >>stderr, u'ATTENTION : %s' % msg
+
+    if not opts:
+        print USAGE
+    exit(0)
+
diff --git a/debian/auf-referentiels.dirs b/debian/auf-referentiels.dirs
new file mode 100644 (file)
index 0000000..cd6d7aa
--- /dev/null
@@ -0,0 +1,2 @@
+usr/sbin
+usr/share/auf-referentiels
diff --git a/debian/changelog b/debian/changelog
new file mode 100644 (file)
index 0000000..73035d3
--- /dev/null
@@ -0,0 +1,6 @@
+auf-referentiels (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
+
diff --git a/debian/compat b/debian/compat
new file mode 100644 (file)
index 0000000..7ed6ff8
--- /dev/null
@@ -0,0 +1 @@
+5
diff --git a/debian/control b/debian/control
new file mode 100644 (file)
index 0000000..c5cde55
--- /dev/null
@@ -0,0 +1,14 @@
+Source: auf-referentiels
+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-referentiels
+
+Package: auf-referentiels
+Architecture: all
+Depends: python (>= 2.5), python-simplejson
+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.
diff --git a/debian/copyright b/debian/copyright
new file mode 100644 (file)
index 0000000..e1a2d27
--- /dev/null
@@ -0,0 +1,36 @@
+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.
+
diff --git a/debian/cron.d b/debian/cron.d
new file mode 100644 (file)
index 0000000..05de4df
--- /dev/null
@@ -0,0 +1 @@
+0 7,13 * * *   root    [ -x /usr/sbin/auf-referentiels ] && /usr/sbin/auf-referentiels -u
diff --git a/debian/rules b/debian/rules
new file mode 100755 (executable)
index 0000000..720e507
--- /dev/null
@@ -0,0 +1,6 @@
+#!/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