Redmine

Introduction

Redmine est une application web Open Source de gestion complète de projet en mode web, développé en Ruby sur la base du framework Ruby on Rails. Redmine est basé sur des modules et des plugins, chacun pouvant être activé séparément Principales fonctionnalités :

  • gestion multi-projets,
  • gestion fine des droits utilisateurs définis par des rôles,
  • gestion de groupes d’utilisateurs,
  • rapports de bogues (bugs), demandes d’évolutions,
  • Wiki multi-projets,
  • forums multi-projets,
  • news accessibles par RSS / ATOM,
  • notifications par courriel (mail),
  • gestion de feuilles de route, GANTT, calendrier, historique,
  • intégration avec divers suivis de versions : SVN, CVS, Mercurial, Git, Bazaar & Darcs,
  • identification possible via LDAP,
  • multilingue (25 langues disponibles pour la 0.7.0),
  • support de plusieurs bases de données : MySQL, PostgreSQL ou SQLite.

les modules par défaut:

  • Suivi des demandes
  • Suivi du temps passé
  • Publication d’annonces
  • Publication de documents
  • Publication de fichiers
  • Wiki
  • Dépôt de sources
  • Forums de discussion
  • Calendrier
  • Gantt

les points fort, à mon avis de redmine sont:

  • hautement personnalisable et paramétrable: on peut tout gérer via une interface sobre et efficace (utilisation ou non de module, de plugin)
  • multiplateforme et multibase
  • multi-projets et sous projets: tout les projets peuvent être gérés dans un seul outil avec des règles communes
  • gestion de documents
  • gestion fine des droits:on génère des membres, des rôles ayant des droits et pour chaque projets on associe membre et rôle. La gestion des rôles va jusqu’à l’autorisation des statuts par rôle (un key user pour avoir le droit de placer le statut nouveau ou clotûré)
  • gestion propre des rôles et des statuts (il existe des rôles et des statuts lors de l’initialisation de la base mais on peut tout reparamétré)
  • utilisation de champs personnalisables dans les demandes et les catégories (on peut facilement ajouter des notions à remplir dans les demandes)
  • suivi des demandes par mail (création de demande par mail aussi)

le point faible: même si l’outil est open source toutes créations ou modifications impose de fortes connaissances en:

  • SGBD
  • HTML
  • CSS
  • Javascript
  • Ruby
  • framework Rails

cela fait beaucoup

Installation

Cette installation ce fait sous windows mais elle est transposable sous linux L’architecture est la suivante:

  • appli redmine
  • sgbd postgresql
  • serveur web webrick

on télécharge sur le net:

Note

pour l’installation sous linux, le principe reste le même il faut installer ruby, un SGBD puis les différents modules de rails

  • installation de ruby par rubyinstaller-1.8.6-p398 dans C:ruby186
  • décompression de redmine-1.0.4.zip dans C:/users/faoustin/redmine
  • modification du fichier C:/users/faoustin/redmine/config/database.yml.example en C:/users/faoustin/redmine/config/database.yml contenant
production:
  adapter: postgresql
  database: redmine
  host: localhost
  username: redmine
  password: my_password
  encoding: utf8
  schema_search_path: public
  • installation de postgresql 9.0 via postgresql-9.0.1-1-windows.exe
  • création d’une base redmine
CREATE ROLE redmine LOGIN ENCRYPTED PASSWORD 'my_password' NOINHERIT VALID UNTIL 'infinity';
CREATE DATABASE redmine WITH ENCODING='UTF8' OWNER=redmine;
  • puis dans une console installation des modules manquants
gem install i18n -v=0.4.2
gem install rails -v=2.3.5
-- installe plusieurs module dont rack en version 1.0.1
gem install postgres-pr
  • dans une console paramétrage de redmine
cd C:\users\faoustin\redmine
rake generate_session_store
set RAILS_ENV=production
--création des tables de la base
rake db:migrate
--intégration des données de base (choisir le  mode fr)
rake redmine:load_default_data
-- lancement du server webrick
ruby script/server webrick -e production

Note

il est possible de passer dans la commande gem la notion de proxy, par exemple gem install rails -v=2.3.5 -p http://proxy-ancenis.terrena.fr:8080

Note

