Écrire un rapport

From Gramps
Revision as of 06:48, 6 May 2010 by Romjerome (talk | contribs) (Rapport de classe)
Jump to: navigation, search
Gramps-notes.png
This page has good information but needs a cleanup. Please make the Gramps Wiki more useful by re‑organizing this page and linking introductory material. Consider also updating the screenshots.

Introduction

Ce tutoriel décrit les bases d'écriture d'un simple rapport utilisant l'infrastructure de GRAMPS. il couvre les processus de gestion d'options, la construction d'un document et de création de rapport.

Les objectifs de ce rapport est de créer une base de données de rapport de synthèse. Il comportera les informations suivantes dans le rapport:

    * Le nombre de personnes dans la base de données
    * Le nombre de garçons et de filles
    * Le nombre de noms de famille uniques.
    * Le prénom le plus commun.

À partir de la version 3.2, également un accès simple aux API de base de données est disponible, accompagnée de Rapports rapides, Gramplets and Addons.


Aperçu

Avant d'entrer dans les détails, il est utile de noter que le rapport devrait comporter trois éléments fondamentaux. Comme expliqué sur la page Addons, les éléments sont dans deux fichiers différents : le fichier code source (càd : report.py) et le fichier d'enregistrement du greffon Gramps (càd : report.gpr.py).

report.py

Rapport de classe
    C'est ce code qui prend les données de la base de données GRAMPS et organise dans la structure du document.
Cette structure peut ensuite être imprimée, visualisée, ou écrite dans un fichier dans une variété de formats.
Cette classe utilise l'interface docgen à l'écart résumé le format de sortie de détails.
Options de la classe
    C'est le code qui fournit les moyens nécessaires pour obtenir des options pour le rapport
en utilisant une variété de mécanismes disponibles.

report.gpr.py

Déclaration d'enregistrement
    Ceci initialise le report par un simple appel de register() dans le module.
Il est trivial, mais sans elle votre rapport ne sera pas disponible dans GRAMPS, même si il est par ailleurs parfaitement écrit.

Un rapport peut être généré potentiellement comme un rapport unique, comme un item de livre GRAMPS, et comme un rapport en ligne de commande. L'enregistrement détermine quels sont les modes activés pour un rapport donné. Le rapport classe ne nécessite aucune connaissance du mode. La classe d'options est là pour fournir des options d'interface pour tous les modes disponibles.

Document d'interface

GRAMPS résumé les tentatives de sortie hors format de document le rapport. Par codage à la docgen classe, le rapport peut générer sa production dans le format désiré par l'utilisateur final. Le document transmis au rapport (self.doc) pourrait représenter une page HTML, OpenDocument, PDF ou dans les autres formats supportés par l'utilisateur. Le rapport n'a pas à se préoccuper des détails du format de sortie, puisque tous les détails sont pris en charge par l'objet document.

Un document est composé de paragraphes, des tableaux, des graphiques et d'objets. Les tableaux et les graphiques des objets ne seront pas couvertes dans ce tutoriel.

Le rapport définit une série de paragraphe et styles, ainsi que leur application par défaut. L'utilisateur peut l'emporter sur la définition de chaque modèle, qui permet à l'utilisateur de personnaliser le rapport. Chaque style de paragraphe doit être nommé spécifiquement, à prévenir les collisions lors de l'impression dans un format livre. Il est recommandé à chaque préfixe style de paragraphe avec un code à trois lettres uniques au rapport.

