From: yomguy Date: Tue, 2 Oct 2012 12:30:32 +0000 (+0200) Subject: cleanup sandbox, update diagram X-Git-Tag: 1.4.5~59^2~1 X-Git-Url: https://git.parisson.com/?a=commitdiff_plain;h=30a164d33f64ede5beeb0515f40d1ae47dd54ce1;p=telemeta.git cleanup sandbox, update diagram --- diff --git a/doc/devel/telemeta-all.dot b/doc/devel/telemeta-all.dot index eae9adf1..628a296a 100644 --- a/doc/devel/telemeta-all.dot +++ b/doc/devel/telemeta-all.dot @@ -161,31 +161,6 @@ digraph name { >] - django_contrib_auth_models_Message [label=< - - - - - - - - - - - -
Message
idAutoField
messageTextField
- >] - @@ -363,6 +338,9 @@ digraph name { + + + telemeta_models_enum_Enumeration [label=< +
+ >] + + telemeta_models_enum_TapeWheelDiameter [label=< + + + + + + + + + + +
TapeWheelDiameter
<Enumeration>
idAutoField
valueCharField
>] @@ -981,6 +984,106 @@ digraph name { > + + >] + + telemeta_models_enum_NumberOfChannels [label=< + + + + + + + + + + + +
NumberOfChannels
<Enumeration>
idAutoField
valueCharField
+ >] + + telemeta_models_enum_Organization [label=< + + + + + + + + + + + +
Organization
<Enumeration>
idAutoField
valueCharField
+ >] + + telemeta_models_enum_Rights [label=< + + + + + + + + + + + +
Rights
<Enumeration>
idAutoField
valueCharField
+ >] + + telemeta_models_enum_Topic [label=< + + + + + + + + + + +
Topic
<Enumeration>
idAutoField
valueCharField
>] @@ -1200,6 +1303,20 @@ digraph name { >CharField + department + CharField + + attachment + CharField + function @@ -1228,13 +1345,6 @@ digraph name { >DateField - init_password - BooleanField - >] @@ -1460,6 +1570,94 @@ digraph name { > + + >] + + telemeta_models_format_Format [label=< + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Format
<ModelCore>
idAutoField
original_codeCharField
original_numberCharField
original_statusCharField
original_stateTextField
original_commentsTextField
original_audio_qualityTextField
recording_systemCharField
tape_thicknessCharField
tape_referenceCharField
sticker_presenceBooleanField
>] @@ -1773,24 +1971,38 @@ digraph name { > collectorrecorded_from_date CharFieldDateField recorded_from_daterecorded_to_date DateField recorded_to_datescientist DateFieldCharField + + summary + TextField + + comment + TextField commentcontributor TextFieldCharField collector_selectionpublic_access CharField collector_from_collectiondepositor BooleanFieldCharField creator_referencerecordist CharField external_referencesdigitalist TextFieldCharField public_accesscollector + CharField + + collector_selection CharField + collector_from_collection + BooleanField + + digitization_date + DateField + + publishing_date + DateField + + creator_reference + CharField + + external_references + TextField + file @@ -2542,80 +2796,6 @@ digraph name { >] - telemeta_models_media_Format [label=< - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Format
<ModelCore>
idAutoField
original_codeCharField
tape_numberCharField
statusCharField
conservation_stateCharField
commentsTextField
tape_thicknessCharField
tape_diameterCharField
tape_referenceCharField
- >] - @@ -2710,12 +2890,6 @@ digraph name { [label="user_permissions (user)"] [arrowhead=dot arrowtail=dot, dir=both]; - - - django_contrib_auth_models_Message -> django_contrib_auth_models_User - [label="user (_message_set)"] [arrowhead=none, arrowtail=dot]; - - @@ -2739,6 +2913,7 @@ digraph name { + @@ -2795,6 +2970,16 @@ digraph name { + + + + + + + + + + telemeta_models_location_Location -> telemeta_models_location_LocationType @@ -2875,6 +3060,36 @@ digraph name { + telemeta_models_format_Format -> telemeta_models_media_MediaItem + [label="item (format)"] [arrowhead=none, arrowtail=dot]; + + + telemeta_models_format_Format -> telemeta_models_enum_PhysicalFormat + [label="physical_format (format)"] [arrowhead=none, arrowtail=dot]; + + + telemeta_models_format_Format -> telemeta_models_location_Location + [label="original_location (format)"] [arrowhead=none, arrowtail=dot]; + + + telemeta_models_format_Format -> telemeta_models_enum_NumberOfChannels + [label="original_channels (format)"] [arrowhead=none, arrowtail=dot]; + + + telemeta_models_format_Format -> telemeta_models_enum_TapeWheelDiameter + [label="tape_wheel_diameter (format)"] [arrowhead=none, arrowtail=dot]; + + + telemeta_models_format_Format -> telemeta_models_enum_TapeSpeed + [label="tape_speed (format)"] [arrowhead=none, arrowtail=dot]; + + + telemeta_models_format_Format -> telemeta_models_enum_TapeVendor + [label="tape_vendor (format)"] [arrowhead=none, arrowtail=dot]; + + + + telemeta_models_media_MediaCollection -> telemeta_models_enum_RecordingContext [label="recording_context (collections)"] [arrowhead=none, arrowtail=dot]; @@ -2927,6 +3142,10 @@ digraph name { [label="collection (items)"] [arrowhead=none, arrowtail=dot]; + telemeta_models_media_MediaItem -> telemeta_models_enum_Topic + [label="topic (mediaitem)"] [arrowhead=none, arrowtail=dot]; + + telemeta_models_media_MediaItem -> telemeta_models_location_Location [label="location (mediaitem)"] [arrowhead=none, arrowtail=dot]; @@ -2947,6 +3166,14 @@ digraph name { [label="generic_style (items)"] [arrowhead=none, arrowtail=dot]; + telemeta_models_media_MediaItem -> telemeta_models_enum_Organization + [label="organization (mediaitem)"] [arrowhead=none, arrowtail=dot]; + + + telemeta_models_media_MediaItem -> telemeta_models_enum_Rights + [label="rights (mediaitem)"] [arrowhead=none, arrowtail=dot]; + + telemeta_models_media_MediaItem -> telemeta_models_media_MediaItem [label="copied_from_item (copies)"] [arrowhead=none, arrowtail=dot]; @@ -3045,28 +3272,6 @@ digraph name { [label="resource (related)"] [arrowhead=none, arrowtail=dot]; - - - telemeta_models_media_Format -> telemeta_models_media_MediaItem - [label="item (formats)"] [arrowhead=none, arrowtail=dot]; - - - telemeta_models_media_Format -> telemeta_models_enum_TapeLength - [label="tape_length (formats)"] [arrowhead=none, arrowtail=dot]; - - - telemeta_models_media_Format -> telemeta_models_enum_TapeWidth - [label="tape_width (formats)"] [arrowhead=none, arrowtail=dot]; - - - telemeta_models_media_Format -> telemeta_models_enum_TapeSpeed - [label="tape_speed (formats)"] [arrowhead=none, arrowtail=dot]; - - - telemeta_models_media_Format -> telemeta_models_enum_TapeVendor - [label="tape_vendor (formats)"] [arrowhead=none, arrowtail=dot]; - - diff --git a/doc/devel/telemeta-all.pdf b/doc/devel/telemeta-all.pdf index c16f6128..1dea7b62 100644 Binary files a/doc/devel/telemeta-all.pdf and b/doc/devel/telemeta-all.pdf differ diff --git a/doc/devel/telemeta.dot b/doc/devel/telemeta.dot index 2550f75f..0a2668de 100644 --- a/doc/devel/telemeta.dot +++ b/doc/devel/telemeta.dot @@ -56,108 +56,108 @@ digraph name { >] - telemeta_models_media_MediaRelated [label=< + telemeta_models_media_MediaBaseResource [label=< + >MediaBaseResource
<MediaResource> - - - - - -
MediaRelated
<MediaResource>
titleCharField
datetitle DateTimeFieldCharField
description TextField
mime_typeCharField
urlcode CharFieldCharField
creditsreference CharField
filepublic_access FileFieldCharField
>] - telemeta_models_media_MediaBaseResource [label=< + telemeta_models_media_MediaRelated [label=< + >MediaRelated
<MediaResource> + + + + + +
MediaBaseResource
<MediaResource>
titletitle CharFieldCharField
dateDateTimeField
description CharFieldTextField
codemime_type CharFieldCharField
referenceurl CharField
public_accesscredits CharField
fileFileField
>] @@ -534,6 +534,31 @@ digraph name { > + + >] + + telemeta_models_enum_TapeWheelDiameter [label=< + + + + + + + + + + +
TapeWheelDiameter
<Enumeration>
idAutoField
valueCharField
>] @@ -634,6 +659,106 @@ digraph name { > + + >] + + telemeta_models_enum_NumberOfChannels [label=< + + + + + + + + + + + +
NumberOfChannels
<Enumeration>
idAutoField
valueCharField
+ >] + + telemeta_models_enum_Organization [label=< + + + + + + + + + + + +
Organization
<Enumeration>
idAutoField
valueCharField
+ >] + + telemeta_models_enum_Rights [label=< + + + + + + + + + + + +
Rights
<Enumeration>
idAutoField
valueCharField
+ >] + + telemeta_models_enum_Topic [label=< + + + + + + + + + + +
Topic
<Enumeration>
idAutoField
valueCharField
>] @@ -853,6 +978,20 @@ digraph name { >CharField + department + CharField + + attachment + CharField + function @@ -881,13 +1020,6 @@ digraph name { >DateField - init_password - BooleanField - >] @@ -1113,6 +1245,94 @@ digraph name { > + + >] + + telemeta_models_format_Format [label=< + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Format
<ModelCore>
idAutoField
original_codeCharField
original_numberCharField
original_statusCharField
original_stateTextField
original_commentsTextField
original_audio_qualityTextField
recording_systemCharField
tape_thicknessCharField
tape_referenceCharField
sticker_presenceBooleanField
>] @@ -1426,24 +1646,38 @@ digraph name { > collectorrecorded_from_date CharFieldDateField recorded_from_daterecorded_to_date DateField recorded_to_datescientist DateFieldCharField + + summary + TextField + + comment + TextField commentcontributor TextFieldCharField collector_selectionpublic_access CharField collector_from_collectiondepositor BooleanFieldCharField creator_referencerecordist CharField external_referencesdigitalist TextFieldCharField public_accesscollector + CharField + + collector_selection CharField + collector_from_collection + BooleanField + + digitization_date + DateField + + publishing_date + DateField + + creator_reference + CharField + + external_references + TextField + file @@ -2195,80 +2471,6 @@ digraph name { >] - telemeta_models_media_Format [label=< - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Format
<ModelCore>
idAutoField
original_codeCharField
tape_numberCharField
statusCharField
conservation_stateCharField
commentsTextField
tape_thicknessCharField
tape_diameterCharField
tape_referenceCharField
- >] - @@ -2327,6 +2529,16 @@ digraph name { + + + + + + + + + + telemeta_models_location_Location -> telemeta_models_location_LocationType @@ -2431,6 +2643,36 @@ digraph name { + telemeta_models_format_Format -> telemeta_models_media_MediaItem + [label="item (format)"] [arrowhead=none, arrowtail=dot]; + + + telemeta_models_format_Format -> telemeta_models_enum_PhysicalFormat + [label="physical_format (format)"] [arrowhead=none, arrowtail=dot]; + + + telemeta_models_format_Format -> telemeta_models_location_Location + [label="original_location (format)"] [arrowhead=none, arrowtail=dot]; + + + telemeta_models_format_Format -> telemeta_models_enum_NumberOfChannels + [label="original_channels (format)"] [arrowhead=none, arrowtail=dot]; + + + telemeta_models_format_Format -> telemeta_models_enum_TapeWheelDiameter + [label="tape_wheel_diameter (format)"] [arrowhead=none, arrowtail=dot]; + + + telemeta_models_format_Format -> telemeta_models_enum_TapeSpeed + [label="tape_speed (format)"] [arrowhead=none, arrowtail=dot]; + + + telemeta_models_format_Format -> telemeta_models_enum_TapeVendor + [label="tape_vendor (format)"] [arrowhead=none, arrowtail=dot]; + + + + telemeta_models_media_MediaCollection -> telemeta_models_enum_RecordingContext [label="recording_context (collections)"] [arrowhead=none, arrowtail=dot]; @@ -2483,6 +2725,10 @@ digraph name { [label="collection (items)"] [arrowhead=none, arrowtail=dot]; + telemeta_models_media_MediaItem -> telemeta_models_enum_Topic + [label="topic (mediaitem)"] [arrowhead=none, arrowtail=dot]; + + telemeta_models_media_MediaItem -> telemeta_models_location_Location [label="location (mediaitem)"] [arrowhead=none, arrowtail=dot]; @@ -2503,6 +2749,14 @@ digraph name { [label="generic_style (items)"] [arrowhead=none, arrowtail=dot]; + telemeta_models_media_MediaItem -> telemeta_models_enum_Organization + [label="organization (mediaitem)"] [arrowhead=none, arrowtail=dot]; + + + telemeta_models_media_MediaItem -> telemeta_models_enum_Rights + [label="rights (mediaitem)"] [arrowhead=none, arrowtail=dot]; + + telemeta_models_media_MediaItem -> telemeta_models_media_MediaItem [label="copied_from_item (copies)"] [arrowhead=none, arrowtail=dot]; @@ -2617,26 +2871,4 @@ digraph name { [label="resource (related)"] [arrowhead=none, arrowtail=dot]; - - - telemeta_models_media_Format -> telemeta_models_media_MediaItem - [label="item (formats)"] [arrowhead=none, arrowtail=dot]; - - - telemeta_models_media_Format -> telemeta_models_enum_TapeLength - [label="tape_length (formats)"] [arrowhead=none, arrowtail=dot]; - - - telemeta_models_media_Format -> telemeta_models_enum_TapeWidth - [label="tape_width (formats)"] [arrowhead=none, arrowtail=dot]; - - - telemeta_models_media_Format -> telemeta_models_enum_TapeSpeed - [label="tape_speed (formats)"] [arrowhead=none, arrowtail=dot]; - - - telemeta_models_media_Format -> telemeta_models_enum_TapeVendor - [label="tape_vendor (formats)"] [arrowhead=none, arrowtail=dot]; - - } diff --git a/doc/devel/telemeta.pdf b/doc/devel/telemeta.pdf index c6b8a651..8ad318fd 100644 Binary files a/doc/devel/telemeta.pdf and b/doc/devel/telemeta.pdf differ diff --git a/example/apache2/telemeta.conf b/example/apache2/telemeta.conf index ca39eb18..3b6cedd7 100644 --- a/example/apache2/telemeta.conf +++ b/example/apache2/telemeta.conf @@ -8,34 +8,24 @@ # alert, emerg. CustomLog ${APACHE_LOG_DIR}/access-telemeta.log combined - Alias /media/ /home/dev/telemeta/sandboxes/sandbox_generic/media/ - + Alias /media/ /home/dev/telemeta/example/sandbox/media/ + + Order deny,allow Allow from all - WSGIDaemonProcess telemeta_test user=momo group=momo threads=12 processes=4 maximum-requests=1000 - #deadlock-timeout=1000 + WSGIDaemonProcess telemeta_test user=www-data group=www-data threads=12 processes=4 maximum-requests=1000 deadlock-timeout=300 WSGIProcessGroup telemeta_test WSGIApplicationGroup %{GLOBAL} - WSGIScriptAlias / /home/dev/telemeta/sandboxes/sandbox_generic/wsgi/sandbox_generic.wsgi - - - Order deny,allow - Allow from all - + WSGIScriptAlias / /home/dev/telemeta/example/sandbox/wsgi.py -# Disallow browsing of Subversion working copy administrative dirs. - - Order deny,allow - Deny from all - # # SetHandler None # -Alias /favicon.ico /home/dev/telemeta/telemeta-unstable/telemeta/htdocs/images/favicon.ico +Alias /favicon.ico /home/dev/telemeta/telemeta/static/telemeta/images/favicon.ico SetHandler None diff --git a/example/data/format/original_format.txt b/example/data/format/original_format.txt new file mode 100644 index 00000000..1a5bc133 --- /dev/null +++ b/example/data/format/original_format.txt @@ -0,0 +1,38 @@ +Bande magnétique 6,25mm (1/4') +Bande magnétique mini-Nagra 3,81mm +Cassette analogique +Cassette analogique Type I (Fe) +Cassette analogique Type II (CrO2) +Cassette analogique Type IV (Metal) +Cylindre de cire à gravure directe +Cylindre de cire édité +Fil magnétique +Disque à gravure directe +Disque 78 tours +Disque 45 tours +Disque 33 tours +Cassette audionumérique PCM F1 Betamax +Cassette audionumérique PCM 1610/1630 U-Matic +Cassette audionumérique DAT +Cassette audionumérique DAT 48 kHz +Cassette audionumérique DAT 44,1 kHz +Cassette audionumérique DAT 32 kHz +Bande magnétique audionumérique 1/4" (DASH, ProDigi, EIAJ-C, Nagra-D) +Mini-Disc +CD-A (Audio édité) +CD-R Audio +CD-RW Audio +CD-R Data +CD-ROM édité +CD-RW Data +DVD-R Data +DVD+R Data +DVD-ROM édité +DVD-RW Data +DVD+RW Data +BD-ROM édité (Blu-ray) +BD-R (Blu-ray enregistrable) +BD-RE (Blu-ray réinscriptible) +Disque dur (HDD) +Carte mémoire +SSD diff --git a/example/init/format/original_format.txt b/example/init/format/original_format.txt deleted file mode 100644 index 1a5bc133..00000000 --- a/example/init/format/original_format.txt +++ /dev/null @@ -1,38 +0,0 @@ -Bande magnétique 6,25mm (1/4') -Bande magnétique mini-Nagra 3,81mm -Cassette analogique -Cassette analogique Type I (Fe) -Cassette analogique Type II (CrO2) -Cassette analogique Type IV (Metal) -Cylindre de cire à gravure directe -Cylindre de cire édité -Fil magnétique -Disque à gravure directe -Disque 78 tours -Disque 45 tours -Disque 33 tours -Cassette audionumérique PCM F1 Betamax -Cassette audionumérique PCM 1610/1630 U-Matic -Cassette audionumérique DAT -Cassette audionumérique DAT 48 kHz -Cassette audionumérique DAT 44,1 kHz -Cassette audionumérique DAT 32 kHz -Bande magnétique audionumérique 1/4" (DASH, ProDigi, EIAJ-C, Nagra-D) -Mini-Disc -CD-A (Audio édité) -CD-R Audio -CD-RW Audio -CD-R Data -CD-ROM édité -CD-RW Data -DVD-R Data -DVD+R Data -DVD-ROM édité -DVD-RW Data -DVD+RW Data -BD-ROM édité (Blu-ray) -BD-R (Blu-ray enregistrable) -BD-RE (Blu-ray réinscriptible) -Disque dur (HDD) -Carte mémoire -SSD diff --git a/example/sandbox.wsgi b/example/sandbox.wsgi deleted file mode 100644 index 100fa8be..00000000 --- a/example/sandbox.wsgi +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/python2.5 -# -*- coding: utf-8 -*- - -import os -import sys - -here = os.path.dirname(__file__) - -sys.path.append(here) -sys.path.append(os.path.join(here,'sandbox')) - -os.environ['DJANGO_SETTINGS_MODULE'] = 'sandbox_generic.settings' - -import django.core.handlers.wsgi -application = django.core.handlers.wsgi.WSGIHandler() - diff --git a/example/sandbox/__init__.py b/example/sandbox/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/example/sandbox/diag.sh b/example/sandbox/diag.sh new file mode 100755 index 00000000..5f6c1e59 --- /dev/null +++ b/example/sandbox/diag.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +app="telemeta" +dir="../../doc/devel" + +python modelviz.py -a > $dir/$app-all.dot +python modelviz.py $app > $dir/$app.dot + +dot $dir/$app-all.dot -Tpdf -o $dir/$app-all.pdf +dot $dir/$app.dot -Tpdf -o $dir/$app.pdf + +rsync -a $dir/ doc.parisson.com:/var/www/files/doc/$app/diagram/ diff --git a/example/sandbox/manage.py b/example/sandbox/manage.py new file mode 100755 index 00000000..bcdd55e2 --- /dev/null +++ b/example/sandbox/manage.py @@ -0,0 +1,11 @@ +#!/usr/bin/python +from django.core.management import execute_manager +try: + import settings # Assumed to be in the same directory. +except ImportError: + import sys + sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__) + sys.exit(1) + +if __name__ == "__main__": + execute_manager(settings) diff --git a/example/sandbox/modelviz.py b/example/sandbox/modelviz.py new file mode 100644 index 00000000..24af0627 --- /dev/null +++ b/example/sandbox/modelviz.py @@ -0,0 +1,359 @@ +#!/usr/bin/env python + +"""Django model to DOT (Graphviz) converter +by Antonio Cavedoni + +Make sure your DJANGO_SETTINGS_MODULE is set to your project or +place this script in the same directory of the project and call +the script like this: + +$ python modelviz.py [-h] [-a] [-d] [-g] [-n] [-L ] [-i ] ... > .dot +$ dot .dot -Tpng -o .png + +options: + -h, --help + show this help message and exit. + + -a, --all_applications + show models from all applications. + + -d, --disable_fields + don't show the class member fields. + + -g, --group_models + draw an enclosing box around models from the same app. + + -i, --include_models=User,Person,Car + only include selected models in graph. + + -n, --verbose_names + use verbose_name for field and models. + + -L, --language + specify language used for verrbose_name localization + + -x, --exclude_columns + exclude specific column(s) from the graph. + + -X, --exclude_models + exclude specific model(s) from the graph. + + -e, --inheritance + show inheritance arrows. +""" +__version__ = "0.9" +__svnid__ = "$Id$" +__license__ = "Python" +__author__ = "Antonio Cavedoni " +__contributors__ = [ + "Stefano J. Attardi ", + "limodou ", + "Carlo C8E Miron", + "Andre Campos ", + "Justin Findlay ", + "Alexander Houben ", + "Bas van Oostveen ", + "Joern Hees " +] + +import os +import sys +import getopt + +from django.core.management import setup_environ + +try: + import settings +except ImportError: + pass +else: + setup_environ(settings) + +from django.utils.translation import activate as activate_language +from django.utils.safestring import mark_safe +from django.template import Template, Context, loader +from django.db import models +from django.db.models import get_models +from django.db.models.fields.related import \ + ForeignKey, OneToOneField, ManyToManyField, RelatedField + +try: + from django.db.models.fields.generic import GenericRelation +except ImportError: + from django.contrib.contenttypes.generic import GenericRelation + +def parse_file_or_list(arg): + if not arg: + return [] + if not ',' in arg and os.path.isfile(arg): + return [e.strip() for e in open(arg).readlines()] + return arg.split(',') + + +def generate_dot(app_labels, **kwargs): + disable_fields = kwargs.get('disable_fields', False) + include_models = parse_file_or_list(kwargs.get('include_models', "")) + all_applications = kwargs.get('all_applications', False) + use_subgraph = kwargs.get('group_models', False) + verbose_names = kwargs.get('verbose_names', False) + inheritance = kwargs.get('inheritance', False) + language = kwargs.get('language', None) + if language is not None: + activate_language(language) + exclude_columns = parse_file_or_list(kwargs.get('exclude_columns', "")) + exclude_models = parse_file_or_list(kwargs.get('exclude_models', "")) + + def skip_field(field): + if exclude_columns: + if verbose_names and field.verbose_name: + if field.verbose_name in exclude_columns: + return True + if field.name in exclude_columns: + return True + return False + + + + + t = loader.get_template('django_extensions/graph_models/head.html') + c = Context({}) + dot = t.render(c) + + apps = [] + if all_applications: + apps = models.get_apps() + + for app_label in app_labels: + app = models.get_app(app_label) + if not app in apps: + apps.append(app) + + graphs = [] + for app in apps: + graph = Context({ + 'name': '"%s"' % app.__name__, + 'app_name': "%s" % '.'.join(app.__name__.split('.')[:-1]), + 'cluster_app_name': "cluster_%s" % app.__name__.replace(".", "_"), + 'disable_fields': disable_fields, + 'use_subgraph': use_subgraph, + 'models': [] + }) + + appmodels = get_models(app) + abstract_models = [] + for appmodel in appmodels: + abstract_models = abstract_models + [abstract_model for abstract_model in appmodel.__bases__ if hasattr(abstract_model, '_meta') and abstract_model._meta.abstract] + abstract_models = list(set(abstract_models)) # remove duplicates + appmodels = abstract_models + appmodels + + + for appmodel in appmodels: + appmodel_abstracts = [abstract_model.__name__ for abstract_model in appmodel.__bases__ if hasattr(abstract_model, '_meta') and abstract_model._meta.abstract] + + # collect all attribs of abstract superclasses + def getBasesAbstractFields(c): + _abstract_fields = [] + for e in c.__bases__: + if hasattr(e, '_meta') and e._meta.abstract: + _abstract_fields.extend(e._meta.fields) + _abstract_fields.extend(getBasesAbstractFields(e)) + return _abstract_fields + abstract_fields = getBasesAbstractFields(appmodel) + + model = { + 'app_name': appmodel.__module__.replace(".", "_"), + 'name': appmodel.__name__, + 'abstracts': appmodel_abstracts, + 'fields': [], + 'relations': [] + } + + # consider given model name ? + def consider(model_name): + if exclude_models and model_name in exclude_models: + return False + return not include_models or model_name in include_models + + if not consider(appmodel._meta.object_name): + continue + + if verbose_names and appmodel._meta.verbose_name: + model['label'] = appmodel._meta.verbose_name + else: + model['label'] = model['name'] + + # model attributes + def add_attributes(field): + if verbose_names and field.verbose_name: + label = field.verbose_name + else: + label = field.name + + t = type(field).__name__ + if isinstance(field, (OneToOneField, ForeignKey)): + t += " ({0})".format(field.rel.field_name) + # TODO: ManyToManyField, GenericRelation + + model['fields'].append({ + 'name': field.name, + 'label': label, + 'type': t, + 'blank': field.blank, + 'abstract': field in abstract_fields, + }) + + # Find all the real attributes. Relations are depicted as graph edges instead of attributes + attributes = [field for field in appmodel._meta.local_fields if not isinstance(field, RelatedField)] + + # find primary key and print it first, ignoring implicit id if other pk exists + pk = appmodel._meta.pk + if not appmodel._meta.abstract and pk in attributes: + add_attributes(pk) + for field in attributes: + if skip_field(field): + continue + if not field.primary_key: + add_attributes(field) + + # FIXME: actually many_to_many fields aren't saved in this model's db table, so why should we add an attribute-line for them in the resulting graph? + #if appmodel._meta.many_to_many: + # for field in appmodel._meta.many_to_many: + # if skip_field(field): + # continue + # add_attributes(field) + + # relations + def add_relation(field, extras=""): + if verbose_names and field.verbose_name: + label = field.verbose_name + else: + label = field.name + + # show related field name + if hasattr(field, 'related_query_name'): + label += ' (%s)' % field.related_query_name() + + _rel = { + 'target_app': field.rel.to.__module__.replace('.', '_'), + 'target': field.rel.to.__name__, + 'type': type(field).__name__, + 'name': field.name, + 'label': label, + 'arrows': extras, + 'needs_node': True + } + if _rel not in model['relations'] and consider(_rel['target']): + model['relations'].append(_rel) + + for field in appmodel._meta.local_fields: + if field.attname.endswith('_ptr_id'): # excluding field redundant with inheritance relation + continue + if field in abstract_fields: # excluding fields inherited from abstract classes. they too show as local_fields + continue + if skip_field(field): + continue + if isinstance(field, OneToOneField): + add_relation(field, '[arrowhead=none, arrowtail=none]') + elif isinstance(field, ForeignKey): + add_relation(field, '[arrowhead=none, arrowtail=dot]') + + for field in appmodel._meta.local_many_to_many: + if skip_field(field): + continue + if isinstance(field, ManyToManyField): + if (getattr(field, 'creates_table', False) or # django 1.1. + (hasattr(field.rel.through, '_meta') and field.rel.through._meta.auto_created)): # django 1.2 + add_relation(field, '[arrowhead=dot arrowtail=dot, dir=both]') + elif isinstance(field, GenericRelation): + add_relation(field, mark_safe('[style="dotted", arrowhead=normal, arrowtail=normal, dir=both]')) + + if inheritance: + # add inheritance arrows + for parent in appmodel.__bases__: + if hasattr(parent, "_meta"): # parent is a model + l = "multi-table" + if parent._meta.abstract: + l = "abstract" + if appmodel._meta.proxy: + l = "proxy" + l += r"\ninheritance" + _rel = { + 'target_app': parent.__module__.replace(".", "_"), + 'target': parent.__name__, + 'type': "inheritance", + 'name': "inheritance", + 'label': l, + 'arrows': '[arrowhead=empty, arrowtail=none]', + 'needs_node': True + } + # TODO: seems as if abstract models aren't part of models.getModels, which is why they are printed by this without any attributes. + if _rel not in model['relations'] and consider(_rel['target']): + model['relations'].append(_rel) + + graph['models'].append(model) + graphs.append(graph) + + nodes = [] + for graph in graphs: + nodes.extend([e['name'] for e in graph['models']]) + + for graph in graphs: + # don't draw duplication nodes because of relations + for model in graph['models']: + for relation in model['relations']: + if relation['target'] in nodes: + relation['needs_node'] = False + # render templates + t = loader.get_template('django_extensions/graph_models/body.html') + dot += '\n' + t.render(graph) + + for graph in graphs: + t = loader.get_template('django_extensions/graph_models/rel.html') + dot += '\n' + t.render(graph) + + + t = loader.get_template('django_extensions/graph_models/tail.html') + c = Context({}) + dot += '\n' + t.render(c) + return dot + +def main(): + try: + opts, args = getopt.getopt(sys.argv[1:], "hadgi:L:x:X:en", + ["help", "all_applications", "disable_fields", "group_models", "include_models=", "inheritance", "verbose_names", "language=", "exclude_columns=", "exclude_models="]) + except getopt.GetoptError, error: + print __doc__ + sys.exit(error) + + kwargs = {} + for opt, arg in opts: + if opt in ("-h", "--help"): + print __doc__ + sys.exit() + if opt in ("-a", "--all_applications"): + kwargs['all_applications'] = True + if opt in ("-d", "--disable_fields"): + kwargs['disable_fields'] = True + if opt in ("-g", "--group_models"): + kwargs['group_models'] = True + if opt in ("-i", "--include_models"): + kwargs['include_models'] = arg + if opt in ("-e", "--inheritance"): + kwargs['inheritance'] = True + if opt in ("-n", "--verbose-names"): + kwargs['verbose_names'] = True + if opt in ("-L", "--language"): + kwargs['language'] = arg + if opt in ("-x", "--exclude_columns"): + kwargs['exclude_columns'] = arg + if opt in ("-X", "--exclude_models"): + kwargs['exclude_models'] = arg + + if not args and not kwargs.get('all_applications', False): + print __doc__ + sys.exit() + + print generate_dot(args, **kwargs) + +if __name__ == "__main__": + main() diff --git a/example/sandbox/settings.py b/example/sandbox/settings.py new file mode 100644 index 00000000..75741ef0 --- /dev/null +++ b/example/sandbox/settings.py @@ -0,0 +1,163 @@ +# -*- coding: utf-8 -*- +# Django settings for sandbox project. + +import os +from django.core.urlresolvers import reverse_lazy + +DEBUG = True +TEMPLATE_DEBUG = DEBUG + +ADMINS = ( + ('Guillaume Pellerin', 'yomguy@parisson.com'), +) + +MANAGERS = ADMINS + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. + 'NAME': 'sandbox.sql', # Or path to database file if using sqlite3. + 'USER': '', # Not used with sqlite3. + 'PASSWORD': '', # Not used with sqlite3. + 'HOST': '', # Set to empty string for localhost. Not used with sqlite3. + 'PORT': '', # Set to empty string for default. Not used with sqlite3. + } +} + +# Local time zone for this installation. Choices can be found here: +# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name +# although not all choices may be available on all operating systems. +# On Unix systems, a value of None will cause Django to use the same +# timezone as the operating system. +# If running in a Windows environment this must be set to the same as your +# system time zone. +TIME_ZONE = 'Europe/Paris' + +# Language code for this installation. All choices can be found here: +# http://www.i18nguy.com/unicode/language-identifiers.html +#LANGUAGE_CODE = 'fr_FR' +LANGUAGES = [ ('fr', 'French'), + ('en', 'English'), +] + +SITE_ID = 1 + +# If you set this to False, Django will make some optimizations so as not +# to load the internationalization machinery. +USE_I18N = True + +# If you set this to False, Django will not format dates, numbers and +# calendars according to the current locale +USE_L10N = True + +# Absolute path to the directory that holds media. +# Example: "/home/media/media.lawrence.com/" +MEDIA_ROOT = os.path.join(os.path.dirname(__file__), 'media/') + +if not os.path.exists(MEDIA_ROOT): + os.mkdir(MEDIA_ROOT) + +# URL that handles the media served from MEDIA_ROOT. Make sure to use a +# trailing slash if there is a path component (optional in other cases). +# Examples: "http://media.lawrence.com", "http://example.com/media/" +MEDIA_URL = '/media/' + +# Absolute path to the directory static files should be collected to. +# Don't put anything in this directory yourself; store your static files +# in apps' "static/" subdirectories and in STATICFILES_DIRS. +# Example: "/home/media/media.lawrence.com/static/" +STATIC_ROOT = '/var/www/static/' + +# URL prefix for static files. +# Example: "http://media.lawrence.com/static/" +STATIC_URL = '/static/' + +# Additional locations of static files +STATICFILES_DIRS = ( +# Put strings here, like "/home/html/static" or "C:/www/django/static". +# Always use forward slashes, even on Windows. +# Don't forget to use absolute paths, not relative paths. +) + +# List of finder classes that know how to find static files in +# various locations. +STATICFILES_FINDERS = ( +'django.contrib.staticfiles.finders.FileSystemFinder', +'django.contrib.staticfiles.finders.AppDirectoriesFinder', +# 'django.contrib.staticfiles.finders.DefaultStorageFinder', +) +# Make this unique, and don't share it with anybody. +SECRET_KEY = 'a8l7%06wr2k+3=%#*#@#rvop2mmzko)44%7k(zx%lls^ihm9^5' + +# List of callables that know how to import templates from various sources. +TEMPLATE_LOADERS = ( + 'django.template.loaders.filesystem.Loader', + 'django.template.loaders.app_directories.Loader', +# 'django.template.loaders.eggs.Loader', +) + + +MIDDLEWARE_CLASSES = ( + 'django.middleware.common.CommonMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.locale.LocaleMiddleware', +) + +ROOT_URLCONF = 'sandbox_sqlite.urls' + +TEMPLATE_DIRS = ( + # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". + # Always use forward slashes, even on Windows. + # Don't forget to use absolute paths, not relative paths. + '', +) + +INSTALLED_APPS = ( + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.sites', + 'django.contrib.messages', + 'django.contrib.admin', + 'django.contrib.staticfiles', + 'django_extensions', + 'telemeta', + 'timeside', + 'jsonrpc', + 'south', + 'sorl.thumbnail', +) + +TEMPLATE_CONTEXT_PROCESSORS = ( + 'django.core.context_processors.request', + 'django.contrib.auth.context_processors.auth', + "django.core.context_processors.i18n", + "django.core.context_processors.media", + 'django.core.context_processors.static', +) + +TELEMETA_ORGANIZATION = 'Parisson' +TELEMETA_SUBJECTS = ('test', 'telemeta', 'sandbox') +TELEMETA_DESCRIPTION = "Telemeta TEST sandbox" +TELEMETA_GMAP_KEY = 'ABQIAAAArg7eSfnfTkBRma8glnGrlxRVbMrhnNNvToCbZQtWdaMbZTA_3RRGObu5PDoiBImgalVnnLU2yN4RMA' +TELEMETA_CACHE_DIR = MEDIA_ROOT + 'cache/' +TELEMETA_EXPORT_CACHE_DIR = MEDIA_ROOT + 'export/' +TELEMETA_DATA_CACHE_DIR = TELEMETA_CACHE_DIR + "data/" + +TELEMETA_DOWNLOAD_ENABLED = True +TELEMETA_STREAMING_FORMATS = ('mp3', 'webm') +TELEMETA_DOWNLOAD_FORMATS = ('wav', 'mp3', 'webm') +TELEMETA_PUBLIC_ACCESS_PERIOD = 51 +TELEMETA_DEFAULT_WAVEFORM_SIZES = ['360x130', '640x130'] + +AUTH_PROFILE_MODULE = 'telemeta.userprofile' +SESSION_EXPIRE_AT_BROWSER_CLOSE = False + +LOGIN_URL = '/login/' +LOGIN_REDIRECT_URL = reverse_lazy('telemeta-desk-lists') + +EMAIL_HOST = 'localhost' +DEFAULT_FROM_EMAIL = 'webmaster@parisson.com' diff --git a/example/sandbox/update_schema.sh b/example/sandbox/update_schema.sh new file mode 100755 index 00000000..31c658a1 --- /dev/null +++ b/example/sandbox/update_schema.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +./manage.py schemamigration telemeta --auto +./manage.py migrate telemeta + diff --git a/example/sandbox/urls.py b/example/sandbox/urls.py new file mode 100644 index 00000000..6dd41922 --- /dev/null +++ b/example/sandbox/urls.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +from django.conf.urls.defaults import * + +# Uncomment the next two lines to enable the admin: +from django.contrib import admin +admin.autodiscover() + +js_info_dict = { + 'packages': ('telemeta',), +} + +urlpatterns = patterns('', + # Example: + # (r'^sandbox/', include('sandbox.foo.urls')), + + # Uncomment the admin/doc line below and add 'django.contrib.admindocs' + # to INSTALLED_APPS to enable admin documentation: + # (r'^admin/doc/', include('django.contrib.admindocs.urls')), + + # Uncomment the next line to enable the admin: + (r'^admin/django/', include(admin.site.urls)), + + # Telemeta + (r'^', include('telemeta.urls')), + + # Languages + (r'^i18n/', include('django.conf.urls.i18n')), + (r'^jsi18n/$', 'django.views.i18n.javascript_catalog', js_info_dict), +) diff --git a/example/sandbox/wsgi.py b/example/sandbox/wsgi.py new file mode 100644 index 00000000..642c8723 --- /dev/null +++ b/example/sandbox/wsgi.py @@ -0,0 +1,14 @@ +#!/usr/bin/python2.5 +# -*- coding: utf-8 -*- + +import os +import sys + +here = os.path.dirname(__file__) +sys.path.append(here) + +os.environ['DJANGO_SETTINGS_MODULE'] = 'sandbox.settings' + +import django.core.handlers.wsgi +application = django.core.handlers.wsgi.WSGIHandler() + diff --git a/example/sandbox_mysql/__init__.py b/example/sandbox_mysql/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/example/sandbox_mysql/manage.py b/example/sandbox_mysql/manage.py deleted file mode 100755 index bcdd55e2..00000000 --- a/example/sandbox_mysql/manage.py +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/python -from django.core.management import execute_manager -try: - import settings # Assumed to be in the same directory. -except ImportError: - import sys - sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__) - sys.exit(1) - -if __name__ == "__main__": - execute_manager(settings) diff --git a/example/sandbox_mysql/settings.py b/example/sandbox_mysql/settings.py deleted file mode 100644 index f0888698..00000000 --- a/example/sandbox_mysql/settings.py +++ /dev/null @@ -1,160 +0,0 @@ -# -*- coding: utf-8 -*- -# Django settings for sandbox project. - -import os.path -from django.core.urlresolvers import reverse_lazy - -DEBUG = True -TEMPLATE_DEBUG = DEBUG - -ADMINS = ( - ('Guillaume Pellerin', 'yomguy@parisson.com'), -) - -MANAGERS = ADMINS - -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. - 'NAME': 'telemeta_sandbox', # Or path to database file if using sqlite3. - 'USER': 'demo', # Not used with sqlite3. - 'PASSWORD': 'demo', # Not used with sqlite3. - 'HOST': '', # Set to empty string for localhost. Not used with sqlite3. - 'PORT': '', # Set to empty string for default. Not used with sqlite3. - } -} - -# Local time zone for this installation. Choices can be found here: -# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name -# although not all choices may be available on all operating systems. -# On Unix systems, a value of None will cause Django to use the same -# timezone as the operating system. -# If running in a Windows environment this must be set to the same as your -# system time zone. -TIME_ZONE = 'Europe/Paris' - -# Language code for this installation. All choices can be found here: -# http://www.i18nguy.com/unicode/language-identifiers.html -#LANGUAGE_CODE = 'fr_FR' -LANGUAGES = [ ('fr', 'French'), - ('en', 'English'), -] - -SITE_ID = 1 - -# If you set this to False, Django will make some optimizations so as not -# to load the internationalization machinery. -USE_I18N = True - -# If you set this to False, Django will not format dates, numbers and -# calendars according to the current locale -USE_L10N = True - -# Absolute path to the directory that holds media. -# Example: "/home/media/media.lawrence.com/" -MEDIA_ROOT = '/var/telemeta/media/' - -# URL that handles the media served from MEDIA_ROOT. Make sure to use a -# trailing slash if there is a path component (optional in other cases). -# Examples: "http://media.lawrence.com", "http://example.com/media/" -MEDIA_URL = '/media/' - -# Absolute path to the directory static files should be collected to. -# Don't put anything in this directory yourself; store your static files -# in apps' "static/" subdirectories and in STATICFILES_DIRS. -# Example: "/home/media/media.lawrence.com/static/" -STATIC_ROOT = '/var/www/static/' - -# URL prefix for static files. -# Example: "http://media.lawrence.com/static/" -STATIC_URL = '/static/' - -# Additional locations of static files -STATICFILES_DIRS = ( -# Put strings here, like "/home/html/static" or "C:/www/django/static". -# Always use forward slashes, even on Windows. -# Don't forget to use absolute paths, not relative paths. -) - -# List of finder classes that know how to find static files in -# various locations. -STATICFILES_FINDERS = ( -'django.contrib.staticfiles.finders.FileSystemFinder', -'django.contrib.staticfiles.finders.AppDirectoriesFinder', -# 'django.contrib.staticfiles.finders.DefaultStorageFinder', -) - -# Make this unique, and don't share it with anybody. -SECRET_KEY = 'a8l7%06wr2k+3=%#*#@#rvop2mmzko)44%7k(zx%lls^ihm9^5' - -# List of callables that know how to import templates from various sources. -TEMPLATE_LOADERS = ( - 'django.template.loaders.filesystem.Loader', - 'django.template.loaders.app_directories.Loader', -# 'django.template.loaders.eggs.Loader', -) - - -MIDDLEWARE_CLASSES = ( - 'django.middleware.common.CommonMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.locale.LocaleMiddleware', -) - -ROOT_URLCONF = 'sandbox_mysql.urls' - -TEMPLATE_DIRS = ( - # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". - # Always use forward slashes, even on Windows. - # Don't forget to use absolute paths, not relative paths. - '', -) - -INSTALLED_APPS = ( - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.sites', - 'django.contrib.messages', - 'django.contrib.admin', - 'django.contrib.staticfiles', - 'telemeta', - 'timeside', - 'jsonrpc', - 'south', - 'sorl.thumbnail', -) - -TEMPLATE_CONTEXT_PROCESSORS = ( - 'django.core.context_processors.request', - 'django.contrib.auth.context_processors.auth', - "django.core.context_processors.i18n", - "django.core.context_processors.media", - 'django.core.context_processors.static', -) - -TELEMETA_ORGANIZATION = 'Parisson' -TELEMETA_SUBJECTS = ('test', 'telemeta', 'sandbox') -TELEMETA_DESCRIPTION = "Telemeta TEST sandbox" -TELEMETA_GMAP_KEY = 'ABQIAAAArg7eSfnfTkBRma8glnGrlxRVbMrhnNNvToCbZQtWdaMbZTA_3RRGObu5PDoiBImgalVnnLU2yN4RMA' -TELEMETA_CACHE_DIR = MEDIA_ROOT + 'cache' -TELEMETA_EXPORT_CACHE_DIR = MEDIA_ROOT + 'export' -TELEMETA_DATA_CACHE_DIR = TELEMETA_CACHE_DIR + "/data" - -TELEMETA_DOWNLOAD_ENABLED = True -TELEMETA_STREAMING_FORMATS = ('mp3', 'webm') -TELEMETA_DOWNLOAD_FORMATS = ('wav', 'mp3', 'webm') -TELEMETA_PUBLIC_ACCESS_PERIOD = 51 -TELEMETA_DEFAULT_WAVEFORM_SIZES = ['360x130', '640x130'] - -AUTH_PROFILE_MODULE = 'telemeta.userprofile' -SESSION_EXPIRE_AT_BROWSER_CLOSE = False - -LOGIN_URL = '/login/' -LOGIN_REDIRECT_URL = reverse_lazy('telemeta-desk-lists') - -EMAIL_HOST = 'smtp.free.fr' -DEFAULT_FROM_EMAIL = 'webmaster@parisson.com' diff --git a/example/sandbox_mysql/urls.py b/example/sandbox_mysql/urls.py deleted file mode 100644 index 6dd41922..00000000 --- a/example/sandbox_mysql/urls.py +++ /dev/null @@ -1,29 +0,0 @@ -# -*- coding: utf-8 -*- -from django.conf.urls.defaults import * - -# Uncomment the next two lines to enable the admin: -from django.contrib import admin -admin.autodiscover() - -js_info_dict = { - 'packages': ('telemeta',), -} - -urlpatterns = patterns('', - # Example: - # (r'^sandbox/', include('sandbox.foo.urls')), - - # Uncomment the admin/doc line below and add 'django.contrib.admindocs' - # to INSTALLED_APPS to enable admin documentation: - # (r'^admin/doc/', include('django.contrib.admindocs.urls')), - - # Uncomment the next line to enable the admin: - (r'^admin/django/', include(admin.site.urls)), - - # Telemeta - (r'^', include('telemeta.urls')), - - # Languages - (r'^i18n/', include('django.conf.urls.i18n')), - (r'^jsi18n/$', 'django.views.i18n.javascript_catalog', js_info_dict), -) diff --git a/example/sandbox_sqlite/__init__.py b/example/sandbox_sqlite/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/example/sandbox_sqlite/diag.sh b/example/sandbox_sqlite/diag.sh deleted file mode 100755 index 5f6c1e59..00000000 --- a/example/sandbox_sqlite/diag.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh - -app="telemeta" -dir="../../doc/devel" - -python modelviz.py -a > $dir/$app-all.dot -python modelviz.py $app > $dir/$app.dot - -dot $dir/$app-all.dot -Tpdf -o $dir/$app-all.pdf -dot $dir/$app.dot -Tpdf -o $dir/$app.pdf - -rsync -a $dir/ doc.parisson.com:/var/www/files/doc/$app/diagram/ diff --git a/example/sandbox_sqlite/manage.py b/example/sandbox_sqlite/manage.py deleted file mode 100755 index bcdd55e2..00000000 --- a/example/sandbox_sqlite/manage.py +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/python -from django.core.management import execute_manager -try: - import settings # Assumed to be in the same directory. -except ImportError: - import sys - sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__) - sys.exit(1) - -if __name__ == "__main__": - execute_manager(settings) diff --git a/example/sandbox_sqlite/modelviz.py b/example/sandbox_sqlite/modelviz.py deleted file mode 100644 index 24af0627..00000000 --- a/example/sandbox_sqlite/modelviz.py +++ /dev/null @@ -1,359 +0,0 @@ -#!/usr/bin/env python - -"""Django model to DOT (Graphviz) converter -by Antonio Cavedoni - -Make sure your DJANGO_SETTINGS_MODULE is set to your project or -place this script in the same directory of the project and call -the script like this: - -$ python modelviz.py [-h] [-a] [-d] [-g] [-n] [-L ] [-i ] ... > .dot -$ dot .dot -Tpng -o .png - -options: - -h, --help - show this help message and exit. - - -a, --all_applications - show models from all applications. - - -d, --disable_fields - don't show the class member fields. - - -g, --group_models - draw an enclosing box around models from the same app. - - -i, --include_models=User,Person,Car - only include selected models in graph. - - -n, --verbose_names - use verbose_name for field and models. - - -L, --language - specify language used for verrbose_name localization - - -x, --exclude_columns - exclude specific column(s) from the graph. - - -X, --exclude_models - exclude specific model(s) from the graph. - - -e, --inheritance - show inheritance arrows. -""" -__version__ = "0.9" -__svnid__ = "$Id$" -__license__ = "Python" -__author__ = "Antonio Cavedoni " -__contributors__ = [ - "Stefano J. Attardi ", - "limodou ", - "Carlo C8E Miron", - "Andre Campos ", - "Justin Findlay ", - "Alexander Houben ", - "Bas van Oostveen ", - "Joern Hees " -] - -import os -import sys -import getopt - -from django.core.management import setup_environ - -try: - import settings -except ImportError: - pass -else: - setup_environ(settings) - -from django.utils.translation import activate as activate_language -from django.utils.safestring import mark_safe -from django.template import Template, Context, loader -from django.db import models -from django.db.models import get_models -from django.db.models.fields.related import \ - ForeignKey, OneToOneField, ManyToManyField, RelatedField - -try: - from django.db.models.fields.generic import GenericRelation -except ImportError: - from django.contrib.contenttypes.generic import GenericRelation - -def parse_file_or_list(arg): - if not arg: - return [] - if not ',' in arg and os.path.isfile(arg): - return [e.strip() for e in open(arg).readlines()] - return arg.split(',') - - -def generate_dot(app_labels, **kwargs): - disable_fields = kwargs.get('disable_fields', False) - include_models = parse_file_or_list(kwargs.get('include_models', "")) - all_applications = kwargs.get('all_applications', False) - use_subgraph = kwargs.get('group_models', False) - verbose_names = kwargs.get('verbose_names', False) - inheritance = kwargs.get('inheritance', False) - language = kwargs.get('language', None) - if language is not None: - activate_language(language) - exclude_columns = parse_file_or_list(kwargs.get('exclude_columns', "")) - exclude_models = parse_file_or_list(kwargs.get('exclude_models', "")) - - def skip_field(field): - if exclude_columns: - if verbose_names and field.verbose_name: - if field.verbose_name in exclude_columns: - return True - if field.name in exclude_columns: - return True - return False - - - - - t = loader.get_template('django_extensions/graph_models/head.html') - c = Context({}) - dot = t.render(c) - - apps = [] - if all_applications: - apps = models.get_apps() - - for app_label in app_labels: - app = models.get_app(app_label) - if not app in apps: - apps.append(app) - - graphs = [] - for app in apps: - graph = Context({ - 'name': '"%s"' % app.__name__, - 'app_name': "%s" % '.'.join(app.__name__.split('.')[:-1]), - 'cluster_app_name': "cluster_%s" % app.__name__.replace(".", "_"), - 'disable_fields': disable_fields, - 'use_subgraph': use_subgraph, - 'models': [] - }) - - appmodels = get_models(app) - abstract_models = [] - for appmodel in appmodels: - abstract_models = abstract_models + [abstract_model for abstract_model in appmodel.__bases__ if hasattr(abstract_model, '_meta') and abstract_model._meta.abstract] - abstract_models = list(set(abstract_models)) # remove duplicates - appmodels = abstract_models + appmodels - - - for appmodel in appmodels: - appmodel_abstracts = [abstract_model.__name__ for abstract_model in appmodel.__bases__ if hasattr(abstract_model, '_meta') and abstract_model._meta.abstract] - - # collect all attribs of abstract superclasses - def getBasesAbstractFields(c): - _abstract_fields = [] - for e in c.__bases__: - if hasattr(e, '_meta') and e._meta.abstract: - _abstract_fields.extend(e._meta.fields) - _abstract_fields.extend(getBasesAbstractFields(e)) - return _abstract_fields - abstract_fields = getBasesAbstractFields(appmodel) - - model = { - 'app_name': appmodel.__module__.replace(".", "_"), - 'name': appmodel.__name__, - 'abstracts': appmodel_abstracts, - 'fields': [], - 'relations': [] - } - - # consider given model name ? - def consider(model_name): - if exclude_models and model_name in exclude_models: - return False - return not include_models or model_name in include_models - - if not consider(appmodel._meta.object_name): - continue - - if verbose_names and appmodel._meta.verbose_name: - model['label'] = appmodel._meta.verbose_name - else: - model['label'] = model['name'] - - # model attributes - def add_attributes(field): - if verbose_names and field.verbose_name: - label = field.verbose_name - else: - label = field.name - - t = type(field).__name__ - if isinstance(field, (OneToOneField, ForeignKey)): - t += " ({0})".format(field.rel.field_name) - # TODO: ManyToManyField, GenericRelation - - model['fields'].append({ - 'name': field.name, - 'label': label, - 'type': t, - 'blank': field.blank, - 'abstract': field in abstract_fields, - }) - - # Find all the real attributes. Relations are depicted as graph edges instead of attributes - attributes = [field for field in appmodel._meta.local_fields if not isinstance(field, RelatedField)] - - # find primary key and print it first, ignoring implicit id if other pk exists - pk = appmodel._meta.pk - if not appmodel._meta.abstract and pk in attributes: - add_attributes(pk) - for field in attributes: - if skip_field(field): - continue - if not field.primary_key: - add_attributes(field) - - # FIXME: actually many_to_many fields aren't saved in this model's db table, so why should we add an attribute-line for them in the resulting graph? - #if appmodel._meta.many_to_many: - # for field in appmodel._meta.many_to_many: - # if skip_field(field): - # continue - # add_attributes(field) - - # relations - def add_relation(field, extras=""): - if verbose_names and field.verbose_name: - label = field.verbose_name - else: - label = field.name - - # show related field name - if hasattr(field, 'related_query_name'): - label += ' (%s)' % field.related_query_name() - - _rel = { - 'target_app': field.rel.to.__module__.replace('.', '_'), - 'target': field.rel.to.__name__, - 'type': type(field).__name__, - 'name': field.name, - 'label': label, - 'arrows': extras, - 'needs_node': True - } - if _rel not in model['relations'] and consider(_rel['target']): - model['relations'].append(_rel) - - for field in appmodel._meta.local_fields: - if field.attname.endswith('_ptr_id'): # excluding field redundant with inheritance relation - continue - if field in abstract_fields: # excluding fields inherited from abstract classes. they too show as local_fields - continue - if skip_field(field): - continue - if isinstance(field, OneToOneField): - add_relation(field, '[arrowhead=none, arrowtail=none]') - elif isinstance(field, ForeignKey): - add_relation(field, '[arrowhead=none, arrowtail=dot]') - - for field in appmodel._meta.local_many_to_many: - if skip_field(field): - continue - if isinstance(field, ManyToManyField): - if (getattr(field, 'creates_table', False) or # django 1.1. - (hasattr(field.rel.through, '_meta') and field.rel.through._meta.auto_created)): # django 1.2 - add_relation(field, '[arrowhead=dot arrowtail=dot, dir=both]') - elif isinstance(field, GenericRelation): - add_relation(field, mark_safe('[style="dotted", arrowhead=normal, arrowtail=normal, dir=both]')) - - if inheritance: - # add inheritance arrows - for parent in appmodel.__bases__: - if hasattr(parent, "_meta"): # parent is a model - l = "multi-table" - if parent._meta.abstract: - l = "abstract" - if appmodel._meta.proxy: - l = "proxy" - l += r"\ninheritance" - _rel = { - 'target_app': parent.__module__.replace(".", "_"), - 'target': parent.__name__, - 'type': "inheritance", - 'name': "inheritance", - 'label': l, - 'arrows': '[arrowhead=empty, arrowtail=none]', - 'needs_node': True - } - # TODO: seems as if abstract models aren't part of models.getModels, which is why they are printed by this without any attributes. - if _rel not in model['relations'] and consider(_rel['target']): - model['relations'].append(_rel) - - graph['models'].append(model) - graphs.append(graph) - - nodes = [] - for graph in graphs: - nodes.extend([e['name'] for e in graph['models']]) - - for graph in graphs: - # don't draw duplication nodes because of relations - for model in graph['models']: - for relation in model['relations']: - if relation['target'] in nodes: - relation['needs_node'] = False - # render templates - t = loader.get_template('django_extensions/graph_models/body.html') - dot += '\n' + t.render(graph) - - for graph in graphs: - t = loader.get_template('django_extensions/graph_models/rel.html') - dot += '\n' + t.render(graph) - - - t = loader.get_template('django_extensions/graph_models/tail.html') - c = Context({}) - dot += '\n' + t.render(c) - return dot - -def main(): - try: - opts, args = getopt.getopt(sys.argv[1:], "hadgi:L:x:X:en", - ["help", "all_applications", "disable_fields", "group_models", "include_models=", "inheritance", "verbose_names", "language=", "exclude_columns=", "exclude_models="]) - except getopt.GetoptError, error: - print __doc__ - sys.exit(error) - - kwargs = {} - for opt, arg in opts: - if opt in ("-h", "--help"): - print __doc__ - sys.exit() - if opt in ("-a", "--all_applications"): - kwargs['all_applications'] = True - if opt in ("-d", "--disable_fields"): - kwargs['disable_fields'] = True - if opt in ("-g", "--group_models"): - kwargs['group_models'] = True - if opt in ("-i", "--include_models"): - kwargs['include_models'] = arg - if opt in ("-e", "--inheritance"): - kwargs['inheritance'] = True - if opt in ("-n", "--verbose-names"): - kwargs['verbose_names'] = True - if opt in ("-L", "--language"): - kwargs['language'] = arg - if opt in ("-x", "--exclude_columns"): - kwargs['exclude_columns'] = arg - if opt in ("-X", "--exclude_models"): - kwargs['exclude_models'] = arg - - if not args and not kwargs.get('all_applications', False): - print __doc__ - sys.exit() - - print generate_dot(args, **kwargs) - -if __name__ == "__main__": - main() diff --git a/example/sandbox_sqlite/settings.py b/example/sandbox_sqlite/settings.py deleted file mode 100644 index 2e21f4ae..00000000 --- a/example/sandbox_sqlite/settings.py +++ /dev/null @@ -1,163 +0,0 @@ -# -*- coding: utf-8 -*- -# Django settings for sandbox project. - -import os -from django.core.urlresolvers import reverse_lazy - -DEBUG = True -TEMPLATE_DEBUG = DEBUG - -ADMINS = ( - ('Guillaume Pellerin', 'yomguy@parisson.com'), -) - -MANAGERS = ADMINS - -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. - 'NAME': 'sandbox.sql', # Or path to database file if using sqlite3. - 'USER': '', # Not used with sqlite3. - 'PASSWORD': '', # Not used with sqlite3. - 'HOST': '', # Set to empty string for localhost. Not used with sqlite3. - 'PORT': '', # Set to empty string for default. Not used with sqlite3. - } -} - -# Local time zone for this installation. Choices can be found here: -# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name -# although not all choices may be available on all operating systems. -# On Unix systems, a value of None will cause Django to use the same -# timezone as the operating system. -# If running in a Windows environment this must be set to the same as your -# system time zone. -TIME_ZONE = 'Europe/Paris' - -# Language code for this installation. All choices can be found here: -# http://www.i18nguy.com/unicode/language-identifiers.html -#LANGUAGE_CODE = 'fr_FR' -LANGUAGES = [ ('fr', 'French'), - ('en', 'English'), -] - -SITE_ID = 1 - -# If you set this to False, Django will make some optimizations so as not -# to load the internationalization machinery. -USE_I18N = True - -# If you set this to False, Django will not format dates, numbers and -# calendars according to the current locale -USE_L10N = True - -# Absolute path to the directory that holds media. -# Example: "/home/media/media.lawrence.com/" -MEDIA_ROOT = os.path.join(os.path.dirname(__file__), 'media/') - -if not os.path.exists(MEDIA_ROOT): - os.mkdir(MEDIA_ROOT) - -# URL that handles the media served from MEDIA_ROOT. Make sure to use a -# trailing slash if there is a path component (optional in other cases). -# Examples: "http://media.lawrence.com", "http://example.com/media/" -MEDIA_URL = '/media/' - -# Absolute path to the directory static files should be collected to. -# Don't put anything in this directory yourself; store your static files -# in apps' "static/" subdirectories and in STATICFILES_DIRS. -# Example: "/home/media/media.lawrence.com/static/" -STATIC_ROOT = '/var/www/static/' - -# URL prefix for static files. -# Example: "http://media.lawrence.com/static/" -STATIC_URL = '/static/' - -# Additional locations of static files -STATICFILES_DIRS = ( -# Put strings here, like "/home/html/static" or "C:/www/django/static". -# Always use forward slashes, even on Windows. -# Don't forget to use absolute paths, not relative paths. -) - -# List of finder classes that know how to find static files in -# various locations. -STATICFILES_FINDERS = ( -'django.contrib.staticfiles.finders.FileSystemFinder', -'django.contrib.staticfiles.finders.AppDirectoriesFinder', -# 'django.contrib.staticfiles.finders.DefaultStorageFinder', -) -# Make this unique, and don't share it with anybody. -SECRET_KEY = 'a8l7%06wr2k+3=%#*#@#rvop2mmzko)44%7k(zx%lls^ihm9^5' - -# List of callables that know how to import templates from various sources. -TEMPLATE_LOADERS = ( - 'django.template.loaders.filesystem.Loader', - 'django.template.loaders.app_directories.Loader', -# 'django.template.loaders.eggs.Loader', -) - - -MIDDLEWARE_CLASSES = ( - 'django.middleware.common.CommonMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.locale.LocaleMiddleware', -) - -ROOT_URLCONF = 'sandbox_sqlite.urls' - -TEMPLATE_DIRS = ( - # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". - # Always use forward slashes, even on Windows. - # Don't forget to use absolute paths, not relative paths. - '', -) - -INSTALLED_APPS = ( - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.sites', - 'django.contrib.messages', - 'django.contrib.admin', - 'django.contrib.staticfiles', - 'django_extensions', - 'telemeta', - 'timeside', - 'jsonrpc', - 'south', - 'sorl.thumbnail', -) - -TEMPLATE_CONTEXT_PROCESSORS = ( - 'django.core.context_processors.request', - 'django.contrib.auth.context_processors.auth', - "django.core.context_processors.i18n", - "django.core.context_processors.media", - 'django.core.context_processors.static', -) - -TELEMETA_ORGANIZATION = 'Parisson' -TELEMETA_SUBJECTS = ('test', 'telemeta', 'sandbox') -TELEMETA_DESCRIPTION = "Telemeta TEST sandbox" -TELEMETA_GMAP_KEY = 'ABQIAAAArg7eSfnfTkBRma8glnGrlxRVbMrhnNNvToCbZQtWdaMbZTA_3RRGObu5PDoiBImgalVnnLU2yN4RMA' -TELEMETA_CACHE_DIR = MEDIA_ROOT + 'cache' -TELEMETA_EXPORT_CACHE_DIR = MEDIA_ROOT + 'export' -TELEMETA_DATA_CACHE_DIR = TELEMETA_CACHE_DIR + "/data" - -TELEMETA_DOWNLOAD_ENABLED = True -TELEMETA_STREAMING_FORMATS = ('mp3', 'webm') -TELEMETA_DOWNLOAD_FORMATS = ('wav', 'mp3', 'webm') -TELEMETA_PUBLIC_ACCESS_PERIOD = 51 -TELEMETA_DEFAULT_WAVEFORM_SIZES = ['360x130', '640x130'] - -AUTH_PROFILE_MODULE = 'telemeta.userprofile' -SESSION_EXPIRE_AT_BROWSER_CLOSE = False - -LOGIN_URL = '/login/' -LOGIN_REDIRECT_URL = reverse_lazy('telemeta-desk-lists') - -EMAIL_HOST = 'localhost' -DEFAULT_FROM_EMAIL = 'webmaster@parisson.com' diff --git a/example/sandbox_sqlite/update_schema.sh b/example/sandbox_sqlite/update_schema.sh deleted file mode 100755 index 31c658a1..00000000 --- a/example/sandbox_sqlite/update_schema.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -./manage.py schemamigration telemeta --auto -./manage.py migrate telemeta - diff --git a/example/sandbox_sqlite/urls.py b/example/sandbox_sqlite/urls.py deleted file mode 100644 index 6dd41922..00000000 --- a/example/sandbox_sqlite/urls.py +++ /dev/null @@ -1,29 +0,0 @@ -# -*- coding: utf-8 -*- -from django.conf.urls.defaults import * - -# Uncomment the next two lines to enable the admin: -from django.contrib import admin -admin.autodiscover() - -js_info_dict = { - 'packages': ('telemeta',), -} - -urlpatterns = patterns('', - # Example: - # (r'^sandbox/', include('sandbox.foo.urls')), - - # Uncomment the admin/doc line below and add 'django.contrib.admindocs' - # to INSTALLED_APPS to enable admin documentation: - # (r'^admin/doc/', include('django.contrib.admindocs.urls')), - - # Uncomment the next line to enable the admin: - (r'^admin/django/', include(admin.site.urls)), - - # Telemeta - (r'^', include('telemeta.urls')), - - # Languages - (r'^i18n/', include('django.conf.urls.i18n')), - (r'^jsi18n/$', 'django.views.i18n.javascript_catalog', js_info_dict), -)