pour changer le port il faut lancer la commande ruby script/server webrick avec le paramètre -p 3001 par exemple puis modifier GénéralNom d’hôte et chemin dans la partie configuration de redmine

Warning

l’environnement development permet surtout de ne pas utiliser de cache pour webrick

Au niveau serveur web on peut aussi utiliser mongrel qui est écrit en C et ruby On peut aussi associer mongrel +:

liste des plugins

passage à la version 1.3

l’installation est identique mais des versions de softs changent:

puis

gem install rails -v=2.3.14
gem install i18n -v=0.4.2
gem install rack -v=1.1.1 or
gem install rack -v=1.1.2
gem install postgres-pr

installation de redmine en tant que service

Il est possible sous windows XP de créer un service windows qui va lancer le server webrick de votre application. dans notre cas:

  • ruby est installé içi C:/Ruby187
  • redmine est installé dans D:/redmine

Pour cela:

"C:/Program Files/Windows Resource Kits/Tools/"Instsrv.exe redmine "C:/Program Files/Windows Resource Kits/Tools/srvany.exe"
  • modifier la clé de registre “HKEY_LOCAL_MACHINE/SYSTEM/ControlSet001/Services/redmine”
_images/20101216_1.jpg
_images/20101216_2.jpg
  • créer des dépendances avec d’autres services si besoin (ex le service de la base de donnée)
_images/20101228_1.jpg
  • lancer le service
_images/20101216_3.jpg
  • arrêt / lancement des services en ligne de commande
  • créer le service redmine
Net stop redmine
Net start redmine

Note

le changement de theme et l’utilisation de prism (mozilla) permet d’avoir l’aspect d’une application standalone

Warning

il est possible de suivre en tant réel les logs du service en fessant

tail -f log\production.log

installation de redmine sous debian6

Comme souvent cela est plus facile et plus rapide.

Nous allons installer Redmine avec un serveur apache

pour cela:

apt-get install vim postgresql
apt-get install apache2 libapache2-mod-passenger
apt-get install redmine redmine-pgsql librmagick-ruby

Note

lors de l’installation de redmine laisser apt créer et configurer la base postgresql

Nous allons configurer apache

cp /usr/share/doc/redmine/examples/apache2-passenger-alias.conf /etc/apache2/sites-available/redmine.conf
vim /etc/apache2/sites-available/redmine.conf

modifier le fichier /etc/apache2/sites-available/redmine ainsi

  • remplacer “VirtualHost localhost” par “VirtualHost *:80”
  • décommenter Servername pour indiquer par exemple ServerName myservdeb02.myprop.fr

On vérifie les hôtes apache actuellement activé:

root@vps102:~# ls -la /etc/apache2/sites-enabled/
total 8
drwxr-xr-x 2 root root 4096 Aug 8 14:09 .
drwxr-xr-x 7 root root 4096 Aug 8 14:09 ..
lrwxrwxrwx 1 root root 26 Aug 8 14:09 000-default -> ../sites-available/default

on voit que default est actuellement activer, il faut donc le désactiver et activer redmine, activer le module rewrite et relancer apache

a2dissite default
a2ensite redmine.
a2enmod rewrite
/etc/init.d/apache2 reload

et voila il suffit maintenant de ce connecter sur http://myservdeb02.myprop.fr/redmine !!!

Note

la config de redmine est sur /etc/redmine/default/database.yml

installation de la dernière version de redmine

test réalisé sous Debian7.4

apt-get install postgresql postgresql-server-dev-all apache2 subversion rake ruby-dev rubygems librmagick-ruby libopenssl-ruby libpgsql-ruby libapache2-mod-passenger imagemagick libmagickwand-dev libxslt-dev libxml2-dev
gem install -v=3.2.13 rails
gem install -v=2.35.1 selenium-webdriver
gem install rmagick
gem install -v=2.0.2 jquery-rails
gem install -v=1.0.9 coderay
gem install -v=1.5.0 fastercsv
gem install -v=3.0.0 builder
gem install -v=0.3.1 net-ldap
gem install -v=2.3.0 ruby-openid
gem install rack-openid
gem install pg
gem install yard
gem install -v=3.3.2 shoulda
gem install redcarpet
gem install -v=0.13.3 mocha
gem install -v=2.0.0 capybara
gem install -v=1.5.9 nokogiri

