Administration système Unix et divagations diverses

Aller au contenu | Aller au menu | Aller à la recherche

samedi 30 mars 2013

Installer DMSF sur Redmine 1.4

DMSF est un plugin permettant d'ajouter un workflow de gestion documentaire à Redmine. Il a été libéré en 2011 et publié sur Google Code. La dernière news sur le site indique que le mainteneur n'a plus le temps de s'occuper du projet et qu'il laisse tomber. Le projet est donc désormais chez GitHub. La doc d'installation est assez succincte et confuse sur ce dernier. En effet, on y lit que DMSF est compatible avec Redmine 1.[234].x mais juste en dessous Redmine 2.0x est donné comme prérequis à partir de la version 1.4.4.

Le problème est que la version 2 de redmine n'arrivera vraisemblablement sous Debian qu'après la release de Wheezy (qui d'après les oracles n'a jamais été aussi proche…), puisqu'il est dans exp. Le site ne propose aucun lien de téléchargement hormis sur Google Code qui correspond à une version 1.2.2. Ne vous laissez pas avoir (comme moi), la numérotation ne suit en rien celle de redmine et tenter d'installer le plugin sur une 1.4 à partir d'une des branches du repo Git ne mènera à rien. Il faut donc récupérer la 1.2.2 sur Google Code.

J'ai fait une install sans Xapian (la recherche fulltext), je tenterais certainement de l'ajouter plus tard. La procédure est la suivante :

  • décompressez l'archive, placez son contenu dans /usr/share/redmine/vendor/plugins ;
  • vérifiez que www-data peut écrire dans /usr/share/redmine/public/plugins_assets ;
  • lancez un coup de rake db:migrate:plugins RAILS_ENV=production. Cela devrait modifier la base pour y ajouter DMSF ;
  • lancez rake redmine:dmsf_convert_documents project=identifiant-projet RAILS_ENV="production" pour chaque projet que vous souhaitez convertir ;
  • redémarrez redmine.