Paragraphe et styles sont définis dans le make_default_style() la fonction de la classe d'options. Les points sont regroupés en un StyleSheet, que le make_default_style() définit. Pour l'exemple de rapport (DbSummary), les styles de paragraphe sont définies comme suit:

    def make_default_style(self, default_style):

        # Define the title paragraph, named 'DBS-Title', which uses a
        # 18 point, bold Sans Serif font with a paragraph that is centered

        font = docgen.FontStyle()
        font.set_size(18)
        font.set_type_face(docgen.FONT_SANS_SERIF)
        font.set_bold(True)

        para = docgen.ParagraphStyle()
        para.set_header_level(1)
        para.set_alignment(docgen.PARA_ALIGN_CENTER)
        para.set_font(font)
        para.set_description(_('The style used for the title of the page.'))

        default_style.add_style('DBS-Title',para)

        # Define the normal paragraph, named 'DBS-Normal', which uses a
        # 12 point, Serif font.

        font = docgen.FontStyle()
        font.set_size(12)
        font.set_type_face(docgen.FONT_SERIF)

        para = docgen.ParagraphStyle()
        para.set_font(font)
        para.set_description(_('The style used for normal text'))

        default_style.add_style('DBS-Normal',para)

Définir les classes

Rapport de classe

L'utilisateur du rapport de classe doit hériter de la classe Rapport contenues dans le rapport du module. Le constructeur devrait prendre trois arguments (à part la classe exemple lui-même, le plus souvent signalés par un "moi" nom):

    * GRAMPS instance de base de données
    * Personne objet
    * Options de la classe exemple

Le premier est la base de données pour travailler. La deuxième est la personne sur laquelle le rapport est centré. Le troisième est l'instance de la classe d'options définies dans le même rapport, voir la section suivante. Voici un exemple d'un rapport de définition de classe:

  from ReportBase import Report, ReportUtils, ReportOptions

  class ReportClassName(Report):
      def __init__(self,database,person,options_class):
          Report.__init__(self,database,person,options_class)

Le rapport classe le constructeur va initialiser plusieurs variables pour l'utilisateur basé sur les valeurs passées. Il s'agit de:

Self.doc
Le document ouvert exemple prêt pour la sortie. Il s'agit du type docgen, et elle est pas un fichier normal objet.
Self.start_person
Le Personne exemple contenant le début ou la personne centrale (la personne sélectionnée) Lorsque le rapport a été appelée.
Self.database
Le GrampsDbBase objet de base de données
Self.options_class
Le ReportOptions classe passées au rapport

Tout le reste du rapport classe les besoins afin de produire le rapport devrait être obtenu auprès de la options_class. Par exemple, vous pouvez avoir besoin d'inclure le code supplémentaires dans le rapport construction de la classe d'obtenir les options que vous avez définies pour le rapport.

Rapport de la classe must fournir une write_report(). Cette méthode devrait larguer le rapport contenu dans le document déjà ouvert.

      def write_report(self):
          self.doc.start_paragraph("ABC-Title")
          self.doc.write_text(_("Some text"))
          self.doc.end_paragraph()

Le reste du rapport est quasiment classe donnée au rapport écrivain. Selon les objectifs et la portée du rapport, il ya un montant de code en cause. Lorsque l'utilisateur génère le rapport dans n'importe quel mode, la construction de la classe va être exécuté, et ensuite le write_report() méthode sera appelée. Donc, si vous avez écrit que la méthode de cotation belle chose vraiment importante, assurez-vous qu'il est finalement appelée depuis le write_report(). Sinon personne ne la verrez que si en regardant le code.

Options de la classe

    * Options de la classe devrait découler de ReportOptions classe:
  class OptionsClassName(ReportOptions):
      def __init__(self,name,person_id=None):
          ReportOptions.__init__(self,name,person_id)

Il devrait fixer de nouvelles options qui sont spécifiques aux fins du présent rapport, par des raisons de la set_new_options() qui définit options_dict et options_help dictionnaires:

      def set_new_options(self):
          # Options specific for this report
          self.options_dict = {
              'my_fist_option'    : 0,
              'my_second_option'  : '',
          }
          self.options_help = {
              'my_fist_option'    : ("=num","Number of something",
                                     [ "First value", "Second value" ],
                                     True),
              'my_second_option'  : ("=str","Some necessary string for the report",
                                     "Whatever String You Wish"),
        }
  • Il devrait également permettre à la "semi-common" les options qui sont utilisées dans le présent rapport, par des raisons de la enable_options qui définit enable_dict dictionnaire. Les semi-commons sont les options que GRAMPS connaît, mais qui ne sont pas nécessairement présentes dans tous les rapports:
      def enable_options(self):
          # Semi-common options that should be enabled for this report
          self.enable_dict = {
              'filter'    : 0,
          }