création de la base postgresql

su postgres
psql
postgres=# CREATE ROLE redmine LOGIN ENCRYPTED PASSWORD 'redmine' NOINHERIT VALID UNTIL 'infinity';
postgres=# CREATE DATABASE redmine WITH ENCODING='UTF8' OWNER=redmine TEMPLATE template0;
postgres=# \q
exit

modifier /etc/postgresql/9.1/main/postgresql.conf pour listen ‘*’ et port 5432

cd /tmp
svn co http://redmine.rubyforge.org/svn/branches/2.3-stable redmine-2.3
mv redmine-2.3/ /var/lib/redmine
cd /var/lib/redmine
echo "production:
 adapter: postgresql
 database: redmine
 host: localhost
 port:
 username: redmine
 password: redmine
 encoding: utf8
 schema_search_path: public" > config/database.yml
bundle install --without test production
rake generate_secret_token
RAILS_ENV=production rake db:migrate
RAILS_ENV=production rake redmine:load_default_data
ln -s /var/lib/redmine/public /var/www/redmine
chown -R www-data:www-data /var/www/redmine
chmod -R 777 files log tmp public/plugin_assets
echo "RailsBaseURI /redmine" > /etc/apache2/sites-available/redmine
a2ensite redmine
/etc/init.d/apache2 restart

installation de l’envoi des emails

cd /etc/redmine/default
cp /usr/share/redmine/config/email.yml.example .
mv email.yml.example email.yml
vi email.yml
/etc/init.d/apache2 restart

on doit trouver dans email.yml par exemple

production:
    delivery_method: :smtp
    smtp_settings:
        address: srvxxxx1
        port: 25
        domain: myprop-group.com
        authentication: :login
        user_name: "informatiquepz"
        password: "informatique"

intégration ldap

_images/20120628_01.png

installation d’un plugin

redmine_wiki_notes

juste décompresser l’archive et l’installer dans le repertoire plugin

http://www.github.com/dseifert/redmine_wiki_notes

et ajouter dans wiki_syntax.html

<tr><th colspan="3">Wiki Note</th></tr>
<tr><th><img src="../images/note.png" style="border: 1px solid #bbb;" alt="Image" /></th><td>{{note(<em>text</em>)}}</td><td></td></tr>
<tr><th><img src="../images/important.png" style="border: 1px solid #bbb;" alt="Image" /></th><td>{{important(<em>text</em>)}}</td><td></td></tr>
<tr><th><img src="../images/warning.png" style="border: 1px solid #bbb;" alt="Image" /></th><td>{{warning(<em>text</em>)}}</td><td></td></tr>
<tr><th><img src="../images/tip.png" style="border: 1px solid #bbb;" alt="Image" /></th><td>{{tip(<em>text</em>)}}</td><td></td></tr>

todo

Nous allons installer un plugin qui fait la gestion de todo

  • télécharger et décompresser la plugin à l’url http://www.redmine.org/boards/3/topics/4070 (prendre la branche ‘master’)
  • renommer le repertoire du plugin en ‘redmine_todos_plugin’
  • arreter redmine (ex sous windows)
net stop redmine
  • sauvegarder votre base de donnée (ici la base ce nomme redmine)
pg_dump redmine > fichier_de_sortie
  • placer le répertoire ‘redmine_todos_plugin’ dans ‘vendorplugins’
  • lancer dans une console à la racine de votre projet redmine
rake db:migrate_plugins RAILS_ENV=production
  • redémarrer redmine
net start redmine
  • connecter vous en admin et allez voir si le plugin est bien présent + paramètres utilisateurs si besoin

Graphviz

Il est possible d’ajouter un plugin qui permet de créer des graphiques graphviz à la voler

net stop redmine
  • sauvegarder votre base de donnée (ici la base ce nomme redmine)
pg_dump redmine > fichier_de_sortie
  • placer le répertoire ‘mochaco_graphviz’ dans ‘vendorplugins’

Note

il n’est pas utile pour ce plugin de lancer un db:migrate_plugins car le plugin n’a pas d’impact sur la base

  • redémarrer redmine
net start redmine
  • connecter vous en admin et allez voir si le plugin est bien présent + paramètres
_images/20110107_5.jpg