Normalement il accepte de redémarrer et quand vous cliquez sur "DMSF" dans un projet, vous devriez… Vous prendre une erreur 500. C'est du à une modification du fonctionnement des plugins en 1.4 qui doivent déclarer explicitement leurs routes (si j'ai bien compris le fonctionnement de cette usine à gaz), le patch suivant (suivi d'un restart Apache) résoud le problème :

--- ./vendor/plugins/redmine_dmsf/config/routes.rb      2011-07-04 15:36:36.000000000 +0200
+++ ./vendor/plugins/redmine_dmsf/config/routes.rb     2013-03-30 08:25:43.673406115 +0100
@@ -17,6 +17,22 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 ActionController::Routing::Routes.draw do |map|
-  map.resources :dmsf
+  map.resources :dmsf, :only => [:new, :create, :show, :edit], :member => {
+    'edit_root' => :get,
+    'entries_operation' => :post,
+    'entries_email' => :post,
+    'notify_activate' => :post,
+    'notify_deactivate' => :post,
+    'save_root' => :post,
+    'delete_entries' => :post,
+    'delete' => :post,
+    'save' => :post
+  }
   map.resources :dmsf_files
+  map.connect 'dmsf/:id/dmsf_files/:action', :controller => 'dmsf_files'
+  map.connect 'dmsf/:id/dmsf_state/:action', :controller => 'dmsf_state'
+  map.connect 'dmsf/:id/dmsf_detail/:action', :controller => 'dmsf_detail'
+  map.connect 'dmsf/:id/dmsf_upload/:action', :controller => 'dmsf_upload'
+  map.connect 'dmsf/:id/dmsf_files_copy/:action', :controller => 'dmsf_files_copy'
+  map.connect 'dmsf/dmsf_folders_copy/:action', :controller => 'dmsf_folders_copy'
+  map.connect 'dmsf/:id/user_pref_save/:action', :controller => 'user_pref_save'
 end

Et voilà, DMSF est installé. Si jamais il y a un problème de permissions sur /usr/share/redmine/public/plugins_assets, les ressources du plugin ne sont pas copiées (et malgré plusieurs tentatives, même après correction elles ne le sont pas), il suffit de copier à la main /usr/share/redmine/vendor/plugins/redmine_dmsf/assets  vers /usr/share/redmine/public/plugins_assets/redmine_dmsf.

En espérant que ça fasse gagner du temps à des gens…

vendredi 24 février 2012

Hibernate et java.lang.IllegalArgumentException: object is not an instance of declaring class

Une simple note qui pourrait aider ceux qui rencontrent le problème. Une des causes de l'exception peut être la présence deux deux méthodes getXXX et isXXX sur la même classe persistante qui ne renvoient pas le même type de données, Hibernate essaie alors d'invoquer les méthodes de l'objet renvoyé par getXXX sur le résultat de isXXX (puisque les deux sont considérés comme des getters sur XXX). Il faut donc renommer ou supprimer le isXXX.

C'était un article bref mais intense.

jeudi 8 septembre 2011

PDF::API2 en CGI et "malformed xref"

PDF::API2 est un module perl pour la manipulation de fichiers PDF. Il peut être utilisé en combinaison avec un script CGI pour envoyer un fichier directement à un client. Quelque chose du genre :

use PDF::API2;
use CGI;

my $cgi = CGI->new;
my $pdf = new PDF::API2();
# …
print $cgi->header(-type => 'application/pdf', -Content_Disposition => 'attachment; filename=monpdf.pdf');
# Envoie le PDF sur la sortie standard (vers le client)
$pdf->saveas('-');

Le PDF ainsi généré pourra être ouvert par des lecteurs basés sur libpoppler (et peut être d'autres) mais Acrobat Reader refusera en prétendant qu'il est corrompu. En essayant de rouvrir le même PDF avec PDF::API2, celui-ci vous enverra gentiment bouler avec un Malformed xref in PDF file at /usr/share/perl5/PDF/API2/Basic/PDF/File.pm line 1198..

En fait, les sections xref des PDF utilisent des informations comprenant des déplacements dans le fichier. Pour les obtenir, PDF::API2 utilise le déplacement courant du fichier dans lequel il est en train d'écrire. Le problème est que lorsque l'on est en CGI, l'écriture des headers décale le déplacement courant de la taille de ceux-ci, les déplacement indiqués dans la XRef sont donc invalides.

Pour résoudre le problème, il suffit de modifier légèrement la génération du PDF en l'écrivant dans une chaine puis en l'affichant :

# $pdf->saveas('-');
print $pdf->stringify();

Et l'erreur disparaît, Acrobat Reader est content…

mardi 6 septembre 2011

Timeout avec GTKmm

Petit extrait de code pour créer un timeout avec GTKmm. À adapter proprement pour l'utilisation.

// Variable globale (sale) pointant sur le timeout
Glib::RefPtr<Glib::TimeoutSource> ts;

// Définition du callback
bool timeout() {
  std::cerr << "Callback timeout" << std::endl;
  // Détruit le timeout, évitant de futures notifications
  ts->destroy();
}

// ...

// le callback sera appelé toutes les 500ms environ (dans la mainloop Gtk)
ts = Glib::TimeoutSource::create(500);
// Indique le callback à appeler
ts->connect(sigc::ptr_fun(&timeout));
// Attache la source au contexte ce qui déclenche
// l'exéccution périodique du callback à partir de l'entrée dans la mainloop
ts->attach();

// ...

mardi 23 août 2011

Améliorer l'affichage de SVN diff

Parce que quand on a goûté à Git, quand même, c'est dur…

Lire la suite...

mercredi 9 mars 2011

Dojotoolkit - Instanciation par programmation de NumberTextBox/CurrencyTextBox

Juste un petit post rapide parce que ça m'a pris pas mal de temps à trouver d'où venait le problème.

Si vous utilisez Dojo, vous essayez peut être d'améliorer les performances en ne passant pas par leur parser (qui analyse tout le DOM) mais en instanciant directement les widgets.

Je suis tombé récemment sur un problème avec des dijit.form.CurrencyTextBox (mais j'imagine qu'il est également valable pour les NumberTextBox) que j'initialise à partir d'input qui ont une valeur. Le widget résultant ne mettait pas en forme la valeur du contrôle avant que l'on lui donne le focus et qu'on le quitte. Pire encore, si la locale n'était pas en-us on se retrouvait avec un message d'erreur "valeur invalide" (en raison de l'utilisation du point décimal à la place de la virgule. Par contre, le même input avec un dojoType passé à dojo.parser.instantiate s'affichait correctement du premier coup.

La solution est toute simple, il suffit de forcer la conversion de la valeur en Number : <code> var field = new dijit.form.NumberTextBox({ value: Number(i.value) }, i); field.startup(); </code>

Si jamais i.value n'est pas un nombre ou est vide, Number(i.value) renverra NaN qui est très bien accepté par le constructeur. En espérant vous avoir fait gagner un peu de temps...

mercredi 17 mars 2010

Utilisation de vtun pour accéder à un réseau distant

Après avoir expliqué comment créer un tunnel avec vtun, nous allons voir comment utiliser ce tunnel pour accéder au LAN se situant derrière la machine distante.

Lire la suite...

vendredi 12 mars 2010

Création d'un tunnel chiffré entre deux machines avec vtun

J'ose pas parler de VPN parce que bon faut pas déconner.

Lire la suite...

jeudi 17 décembre 2009

Debian, java et NoRouteToHostException

Une histoire de réseau qui fonctionne pas en java mais qui fonctionne partout ailleurs...

Lire la suite...

samedi 21 novembre 2009

MySQL et too many open files

Pourquoi qu'il dit "File 'toto.MYD' not found (Errcode: 24) when using LOCK TABLES" ? Elle existe ma table...

Lire la suite...

lundi 16 novembre 2009

Exim, PostgreSQL et l'UTF-8

Deux moyens pour éviter les méchantes erreurs du type PGSQL: query failed: ERREUR: séquence d'octets invalide pour l'encodage « UTF8 » : 0xe76f69 dans le paniclog.

Lire la suite...

vendredi 28 août 2009

Ajout d'une table à une réplication Slony-I

Pourquoi j'irais faire ça alors que ça marche très bien ?

Quelque temps après la mise en place de votre réplication PostgreSQL, vos besoins évoluent et vous voulez avoir un nœud supplémentaire dans votre système de réplication. Voici quelques éléments qui devraient vous y aider.

Lire la suite...

mardi 28 juillet 2009

Création d'un chroot sous Debian

Comment créer un chroot qui sera lancé au démarrage de la machine.

Lire la suite...

Activer le SSL sous PostgreSQL

Des fois ça marche tout seul et des fois non.

Cet article décrit comment faire en sorte de pouvoir utiliser des connexions chiffrées (via SSL/TLS) dans PostgreSQL 8.3.

Lire la suite...

mercredi 22 juillet 2009

VHFFS - Mettre à jour le mot de passe d'un utilisateur mail

Puisque ça peut être utile à quelques personnes, j'ai décidé de créer une catégorie [vhffs] qui recensera des astuces concises sur VHFFS (un système d'hébergement de masse).

Lire la suite...

vendredi 3 juillet 2009

Firewall IPv6

Quelques notes en vrac sur la mise en place d'un firewall sur une machine avec la prise en charge IPv6

Lire la suite...

vendredi 19 juin 2009

Mise en place d'une réplication PostgreSQL avec Slony I

Comment mettre en place une réplication maître/esclave sous PostgreSQL grâce à Slony I (oui oui c'est le billet annoncé il y a 2 mois).

Lire la suite...

mercredi 10 juin 2009

Encodage des caractères sous MySQL

Ou pourquoi utiliser une variable quand on peut en utiliser 36.

Lire la suite...

vendredi 29 mai 2009

Installation des xtables-addons

Les xtables-addons sont un ensemble de modules iptables permettant, entre autres, de filtrer les flux P2P

Lire la suite...

mercredi 13 mai 2009

Logwatch, lenny et le paramètre MailTo

Décidemment, on parle beaucoup de journaux.

Lire la suite...

- page 1 de 2