Tous les options sont déjà prises en charge par la base de GRAMPS.

  • Pour tout mettre en place de nouvelles options dans la classe d'options, il doit être défini widgets pour fournir les moyens de changer ces options par le biais du dialogue. En outre, il faut définir des méthodes pour extraire les valeurs de ces options dans le widgets et de les mettre ainsi dans la classe variable dictionnaire:
      def add_user_options(self,dialog):
          option_menu = gtk.OptionMenu()
          self.the_menu = gtk.Menu()

          for item_index in range(10):
              item = _("Item numer %d") % item_index
              menuitem = gtk.MenuItem(item)
              menuitem.show()
              self.the_menu.append(menuitem)

          option_menu.set_menu(self.the_menu)
          option_menu.set_history(self.options_dict['my_first_option'])

          dialog.add_option(_('My first option'),option_menu)

          self.the_string_entry = gtk.Entry()
          if self.options_dict['my_second_option']:
              self.the_string_entry.set_text(self.options_dict['my_second_option'])
          else:
              self.the_string_entry.set_text(_("Empty string"))
          self.the_string_entry.show()
          dialog.add_option(_('My second option'),self.the_string_entry)

      def parse_user_options(self,dialog):
          self.options_dict['my_second_option'] = unicode(self.the_string_entry.get_text())
          self.options_dict['my_first_option'] = self.the_menu.get_history()
  • Enfin, les définitions par défaut pour l'utilisateur réglable paragraphe style doit être défini ici, pour former un 'défaut' feuille de style:
      def make_default_style(self,default_style):
          f = BaseDoc.FontStyle()
          f.set_size(10)
          f.set_type_face(BaseDoc.FONT_SANS_SERIF)
          p = BaseDoc.ParagraphStyle()
          p.set_font(f)
          p.set_description(_("The style used for the person's name."))
          default_style.add_style("ABC-Name",p)


Implémentation

Définition de la classe Rapport Options

Dans cet exemple, aucune des options spéciales sont requises. Cela rend la classe d'options très simple. Tout ce qui est nécessaire pour définir les styles par défaut.

class DbSummaryOptions(ReportOptions):

    def __init__(self, name, person_id=None):

        ReportOptions.__init__(self, name, person_id)

    def make_default_style(self, default_style):

        # Define the title paragraph, named 'DBS-Title', which uses a
        # 18 point, bold Sans Serif font with a paragraph that is centered

        font = BaseDoc.FontStyle()
        font.set_size(18)
        font.set_type_face(BaseDoc.FONT_SANS_SERIF)
        font.set_bold(True)

        para = BaseDoc.ParagraphStyle()
        para.set_header_level(1)
        para.set_alignment(BaseDoc.PARA_ALIGN_CENTER)
        para.set_font(font)
        para.set_description(_('The style used for the title of the page.'))

        default_style.add_style('DBS-Title',para)

        # Define the normal paragraph, named 'DBS-Normal', which uses a
        # 12 point, Serif font.

        font = BaseDoc.FontStyle()
        font.set_size(12)
        font.set_type_face(BaseDoc.FONT_SERIF)

        para = BaseDoc.ParagraphStyle()
        para.set_font(font)
        para.set_description(_('The style used for normal text'))

        default_style.add_style('DBS-Normal',para)

Définir le rapport de classe

La mise en place effective de la DbSummary rapport est assez simple. Pas de travail supplémentaire doit être fait pour initialiser la classe, de sorte que les parents __init__ routine est appelée.

Tout le travail se fait dans le write_report(). Cette fonction utilise un GrampsCursor à itérer à travers la carte de la Person qui rassemble les objets et de simples statistiques.