il suffit par la suite d’utiliser la macro graphviz ainsi

{{graphviz(dot,
  digraph sample{
    a -> b -> c;
    b -> d;
    a [label="URL link", URL="http://www.redmine.org"];
    b [label="Wiki link", URL="[[WikiSamplePage]]"];
  }
)}}

Mise en place fonctionnelle

Mon expérience me permet de mettre en avant une démarche d’installation

  • n’autoriser qu’un accès à redmine qu’avec une authentification obligatoire

  • définir les rôles et leurs droits

  • définir les différents statuts d’une demande d’évo (ex demande / analyse / dev / test info / test utilisateur / clos / supprimé)

  • définir les champs à ajouter pour les demandes

    • qu’avons nous besoins pour résoudre une demande de modification et à quel niveau
    • quelle donnée pour la supervision (ex site, demandeur, ...)
    • identification des reports
  • définir les champs à ajouter pour les projets (ex enveloppe budgétaire)

  • créer les projets et sous projets (par défaut pour moi personne ne peut créer de projet hors mis l’admin, un chef de projet peut créer des sous projet)

  • créer membres et les lier aux projets avec leurs rôles respectifs

Ajout de statistique

Il est souvent intéressant d’avoir sur la page d’accueil de redmine (la page welcome) des infos de statistique comme:

  • nombre de ticket ouvert/fermé/encours pour une période de temps
  • répartition des tickets par projet
  • répartition des tickets par contributeur
  • ...

Il existe des plugins qui permettent de faire des graphiques mais je les trouve lourd et souvent pas adapté à une visualisation rapide.

Il est possible par contre de modifier la page welcome en y intégrant des graphiques qui seront calculés régulièrement via un crontab et l’utilisation open-flash-chart

exemple de fichier python permettant de générer des graphiques

pyofc.py

version = '0.1'
author = 'Frederic Aoustin'
description = 'generate data for open flash chart'

class Chart:

    def __init__(self, file, cursor):
        try:
            self._desc = cursor.description
            self._data = cursor.fetchall()
            self._file = open(file,'w')
        except Exception as e:
            raise Exception, 'Error in chart, %s' % e

    def generate(self):
        pass

class PieChart(Chart):
    """cursor:
    |   |title|
    |lb1|val1 |
    |lb2|val2 |
    |lb3|val3 |
    """

    txt = """&bg_colour=#FDFDFD&
&pie=60,#505050,{font-size: 12px; color: #404040;}&
&values=%(values)s&
&pie_labels=%(labels)s&
&colours=#5E83BF,#C11B01,#D2D2FB,#B0C101,#d01f3c,#356aa0,#C79810,#80a033,#9933CC,#CC3399&
"""

    def __init__(self, file, cursor):
        Chart.__init__(self, file, cursor)

    def generate(self):
        id = {}
        id['labels'] = ','.join([str(item[0]) for item in self._data])
        id['values'] = ','.join([str(item[1]) for item in self._data])
        self._file.write(self.txt % id)
        self._file.close()

class BarSketchChart(Chart):
    """cursor:
    |   |y1  |y2  |
    |lb1|val1|val4|
    |lb2|val2|val5|
    |lb3|val3|val6|
    """
    txt = """&x_label_style=11,#303030,2&
&y_label_style=11,#303030&
&y_ticks=0,10,1&
&x_labels=%(labels)s&
&y_min=0&
&y_max=%(max_value)s&
&bg_colour=#FDFDFD&
&x_grid_colour=#FDFDFD&
&y_grid_colour=#FDFDFD&
"""
    txt2 = """&bar_sketch%(cnt)s=55,6,%(color)s,#000000,%(name)s,10&
&values%(cnt)s=%(values)s&
"""
    color = ["#5E83BF","#9933CC","#80a033","#C11B01","#CC3399","#D2D2FB","#B0C101","#d01f3c","#356aa0","#C79810","#80a033","#9933CC","#CC3399"]

    def __init__(self, file, cursor):
        Chart.__init__(self, file, cursor)

    def generate(self):
        id = {}
        id['labels'] = ','.join([str(item[0]) for item in self._data])
        ln = len(self._desc)-1
        m = []
        for i in self._data:
            for j in i[1:]:
                m.append(j)
        id['max_value'] = max(m)
        st = self.txt % id
        k=1
        for i in range(1,ln+1):
            id = {}
            id['values'] = ','.join([str(item[i]) for item in self._data])
            id['name'] = self._desc[i][0]
            id['color'] = self.color[i]
            id['max_value'] = max(m)
            if k == 1:
                id['cnt'] = ''
            else:
                id['cnt']='_%s' % k
            st = st + self.txt2 % id
            k = k+1
        self._file.write(st)
        self._file.close()

