From 40566e1cde3f55309c3acd3b7c7703b167bf0c29 Mon Sep 17 00:00:00 2001 From: olivier Date: Tue, 17 Jun 2008 14:39:34 +0000 Subject: [PATCH] removing old sqlalchemy based scripts git-svn-id: http://svn.parisson.org/svn/crem@38 3bf09e05-f825-4182-b9bc-eedd7160adf0 --- trunk/docref/spec/build.sh | 6 - trunk/docref/spec/docref.txt | 223 --------------------- trunk/docref/spec/elements.py | 136 ------------- trunk/docref/spec/parse.py | 18 -- trunk/docref/spec/staticenum.py | 69 ------- trunk/docref/spec/tables.py | 331 -------------------------------- trunk/docref/spec/texttable.py | 155 --------------- 7 files changed, 938 deletions(-) delete mode 100644 trunk/docref/spec/build.sh delete mode 100644 trunk/docref/spec/docref.txt delete mode 100644 trunk/docref/spec/elements.py delete mode 100644 trunk/docref/spec/parse.py delete mode 100644 trunk/docref/spec/staticenum.py delete mode 100644 trunk/docref/spec/tables.py delete mode 100644 trunk/docref/spec/texttable.py diff --git a/trunk/docref/spec/build.sh b/trunk/docref/spec/build.sh deleted file mode 100644 index 14af7e3..0000000 --- a/trunk/docref/spec/build.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -python parse.py -cd build -rst2html docref.txt docref.html && rst2latex docref.txt docref.tex && pdflatex docref.tex - diff --git a/trunk/docref/spec/docref.txt b/trunk/docref/spec/docref.txt deleted file mode 100644 index 48bb608..0000000 --- a/trunk/docref/spec/docref.txt +++ /dev/null @@ -1,223 +0,0 @@ - - -=================================================================== -Recommandations pour la réorganisation de la base de donnée du CREM -=================================================================== ------------------------------------- -Document de référence, version alpha ------------------------------------- - - -I - Enjeux -========== - -I.1 - Recherche d'informations ------------------------------- - -L'analyse de la structure de données et la rencontre des personnes concernées par son usage -permettent de délimiter des enjeux majeurs. Il apparaît notamment que le fond documentaire -que constitue cette base n'est actuellement pas mis à profit comme il pourrait l'être. Cette -base est largement sous-utilisée, les chercheurs, pour certains, ne l'utilisent pas du tout. - -La raison principale de cette situation est le fait que l'environnement technique et la -structure de la base ont été conçus pour s'inscrire dans un environnement documentaire -traditionnel, qui implique généralement de prendre contact avec un documentaliste pour effectuer -une recherche. Le documentaliste est un spécialiste de la base, il possède les connaissances -techniques nécessaires à sa consultation. - -Mais à l'heure d'Internet, ce processus de recherche est trop lourd et inadapté, en un mot -: obsolète. Les chercheurs lui préfèrent d'autres fonds documentaires accessibles en ligne, -de façon immédiate, et équipés d'outils de recherche puissants et ergonomiques. - -L'enjeu principal de la réorganisation de la base du CREM consiste donc à : sous-tendre le -développement d'un outil moderne de gestion et de consultation en ligne, avec des fonctions -de recherche puissantes et intuitives déterminer et améliorer les données de la base qui -sont prioritaires pour la recherche d'information - -En de-ça des-dits champs prioritaires, il existe un grand nombre d'information techniques de -second ordre, qui soit ne sont utiles qu'aux documentalistes, soit ne présentent pas d'intérêt -majeur pour la recherche d'information. Ces informations peuvent être conservées telles quelles, -sans grand effort de réorganisation, et resteront ainsi disponibles lors de la consultation -individuelle des fiches. - -En procédant de cette façon, c'est à dire en délimitant les-dîtes priorités, il semble -possible de dégager une véritable plus-value, de rendre le fond documentaire du CREM plus vivant, -sans pour autant engager des moyens démesurés dans la réorganisation de la base de donnée. - -I.2 - Gestion et mise à jour des données ----------------------------------------- - -Il est entendu qu'au delà de la consultation d'information, il s'agit également de faciliter -la gestion des données, leur mise à jour. Cette question implique pour une large part des -problématiques d'ordre ergonomique, liées au développement d'un outil logiciel autour de la -base, ce qui n'entre pas dans le cadre de la réorganisation de la base de données. - -Cependant, au niveau de la base, certains choix sont structurant. Par exemple l'emploi d'une -liste hiérarchisée de lieux telle que le Thesaurus of Geographical Names (TGN, recommandé par -Dublin Core), permet, en choisissant une région, une sous-région ou un village, de renseigner -automatiquement le pays (et les autres zones géographiques intermédiaires), ce qui diminue -l'effort et prévient les erreurs de saisie. - -Pour un grand nombre de champs, l'emploi d'énumérations (liste de valeurs valides pour -un champ donné) facilite et valide déjà la mise à jour des données. Cet aspect de la base -devra être conservé. - -Cependant, il semble que l'enjeu majeur de la réorganisation, du point de vue de la gestion -des données, est de permettre un travail collaboratif, entre chercheurs et documentalistes. C'est -là, d'une manière générale, ce qui permet sur Internet de rendre un fond documentaire vivant. - -Dans le cadre du CREM, il serait ainsi idéal d'amener les chercheurs à alimenter la base de -façon autonome, en sus des documentalistes dont c'est le métier. Ce serait là une véritable -nouveauté, représentant un fort potentiel d'enrichissement des données. - -D'une façon générale, une application en ligne ("webifiée") bien conçue se prête -très bien au travail collaboratif. Cependant, il semble que dans notre cas, les potentielles -contributions des chercheurs se heurtent à une question importante de confidentialité et -de propriété intellectuelle. Des cas ont en effet été rapportés d'usage détournés du -fruit du travail du centre de recherche, et d'une manière générale, il semble qu'il faille -observer une grande prudence pour la mise en commun d'enregistrement sonores et autres données, -qui représentent une matière précieuse aux yeux des chercheurs. - -La sécurité informatique est pour une large part distinct de la base de donnée ; elle -implique des efforts particuliers au niveau du développement applicatif, et de l'administration -de l'infrastructure réseau. - -Cependant, au niveau de la base de donnée, il est possible de mettre l'accent sur la -propriété des données. Chaque ressource (collection, item) peut en effet se voir attribuer -un propriétaire. Le dit propriétaire devrait ensuite pouvoir choisir quel autre utilisateur -et/ou groupe d'utilisateur est autorisé à consulter, écouter, et/ou modifier la ressource. - -En rassurant ainsi les chercheurs, il est envisageable que la base s'enrichisse notablement -par leurs contributions, dont certaines d'abord privées, pourront, à leur guise, devenir -petit à petit accessibles à un nombre grandissant d'utilisateurs et de groupes de travail. - -I.3 - Données prioritaires - -Après consultation des différents utilisateurs il apparaît que les meta-données principales -pour chaque item sont : - -* l'identifiant unique de l'item -* le titre de l'item -* la zone géographique -* le nom du collecteur, c'est à dire le chercheur qui a collecté cet enregistrement -* les instruments de musique utilisés -* l'année d'enregistrement -* le contexte ethnographique -* l'ethnie - -Il s'agit d'apporter une attention particulière à celles-ci, notamment en les normalisant, -pour faciliter la recherche d'informations, mais aussi pour l'ajout et la gestion simplifiés -d'items. - -Les autres données pourront être conservées telles quelles sans grand effort de normalisation. - -I.4 - Dublin Core ------------------ - -... - -II - Modalités de conversion/réorganisation de la base -====================================================== - -II.1 - Enumérations simples ---------------------------- - -dynamic:tables.describe_enums() - -II.2 - Collections ------------------- - -Ancien nom de table : support - -Nouveau nom de table : media_collections - -II.2.1 - Champs convertis -~~~~~~~~~~~~~~~~~~~~~~~~~ - -dynamic:tables.media_collections.describe_conversion() - -II.2.2 - Nouveaux champs -~~~~~~~~~~~~~~~~~~~~~~~~ - -dynamic:tables.media_collections.describe_new_fields() - -II.2.3 - Champs supprimés -~~~~~~~~~~~~~~~~~~~~~~~~~ - -dynamic:tables.media_collections.describe_removed_fields() - -II.3 - Items ------------- - -Ancien nom de table : phono - -Nouveau nom de table : media_items - -II.3.1 - Champs convertis -~~~~~~~~~~~~~~~~~~~~~~~~~ - -dynamic:tables.media_items.describe_conversion() - -II.3.2 - Nouveaux champs -~~~~~~~~~~~~~~~~~~~~~~~~ - -dynamic:tables.media_items.describe_new_fields() - -II.3.3 - Champs supprimés -~~~~~~~~~~~~~~~~~~~~~~~~~ - -dynamic:tables.media_items.describe_removed_fields() - -II.4 - Sélections ------------------ - -II.4.1 - Liste -~~~~~~~~~~~~~~ - -Nom de table: -dynamic:tables.media_playlists.name - -dynamic:tables.media_playlists.describe_new_fields() - -II.4.2 - Table de relation interne -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Nom de table: -dynamic:tables.media_playlist_resources.name - -dynamic:tables.media_playlist_resources.describe_new_fields() - -II.5 - Thesaurus Géographique ------------------------------ - -II.5.1 - Lieux -~~~~~~~~~~~~~~ - -Nom de table: -dynamic:tables.locations.name - -dynamic:tables.locations.describe_new_fields() - -II.5.2 - Alias des lieux -~~~~~~~~~~~~~~~~~~~~~~~~ - -Nom de table: -dynamic:tables.location_aliases.name - -dynamic:tables.location_aliases.describe_new_fields() - -II.5.3 - Relations hiérarchiques -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Nom de table: -dynamic:tables.location_relations.name - -dynamic:tables.location_relations.describe_new_fields() - -II.6 - Utilisateurs -------------------- - -Nom de table: -dynamic:tables.users.name - -dynamic:tables.users.describe_new_fields() diff --git a/trunk/docref/spec/elements.py b/trunk/docref/spec/elements.py deleted file mode 100644 index e46b8d7..0000000 --- a/trunk/docref/spec/elements.py +++ /dev/null @@ -1,136 +0,0 @@ -#coding: utf-8 -import sqlalchemy -import texttable - -def make_table(rows, width=20): - return texttable.indent(rows, hasHeader = True, separateRows = True, - prefix=u'| ', postfix=u' |', - wrapfunc = lambda x: texttable.wrap_onspace(x, width=width)) - -def describe_enums(metadata): - rows = [['Nom interne', 'Ancien nom', 'Description']] - for enum in metadata.enums: - rows.append([enum.name, enum.old_name, enum.label]) - return make_table(rows, 40) - -class Column(sqlalchemy.Column): - old_name = '' - label = '' - desc = '' - dc = '' - comment = '' - conversion = '' - enum = None - - def __init__(self, name, type, *args, **kwargs): - parent_args = {} - for key, value in kwargs.items(): - if key == 'old_name': - if isinstance(value, list): - self.old_name = unicode(",\n".join(value), 'utf-8') - #self.old_name = [] - #for item in value: - # self.old_name.append(unicode(item, 'utf-8')) - else: - self.old_name = unicode(value, 'utf-8') - elif key == 'label': - self.label = unicode(value, 'utf-8') - elif key == 'desc': - self.desc = unicode(value, 'utf-8') - elif key == 'dc': - self.dc = value - elif key == 'comment': - self.comment = unicode(value, 'utf-8') - elif key == 'conversion': - self.conversion = unicode(value, 'utf-8') - else: - parent_args[key] = value - - if isinstance(type, Enumeration): - args = (sqlalchemy.ForeignKey(type.name + '.id'),) + args - self.enum = type - type = sqlalchemy.Integer - - super(Column, self).__init__(name, type, *args, **parent_args) - -class RemovedColumn(object): - old_name = '' - comment = '' - - def __init__(self, old_name, comment=''): - self.old_name = unicode(old_name, 'utf-8') - self.comment = unicode(comment, 'utf-8') - -class Table(sqlalchemy.Table): - - def __init__(self, table_name, metadata, label, *args): - self.label = unicode(label, 'utf-8') - real_columns = [] - self.removed_columns = [] - for column in args: - if isinstance(column, RemovedColumn): - self.removed_columns.append(column) - else: - real_columns.append(column) - super(Table, self).__init__(table_name, metadata, *real_columns) - - - def describe_new_fields(self): - rows = [['Nom', 'Nom interne', 'Dublin Core']] - for column in self.columns: - if not column.old_name: - rows.append([column.label, column.name, column.dc]) - - return make_table(rows) - - def describe_conversion(self): - rows = [['Nouveau nom', 'Ancien nom', 'Nouveau nom interne', 'Dublin Core']] - for column in self.columns: - if column.old_name: - rows.append([column.label, column.old_name, column.name, column.dc]) - - return make_table(rows) - - def describe_removed_fields(self): - rows = [['Nom', 'Commentaire']] - for column in self.removed_columns: - rows.append([column.old_name, column.comment]) - - return make_table(rows, 50) - - def to_dot(self): - dot = u'digraph g {\n' - dot += ' charset = "utf-8";\n' - dot += ' node [shape=record, charset="utf-8"];\n' - dot += ' rankdir = LR;\n' - dot += ' subgraph cluster_new_fields {\n' - dot += ' label = "Nouveaux champs";\n' - dot += ' color = black;\n' - old_fields = '' - conversion = '' - for column in self.columns: - dot += ' ' + column.name + '[label = "{' + column.label + ' | ' + column.name + '}"];\n' - if column.old_name: - old_fields += ' old_' + column.name + '[label = "' + column.old_name + '"];\n' - conversion += ' old_' + column.name + ' -> ' + column.name + ';\n' - dot += ' }\n' - dot += ' subgraph cluster_old_fields {\n' - dot += ' label = "Anciens champs";\n' - dot += ' color = black;\n' - dot += old_fields - dot += ' }\n' - dot += conversion - dot += '}\n' - return dot - -class Enumeration(Table): - - def __init__(self, name, metadata, label='', old_name=''): - self.old_name = unicode(old_name, 'utf-8') - if not hasattr(metadata, 'enums'): - metadata.enums = [] - metadata.enums.append(self) - super(Enumeration, self).__init__(name, metadata, label, - Column('id', sqlalchemy.Integer, primary_key=True), - Column('value', sqlalchemy.String(250), unique=True) - ) diff --git a/trunk/docref/spec/parse.py b/trunk/docref/spec/parse.py deleted file mode 100644 index 535832c..0000000 --- a/trunk/docref/spec/parse.py +++ /dev/null @@ -1,18 +0,0 @@ - -import tables -import codecs -input = codecs.open('docref.txt', 'r', "utf-8") -output = codecs.open('build/docref.txt', 'w', "iso-8859-1") - -for line in input: - if line[0:8] == 'dynamic:': - output.write(eval(line[8:], globals(), locals()) + "\n") - else: - output.write(line) - -input.close() -output.close() - -output = codecs.open('build/collections.dot', 'w', 'utf-8') -output.write(tables.media_collections.to_dot()) -output.close() diff --git a/trunk/docref/spec/staticenum.py b/trunk/docref/spec/staticenum.py deleted file mode 100644 index d364f5b..0000000 --- a/trunk/docref/spec/staticenum.py +++ /dev/null @@ -1,69 +0,0 @@ -#!python - -## The MIT License - -## Copyright (c) - -## Permission is hereby granted, free of charge, to any person obtaining a copy -## of this software and associated documentation files (the "Software"), to deal -## in the Software without restriction, including without limitation the rights -## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -## copies of the Software, and to permit persons to whom the Software is -## furnished to do so, subject to the following conditions: - -## The above copyright notice and this permission notice shall be included in -## all copies or substantial portions of the Software. - -## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -## AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -## THE SOFTWARE. - - -from sqlalchemy import types, exceptions - -class StaticEnum(types.TypeDecorator): - impl = types.Unicode - - def __init__(self, values, empty_to_none=False, strict=False): - """Emulate an Enum type. - - values: - A list of valid values for this column - empty_to_none: - Optional, treat the empty string '' as None - strict: - Also insist that columns read from the database are in the - list of valid values. Note that, with strict=True, you won't - be able to clean out bad data from the database through your - code. - """ - - if values is None or len(values) is 0: - raise exceptions.AssertionError('StaticEnum requires a list of values') - self.empty_to_none = empty_to_none - self.strict = strict - self.values = values[:] - - # The length of the string/unicode column should be the longest string - # in values - size = max([len(v) for v in values if v is not None]) - super(StaticEnum, self).__init__(size) - - - def convert_bind_param(self, value, engine): - if self.empty_to_none and value is '': - value = None - if value not in self.values: - raise exceptions.AssertionError('"%s" not in StaticEnum.values' % value) - return super(StaticEnum, self).convert_bind_param(value, engine) - - - def convert_result_value(self, value, engine): - if self.strict and value not in self.values: - raise exceptions.AssertionError('"%s" not in StaticEnum.values' % value) - return super(StaticEnum, self).convert_result_value(value, engine) - diff --git a/trunk/docref/spec/tables.py b/trunk/docref/spec/tables.py deleted file mode 100644 index 41fd6d4..0000000 --- a/trunk/docref/spec/tables.py +++ /dev/null @@ -1,331 +0,0 @@ -#coding: utf-8 - -import sqlalchemy -from sqlalchemy import String, Integer, ForeignKey, Time, Date, MetaData, Text, Boolean -from elements import Column, RemovedColumn, Table, Enumeration -import elements -from staticenum import StaticEnum - -metadata = MetaData() -def describe_enums(): - return elements.describe_enums(metadata) - -# Users - -users = Table('users', metadata, 'Utilisateurs', - Column('username', String(250), primary_key=True, label='Nom d\'utilisateur'), - Column('level', StaticEnum('user,maintainer,administrator'), label='Niveau de permissions'), - Column('first_name', String(250), label='Prénom'), - Column('last_name', String(250), label='Nom'), - Column('phone', String(250), label='Téléphone'), - Column('email', String(250), label='E-Mail') -) - -# Playlists - -media_playlists = Table('playlists', metadata, 'Sélections personelles d\'items et de collections', - Column('id', Integer, primary_key='true', label='Identifiant'), - Column('owner_username', String(250), ForeignKey('users.username'), label='Propriétaire'), - Column('name', String(250), label='Intitulé')) - -media_playlist_resources = Table('playlist_resources', metadata, 'Ressources associées aux sélections personelles ', - Column('playlist_id', Integer, ForeignKey('playlists.id'), label='Identifiant de la sélection'), - Column('resource_type', StaticEnum('item', 'collection'), label='Type de ressource (item, collection)'), - Column('resource_id', String(250), label='Identifiant de la ressource') -) - -# Simple enumerations - -physical_formats = Enumeration('physical_formats', metadata, 'Formats physiques', old_name='Format (e)') -publishing_status = Enumeration('publishing_status', metadata, 'Status d\'édition/réédition', old_name='Réédition (e)') -publishers = Enumeration('publishers', metadata, 'Editeurs', old_name='Editeur1 (e)') -acquisition_modes = Enumeration('acquisition_modes', metadata, 'Modes d\'acquisition', old_name='Mode_Acqui (e)') -metadata_authors = Enumeration('record_authors', metadata, 'Rédacteurs des fiches', old_name='Rédacteur_Fiche (e)') -metadata_writers = Enumeration('metadata_writers', metadata, 'Opérateur de saisie des fiches', old_name='Saisie_Fiche (e)') -legal_rights = Enumeration('legal_rights', metadata, 'Statuts juridiques', old_name='Droit_d\'Utiliser (e)') -recording_contexts = Enumeration('recording_contexts', metadata, 'Contextes d\'enregistrement', old_name='Terrain_ou_Autre (e)') -ad_conversions = Enumeration('ad_conversions', metadata, 'Statuts de numérisation', old_name='Numérisation (e)') -ethnic_groups = Enumeration('ethnic_groups', metadata, 'Ethnies/Groupe social', old_name='Ethnie (t)') -vernacular_styles = Enumeration('vernacular_styles', metadata, 'Forme / genre vernaculaire', old_name='Form (t)') -generic_styles = Enumeration('generic_styles', metadata, 'Forme / genre générique', old_name='FormStyle générique (e)') -context_keywords = Enumeration('context_keywords', metadata, 'Mots clés du contexte ethnographique', old_name='Mot_Clef (t)') -publisher_collections = Enumeration('publisher_collections', metadata, 'Collections éditeur', old_name='Collection_Série (e)') - -# Geographic Thesaurus - -location_types = Enumeration('location_types', metadata, 'GeoEthno / Types de lieux') - -locations = Table('locations', metadata, 'GeoEthno / Lieux)', - Column('name', String(127), primary_key=True, label='Terme descripteur'), - Column('type', StaticEnum('country', 'continent', 'other')), - Column('complete_type', location_types), - Column('current_name', String(127), ForeignKey('locations.name'), label='Nom actuel'), - Column('is_authoritative', Boolean), -) - -location_aliases = Table('location_aliases', metadata, 'GeoEthno / Alias des lieux', - Column('location_name', String(127), ForeignKey('locations.name'), primary_key=True), - Column('alias', String(127), primary_key=True), - Column('is_authoritative', Boolean)) - -location_relations = Table('location_relations', metadata, 'GeoEthno / Relations hiérachiques', - Column('location_name', String(127), ForeignKey('locations.name'), primary_key=True), - Column('parent_location_name', String(127), ForeignKey('locations.name'), primary_key=True) -) - -# Media Collections - -media_collections = Table('media_collections', metadata, 'Collections', - Column('reference', - String(250), unique=True, - old_name='Réf', label='Référence'), - Column('physical_format_id', - physical_formats, - old_name='Format', label='Format', - desc="Format du 1er exemplaire archivé"), - Column('old_id', - String(250), - old_name='Cote', label='Ancienne cote'), - Column('id', - String(250), primary_key=True, - dc='identifier', - label='Cote', conversion='à préciser'), - Column('title', - String(250), - dc='title', - old_name='Titre', label='Titre'), - Column('native_title', - String(250), - dc='title', - old_name='Transcrip_Trad', label='Traduction du titre'), - Column('physical_items_num', - Integer, - old_name='Nb_de_pieces', label='Nombre de supports physiques'), - Column('publishing_status_id', - publishing_status, - old_name='Réédition', label='Réédition'), - RemovedColumn(old_name='Original'), - RemovedColumn(old_name='Copie_TotPartie'), - RemovedColumn(old_name='Copié_de'), - Column('creator', - String(250), - dc='creator', - old_name='Auteur_Compil', label='Auteur / Cédant'), - Column('booklet_author', - String(250), - dc='contributor', - old_name='Auteur_Notice', label='Auteur notice'), - Column('booklet_description', - Text, - old_name='Notice', label='Notice / Dossier technique'), - Column('collector', - Text, - dc='contributor', - old_name='Collecteur', label='Collecteur'), - Column('publisher_id', - publishers, - dc='publisher', - old_name='Editeur', label='Editeur', - desc='Pour les documents ÉDITÉS:Nom et État de l\'Editeur. Pour les INÉDITS :voir champ "Type de document".'), - Column('year_published', - Integer, - dc='date', - old_name='Année_parution', label='Année de parution', - desc='Ne concerne que les documents ÉDITÉS.', - conversion='à préciser, traiter les nombres négatifs ?'), - Column('publisher_collection', - publisher_collections, - old_name='Collect_Série', label='Collection éditeur', - comment='faux: nom de la collection, suivi du n° dans la collection.'), - Column('publisher_serial', - String(250), - old_name='Num_Dans_Collec', label='Numéro de série', - desc='Numéro de série dans la collection éditeur', - comment='à valider'), - Column('external_references', - Text, - old_name='Réf_Biblio', label='Bibliographie', - desc='Références biblio/disco/filmographiques, uniquement liées à ce support'), - Column('acquisition_mode_id', - acquisition_modes, - old_name='Mod_Acqui', label='Mode d\'acquisition'), - Column('comment', - Text, - old_name='Commentaire', label='Commentaire'), - Column('metadata_author_id', - metadata_authors, - dc='contributor', - old_name='Rédacteur_Fiche', label='Rédacteur fiche', - desc='Responsable de l\'analyse documentaire'), - Column('metadata_writer_id', - metadata_writers, - old_name='Saisie_Fiche', label='Saisie fiches', - desc='Personne qui a saisi les fiches dans la base de données.'), - Column('legal_rights_id', - legal_rights, - dc='rights', - old_name='Droit_Utiliser', label='Statut juridique'), - Column('alt_ids', - String(250), - old_name='Autres_Cotes', label='Autres exemplaires'), - Column('recorded_from_year', - Integer, - dc='date', - old_name='Année_Enreg', label='Années d\'enregistrement', - conversion="split"), - Column('recorded_to_year', - Integer, - dc='date', - old_name='Année_Enreg', label='Années d\'enregistrement', - conversion="split"), - Column('recording_context_id', - recording_contexts, - old_name='Terrain_ou_Autr', label='Contexte d\'enregistrement'), - Column('approx_duration', - Time(), - old_name='Durée_approx', label='Durée approximative'), - Column('doctype_code', - Integer, - old_name='Tri_DiBm', label='Type de document'), - Column('travail', - String(250), - old_name='Travail', label='?'), - Column('state', - String(250), - old_name='Compil_Face_Plage', label="Etat"), - Column('cnrs_contributor', - String(250), - old_name='Déposant_CNRS', label="Déposant CNRS", - desc='Pour les INÉDITS uniquement. Signale les collectes ayant bénéficées d\'une aide du CNRS.'), - Column('items_done', - String(250), - old_name='Fiches', label='Fiches faîtes', - desc="Signale que les fiches Item de ce support sont présentes dans la base."), - Column('a_informer_07_03', - String(250), - old_name='A informer_07-03', label='?'), - Column('ad_conversion_id', - ad_conversions, - old_name='Numérisation', label="Historique de numérisation"), - RemovedColumn(old_name='Champ36'), -) - -# Media Items - -media_item_context_keywords = Table('media_item_context_keywords', metadata, - 'Mots clés associés à un item', - Column('media_item_id', Integer, ForeignKey('media_items.id')), - Column('context_keyword_id', context_keywords)) - -media_items = Table('media_items', metadata, 'Items', - RemovedColumn(old_name='Réf', comment='Calculé en temps réel à partir de la collection'), - Column('collection_id', - String(250), ForeignKey('media_collections.id'), - dc='relation/isPartOf', - label='Collection'), - RemovedColumn(old_name='Format', comment='Calculé en temps réel à partir de la collection'), - RemovedColumn(old_name='Cote_Support', comment='Calculé en temps réel à partir de la collection'), - Column('track', - String(250), - old_name="Face_Plage", label="N° de l'item"), - Column('id', - String(250), - old_name='Cote_Phono', label="Cote item"), - Column('approx_duration', - Time(), - old_name='Durée', label='Durée'), - Column('recorded_from_date', - Date(), - dc='date', - old_name='Date_enregistr', label='Date', desc='Date de l\'enregistrement'), - Column('recorded_to_date', - Date(), - dc='date', - old_name='Date_enregistr', label='Date'), - Column('location_name', - Integer, ForeignKey('locations.name'), - dc='coverage', - old_name=['Continent', 'Etat', 'Région_Village'], label='Lieu', - desc='(?) Lieu de provenance de la musique. Si le lieu de l\'enregistrement est autre, l\'indiquer en "Remarques".'), - Column('location_comment', - String(250), - old_name='Région_Village', label='Commentaire lieu'), - Column('ethnic_group_id', - ethnic_groups, - old_name='Ethnie_GrSocial', label='Ethnie/Groupe social', comment='attention alias ethnies'), - RemovedColumn(old_name='Titre_Support', comment='Calculé en temps réel à partir de la collection'), - Column('title', - String(250), - dc='title', - old_name='Titre_pièce', label='Titre Item'), - Column('native_title', - String(250), - dc='title', - old_name='Transcrip_Trad', label='Traduction du titre', - desc='Traduction des langues non communes, plus translittération des langues n\'utilisant pas l\'alphabet latin.'), - Column('author', - String(250), - dc='creator', - old_name='Auteur', label='Auteur', - desc='Le cas échéant, faire suivre le nom par une mention "-auteur /-compositeur / -arrangeur"'), - Column('vernacular_style_id', - vernacular_styles, - old_name='Form_Genr_Style', label='Forme / genre vernaculaire [nom à revoir]', - desc='Nom local de la forme ou du genre'), - RemovedColumn(old_name='Struct_Modale'), - RemovedColumn(old_name='Struct_Rythm'), - RemovedColumn(old_name='Struct_Rythm'), - RemovedColumn(old_name='Fonction_Usage', - comment='Champ inutile, les mots clés sont associés via une table de relation externe'), - Column('context_comment', - Text, - old_name='Comm_FonctUsage', label='Contexte ethnographique : commentaires'), - Column('external_references', - String(250), - old_name='Documentation', label='Références', - desc='Références directement liées à l\'item.'), - Column('moda_execut', - String(250), - old_name='Moda_Execut', comment='à supprimer ?'), - Column('copied_from_item_id', - String(250), ForeignKey('media_items.id'), - dc='relation/isVersionOf', - old_name='Copie_de', label='Copie de'), - Column('collector', - String(250), - dc='contributor', - old_name='Enregistré_par', label='Collecteur'), - Column('cultural_area', - String(250), - old_name='Aire culturelle', label='Aire culturelle'), - RemovedColumn(old_name='Année_Enreg', - comment='calculé en temps-réel à partir de la date d\'enregistrement'), - Column('generic_style', - generic_styles, - old_name='FormStyl généri', label='Forme / genre générique'), - Column('collector_selection', - String(250), - old_name='ChoixCollecteur', label='Choix du collecteur', - desc='Permet au collecteur de repérer les items les plus intéressants'), - RemovedColumn(old_name='Repère_bande'), - Column('creator_reference', - String(250), - old_name='NroBandNroPièc', label='Référence du déposant'), -) - - - - - - - - - - - - - - - - - diff --git a/trunk/docref/spec/texttable.py b/trunk/docref/spec/texttable.py deleted file mode 100644 index 3d07d25..0000000 --- a/trunk/docref/spec/texttable.py +++ /dev/null @@ -1,155 +0,0 @@ -#coding: utf-8 -import cStringIO,operator - -def indent(rows, hasHeader=False, headerChar=u'-', delim=u' | ', justify=u'left', - separateRows=False, prefix=u'', postfix=u'', wrapfunc=lambda x:x): - """Indents a table by column. - - rows: A sequence of sequences of items, one sequence per row. - - hasHeader: True if the first row consists of the columns' names. - - headerChar: Character to be used for the row separator line - (if hasHeader==True or separateRows==True). - - delim: The column delimiter. - - justify: Determines how are data justified in their column. - Valid values are 'left','right' and 'center'. - - separateRows: True if rows are to be separated by a line - of 'headerChar's. - - prefix: A string prepended to each printed row. - - postfix: A string appended to each printed row. - - wrapfunc: A function f(text) for wrapping text; each element in - the table is first wrapped by this function.""" - # closure for breaking logical rows to physical, using wrapfunc - def rowWrapper(row): - newRows = [wrapfunc(item).split('\n') for item in row] - return [[substr or '' for substr in item] for item in map(None,*newRows)] - # break each logical row into one or more physical ones - logicalRows = [rowWrapper(row) for row in rows] - # columns of physical rows - columns = map(None,*reduce(operator.add,logicalRows)) - # get the maximum of each column by the string length of its items - maxWidths = [max([len(item) for item in column]) for column in columns] - rowSeparator = u"+" + u"+".join([u'-' * (width + len(delim) - 1) for width in maxWidths]) + u"+" - headerSep = u"+" + u"+".join([u'=' * (width + len(delim) - 1) for width in maxWidths]) + u"+" - #headerChar * (len(prefix) + len(postfix) + sum(maxWidths) + \ - # len(delim)*(len(maxWidths)-1)) - #headerSep = u"=" * (len(prefix) + len(postfix) + sum(maxWidths) + \ - # len(delim)*(len(maxWidths)-1)) - # select the appropriate justify method - #justify = {'center':str.center, 'right':str.rjust, 'left':str.ljust}[justify.lower()] - output=u'' - if separateRows: - output += rowSeparator + "\n" - - for physicalRows in logicalRows: - for row in physicalRows: - output += \ - prefix \ - + delim.join([item.ljust(width) for (item,width) in zip(row,maxWidths)]) \ - + postfix + "\n" - if hasHeader: output += headerSep + "\n"; hasHeader=False - elif separateRows: output += rowSeparator + "\n" - return output - -# written by Mike Brown -# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/148061 -def wrap_onspace(text, width): - """ - A word-wrap function that preserves existing line breaks - and most spaces in the text. Expects that existing line - breaks are posix newlines (\n). - """ - return reduce(lambda line, word, width=width: '%s%s%s' % - (line, - ' \n'[(len(line[line.rfind('\n')+1:]) - + len(word.split('\n',1)[0] - ) >= width)], - word), - text.split(' ') - ) - -import re -def wrap_onspace_strict(text, width): - """Similar to wrap_onspace, but enforces the width constraint: - words longer than width are split.""" - wordRegex = re.compile(r'\S{'+str(width)+r',}') - return wrap_onspace(wordRegex.sub(lambda m: wrap_always(m.group(),width),text),width) - -import math -def wrap_always(text, width): - """A simple word-wrap function that wraps text on exactly width characters. - It doesn't split the text in words.""" - return '\n'.join([ text[width*i:width*(i+1)] \ - for i in xrange(int(math.ceil(1.*len(text)/width))) ]) - -if __name__ == '__main__': - labels = ('First Name', 'Last Name', 'Age', 'Position') - data = \ - '''John,Smith,24,Software Engineer - Mary,Brohowski,23,Sales Manager - Aristidis,Papageorgopoulos,28,Senior Reseacher''' - rows = [row.strip().split(',') for row in data.splitlines()] - - print 'Without wrapping function\n' - print indent([labels]+rows, hasHeader=True) - # test indent with different wrapping functions - width = 10 - for wrapper in (wrap_always,wrap_onspace,wrap_onspace_strict): - print 'Wrapping function: %s(x,width=%d)\n' % (wrapper.__name__,width) - print indent([labels]+rows, hasHeader=True, separateRows=True, - prefix='| ', postfix=' |', - wrapfunc=lambda x: wrapper(x,width)) - - # output: - # - #Without wrapping function - # - #First Name | Last Name | Age | Position - #------------------------------------------------------- - #John | Smith | 24 | Software Engineer - #Mary | Brohowski | 23 | Sales Manager - #Aristidis | Papageorgopoulos | 28 | Senior Reseacher - # - #Wrapping function: wrap_always(x,width=10) - # - #---------------------------------------------- - #| First Name | Last Name | Age | Position | - #---------------------------------------------- - #| John | Smith | 24 | Software E | - #| | | | ngineer | - #---------------------------------------------- - #| Mary | Brohowski | 23 | Sales Mana | - #| | | | ger | - #---------------------------------------------- - #| Aristidis | Papageorgo | 28 | Senior Res | - #| | poulos | | eacher | - #---------------------------------------------- - # - #Wrapping function: wrap_onspace(x,width=10) - # - #--------------------------------------------------- - #| First Name | Last Name | Age | Position | - #--------------------------------------------------- - #| John | Smith | 24 | Software | - #| | | | Engineer | - #--------------------------------------------------- - #| Mary | Brohowski | 23 | Sales | - #| | | | Manager | - #--------------------------------------------------- - #| Aristidis | Papageorgopoulos | 28 | Senior | - #| | | | Reseacher | - #--------------------------------------------------- - # - #Wrapping function: wrap_onspace_strict(x,width=10) - # - #--------------------------------------------- - #| First Name | Last Name | Age | Position | - #--------------------------------------------- - #| John | Smith | 24 | Software | - #| | | | Engineer | - #--------------------------------------------- - #| Mary | Brohowski | 23 | Sales | - #| | | | Manager | - #--------------------------------------------- - #| Aristidis | Papageorgo | 28 | Senior | - #| | poulos | | Reseacher | - #--------------------------------------------- - -- 2.39.5