La seule chose de toute complication la détermination de la plupart des communes patronyme. Un dictionnaire Python est utilisé pour stocker le nombre de fois que chaque nom est utilisé. Chaque fois qu'un nom est rencontré, la valeur dans le dictionnaire est incrémenté. Les résultats sont ensuite chargés dans une liste et classés, ce qui nous permet de trouver le nom le plus courant en regardant la dernière inscription dans la liste.

class DbSummaryReport(Report):

    def __init__(self, database, person, options_class):

        Report.__init__(self, database, person, options_class)

    def write_report(self):

        cursor = self.database.get_person_cursor()

        data = cursor.first()

        males = 0
        females = 0
        total = 0
        surname_map = {}
        while data:
            person = RelLib.Person()
            person.unserialize(data[1])

            if person.get_gender() == RelLib.Person.MALE:
                males += 1
            if person.get_gender() == RelLib.Person.FEMALE:
                females += 1
            total += 1

            surname = person.get_primary_name().get_surname()

            if surname_map.has_key(surname):
                surname_map[surname] += 1
            else:
                surname_map[surname] = 1

            data = cursor.next()
        cursor.close()

        slist = []
        for key in surname_map.keys():
            slist.append((surname_map[key],key))
        slist.sort()

        self.doc.start_paragraph("DBS-Title")
        self.doc.write_text(_("Database Summary"))
        self.doc.end_paragraph()

        self.doc.start_paragraph('DBS-Normal')
        self.doc.write_text(_('Number of males : %d') % males)
        self.doc.end_paragraph()

        self.doc.start_paragraph('DBS-Normal')
        self.doc.write_text(_('Number of females : %d') % females)
        self.doc.end_paragraph()

        self.doc.start_paragraph('DBS-Normal')
        self.doc.write_text(_('Total people : %d') % total)
        self.doc.end_paragraph()

        self.doc.start_paragraph('DBS-Normal')
        self.doc.write_text(_('Number of unique surnames : %d') % len(slist))
        self.doc.end_paragraph()

        self.doc.start_paragraph('DBS-Normal')
        self.doc.write_text(_('Most common surname : %s') % (slist[-1][1]))
        self.doc.end_paragraph()

L'enregistrement du rapport

  • L'enregistrement est défini dans un fichier nom.gpr.py.
  • L'enregistrement devrait définir nom interne du rapport (de préférence, seule chaîne avec des caractères spéciaux, utilisable pour rendre l'identification de la ligne de commande et dans les options de stockage, ainsi que pour former le nom du fichier sain pour stocker ses propres modèles). Il devrait aussi définir la catégorie de rapport (texte / graphiques / Code), traduit nom (celui de l'affichage dans les menus), et les modes de transport qui doit être activé pour le rapport (autonome, le carnet de point, de ligne de commande). Enfin, les deux options de rapport classe et la classe devrait être passé à l'enregistrement. Voici par exemple la déclaration d'enregistrement:

Finalement, les classes options et report doivent passer par l'enregistrement. Voici un exemple d'enregistrement :

  plg = newplugin()
  plg.id    = 'un identifiant unique'
  plg.name  = _("Nom du plugin")
  plg.description =  _("Produces a ...")
  plg.version = '1.0'
  plg.gramps_target_version = '3.2'
  plg.status = STABLE
  plg.fname = 'filename.py'
  plg.ptype = REPORT
  plg.authors = [""]
  plg.authors_email = ["@"]
  plg.category = CATEGORY_TEXT
  plg.reportclass = 'DbSummaryReport'
  plg.optionclass = 'DbSummaryOptions'
  plg.report_modes = [REPORT_MODE_GUI, REPORT_MODE_CLI]

Deux chaînes définissent le rapport de classe et d'options classe. L'argument report_modes argument est fixé à la somme de bits sage (le OU) de chacun des trois modes possibles: GUI (autonome rapport produit d'GRAMPS cours d'exécution dans une fenêtre), BKI (Livre en question), et CLI (interface de ligne de commande). Cela signifie que le rapport sera disponible dans les trois modes. Le reste devrait être d'explication.

Un exemplaire complet du rapport peut être téléchargé (1.66 KB) pour les essais et l'expérimentation.