class BarGlassChart(BarSketchChart):
    """cursor:
    |   |y1  |y2  |
    |lb1|val1|val4|
    |lb2|val2|val5|
    |lb3|val3|val6|
    """
    txt2 = """&bar_glass%(cnt)s=55,%(color)s,,%(name)s,10&
&values%(cnt)s=%(values)s&
"""

    def __init__(self, file, cursor):
        BarSketchChart.__init__(self, file, cursor)

class LineHollowChart(BarSketchChart):
    """cursor:
    |   |y1  |y2  |
    |lb1|val1|val4|
    |lb2|val2|val5|
    |lb3|val3|val6|
    """
    txt2 = """&line_hollow%(cnt)s=2,%(color)s,%(name)s,10,4&
&values%(cnt)s=%(values)s&
"""

    def __init__(self, file, cursor):
        BarSketchChart.__init__(self, file, cursor)

class AreaHollowChart(BarSketchChart):
    """cursor:
    |   |y1  |y2  |
    |lb1|val1|val4|
    |lb2|val2|val5|
    |lb3|val3|val6|
    """
    txt2 = """&area_hollow%(cnt)s=2,3,25,%(color)s,%(name)s,10,%(color)s&
&values%(cnt)s=%(values)s&
"""

    def __init__(self, file, cursor):
        BarSketchChart.__init__(self, file, cursor)

redminegraph.py (faire un sh pour le mettre dans un crontab)

import psycopg2
import pyofc

link = {'query1':{
                    'con' : "dbname='redmine_default' host='127.0.0.1' port=5432 user='postgres' password='postgres'",
                    'query':"""SELECT MOIS,
CREATED ,
TERMINATED,
(SELECT SUM(B.CREATED) FROM ZZ_SYNTHESE_MOIS AS B WHERE  B.MOIS <= A.MOIS) - (SELECT SUM(B.TERMINATED) FROM ZZ_SYNTHESE_MOIS AS B WHERE  B.MOIS <= A.MOIS) AS OPEN
FROM ZZ_SYNTHESE_MOIS AS A
""",
                    'chart':'LineHollowChart',
                    'file':'/usr/share/redmine/public/graph1.txt'
                 },
        'query2':{
                    'con' : "dbname='redmine_default' host='127.0.0.1' port=5432 user='postgres' password='postgres'",
                    'query':"""
SELECT WEEK,
CREATED ,
TERMINATED,
(SELECT SUM(B.CREATED) FROM ZZ_SYNTHESE_WEEK AS B WHERE  B.WEEK <= A.WEEK) - (SELECT SUM(B.TERMINATED) FROM ZZ_SYNTHESE_WEEK AS B WHERE  B.WEEK <= A.WEEK) AS OPEN
FROM ZZ_SYNTHESE_WEEK AS A""",
                    'chart':'LineHollowChart',
                    'file':'/usr/share/redmine/public/graph2.txt'
                 },
        'query3':{
                    'con' : "dbname='redmine_default' host='127.0.0.1' port=5432 user='postgres' password='postgres'",
                    'query':"""select * from (select
projects.name AS PROJECT,
count(*) *100 / (select count(*) from issues where to_char(issues.created_on, 'YYYY/WW')  > to_char(current_timestamp - interval '12 weeks', 'YYYY/WW') )AS CREATED
from issues, projects
WHERE issues.project_id = projects.id
and to_char(issues.created_on, 'YYYY/WW')  > to_char(current_timestamp - interval '12 weeks', 'YYYY/WW')
group by projects.name) as A where CREATED >0""",
                    'chart':'PieChart',
                    'file':'/usr/share/redmine/public/graph3.txt'
                 },
        'query4':{
                    'con' : "dbname='redmine_default' host='127.0.0.1' port=5432 user='postgres' password='postgres'",
                    'query':"""select * from (select
projects.name AS PROJECT,
count(*) *100 / (select count(*) from issues where to_char(issues.created_on, 'YYYY/MM')  > to_char(current_timestamp - interval '12 months', 'YYYY/MM') )AS CREATED
from issues, projects
WHERE issues.project_id = projects.id
and to_char(issues.created_on, 'YYYY/MM')  > to_char(current_timestamp - interval '12 months', 'YYYY/MM')
group by projects.name) as A where CREATED > 0""",
                    'chart':'PieChart',
                    'file':'/usr/share/redmine/public/graph4.txt'
                 },
        }

for i in link.keys():
    connect = psycopg2.connect(link[i]['con'])
    cursor = connect.cursor()
    cursor.execute(link[i]['query'])
    if link[i]['chart']=='PieChart':
        pyofc.PieChart(link[i]['file'],cursor).generate()
    if link[i]['chart']=='BarSketchChart':
        pyofc.BarSketchChart(link[i]['file'],cursor).generate()
    if link[i]['chart']=='BarGlassChart':
        pyofc.BarGlassChart(link[i]['file'],cursor).generate()
    if link[i]['chart']=='LineHollowChart':
        pyofc.LineHollowChart(link[i]['file'],cursor).generate()
    if link[i]['chart']=='AreaHollowChart':
        pyofc.AreaHollowChart(link[i]['file'],cursor).generate()
    cursor.close()
    connect.close()

création des vues dans redmine

CREATE VIEW ZZ_SYNTHESE_WEEK (WEEK,CREATED, TERMINATED ) AS
SELECT WEEK,
SUM(CREATED) AS CREATED ,
SUM(TERMINATED) AS TERMINATED
FROM(

select
to_char(created_on, 'YYYY/WW') AS WEEK,
 count(*) AS CREATED,
 0 AS TERMINATED
from issues
WHERE to_char(created_on, 'YYYY/WW')  > to_char(current_timestamp - interval '12 weeks', 'YYYY/WW')
group by WEEK
union
select
to_char(updated_on, 'YYYY/WW') AS WEEK,
 0 AS CREATED,
 count(*) AS TERMINATED
from issues, issue_statuses
where status_id= issue_statuses.id
and issue_statuses.is_closed = TRUE
and to_char(updated_on, 'YYYY/WW')  > to_char(current_timestamp - interval '12 weeks', 'YYYY/WW')
group by WEEK) AS A
GROUP BY WEEK
ORDER BY WEEK;

CREATE VIEW ZZ_SYNTHESE_MOIS (MOIS,CREATED, TERMINATED ) AS

SELECT MOIS,
SUM(CREATED) AS CREATED ,
SUM(TERMINATED) AS TERMINATED
FROM(

select
to_char(created_on, 'YYYY/MM') AS MOIS,
 count(*) AS CREATED,
 0 AS TERMINATED
FROM issues
WHERE to_char(created_on, 'YYYY/MM')  > to_char(current_timestamp - interval '12 months', 'YYYY/MM')
group by MOIS
union
select
to_char(updated_on, 'YYYY/MM') AS MOIS,
 0 AS CREATED,
 count(*) AS TERMINATED
from issues, issue_statuses
where status_id= issue_statuses.id
and issue_statuses.is_closed = TRUE
and to_char(updated_on, 'YYYY/MM')  > to_char(current_timestamp - interval '12 months', 'YYYY/MM')
group by MOIS) AS A
GROUP BY MOIS
ORDER BY MOIS;

modification de welcomeindex.rhtml

<div class="splitcontentright">
<div id="nagiosinfo"></div>
<br/>
<table>
<tr><td></td><td>sur les 12 dernieres semaines</td></tr>
<tr><td>
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
  codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0"
  width="400" height="280" id="graph-3" align="middle">
<param name="allowScriptAccess" value="sameDomain" />
<param name="movie" value="open-flash-chart.swf?data=graph4.txt" />
<param name="quality" value="high" />
<!-- for firefox, nescape-->
<embed src="open-flash-chart.swf?data=graph4.txt" width="400" height="280"
  allowScriptAccess="sameDomain" align="middle" quality="high"/>
</object>
</td><td>
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
  codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0"
  width="400" height="280" id="graph-3" align="middle">
<param name="allowScriptAccess" value="sameDomain" />
<param name="movie" value="open-flash-chart.swf?data=graph2.txt" />
<param name="quality" value="high" />
<!-- for firefox, nescape-->
<embed src="open-flash-chart.swf?data=graph2.txt" width="400" height="280"
  allowScriptAccess="sameDomain" align="middle" quality="high"/>
</object>
</td></tr>
<tr><td></td><td>Sur les 12 derniers mois</td></tr>
<tr><td>
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
  codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0"
  width="400" height="280" id="graph-3" align="middle">
<param name="allowScriptAccess" value="sameDomain" />
<param name="movie" value="open-flash-chart.swf?data=graph3.txt" />
<param name="quality" value="high" />
<!-- for firefox, nescape-->
<embed src="open-flash-chart.swf?data=graph3.txt" width="400" height="280"
  allowScriptAccess="sameDomain" align="middle" quality="high"/>
</object>
</td><td>
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
  codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0"
  width="400" height="280" id="graph-3" align="middle">
<param name="allowScriptAccess" value="sameDomain" />
<param name="movie" value="open-flash-chart.swf?data=graph1.txt" />
<param name="quality" value="high" />
<!-- for firefox, nescape-->
<embed src="open-flash-chart.swf?data=graph1.txt" width="400" height="280"
  allowScriptAccess="sameDomain" align="middle" quality="high"/>
</object>
</td></tr>
</table>

</div>

<% content_for :header_tags do %>
<%= auto_discovery_link_tag(:atom, {:controller => 'news', :action => 'index', :key => User.current.rss_key, :format => 'atom'},
                                   :title => "#{Setting.app_title}: #{l(:label_news_latest)}") %>
<%= auto_discovery_link_tag(:atom, {:controller => 'projects', :action => 'activity', :key => User.current.rss_key, :format => 'atom'},
                                   :title => "#{Setting.app_title}: #{l(:label_activity)}") %>
<% end %>


<% content_for :header_tags do %>
<%= auto_discovery_link_tag(:atom, {:controller => 'news', :action => 'index', :key => User.current.rss_key, :format => 'atom'},
                                   :title => "#{Setting.app_title}: #{l(:label_news_latest)}") %>
<%= auto_discovery_link_tag(:atom, {:controller => 'projects', :action => 'activity', :key => User.current.rss_key, :format => 'atom'},
                                   :title => "#{Setting.app_title}: #{l(:label_activity)}") %>
<% end %>

sauvegarde

Il faut sauvegarder la base, le code redmine mais aussi les fichiers joints lors de l’utilisation, et les envoyer sur un autre serveur

Dans cette exemple on envoie la sauvegarde sur un serveur zrvpzdev (serveur windows) qui possède un dossier partagé nommé REDMINE

su - postgres -c "pg_dump redmine_default" > redmine_default.sql
tar -cjf redmine_db.tar.gz redmine_default.sql
tar -cjf redmine_varlib.tar.gz /var/lib/redmine
tar -cjf redmine_usrshare.tar.gz /usr/share/redmine
smbclient //myservdev/REDMINE -U administrateur%Numeid@1525$ -c 'put redmine_db.tar.gz'
smbclient //myservdev/REDMINE -U administrateur%Numeid@1525$ -c 'put redmine_varlib.tar.gz'
smbclient //myservdev/REDMINE -U administrateur%Numeid@1525$ -c 'put redmine_usrshare.tar.gz'
su - postgres -c "vacuumdb --full --analyze redmine_default"

Note

si vous êtes dans un domaine il faut modifier le fichier /etc/samba/smb.conf pour mettre workgroup=myprop par exemple

reste à faire

  • installé redmine avec apache sous windows
  • optimiser l’utilisation de postgresql + sauvegarde automatique
  • voir les plugins qui manque (stat + todolist)
  • integration d’un outil de design
  • modification en masse
  • création d’une page mes activités (multi-projet) avec filtre (projet / user/ date)

todolist

  • generation de rss
  • rôle sur la validation des taches d’autres (valider les tâches des autres)
  • validation des taches doit entrainer des “maj” dans la demande
  • filtre dans les taches (projet assigné)
  • design
  • suppression du choix de la demande