Bienvenue sur PostGIS.fr

Bienvenue sur PostGIS.fr , le site de la communauté des utilisateurs francophones de PostGIS.

PostGIS ajoute le support d'objets géographique à la base de données PostgreSQL. En effet, PostGIS "spatialise" le serverur PostgreSQL, ce qui permet de l'utiliser comme une base de données SIG.

Maintenu à jour, en fonction de nos disponibilités et des diverses sorties des outils que nous testons, nous vous proposons l'ensemble de nos travaux publiés en langue française.

source: trunk/workshop-routing-foss4g/web/proj4js/tools/mergejs.py @ 76

Revision 76, 8.0 KB checked in by djay, 12 years ago (diff)

Ajout du répertoire web

  • Property svn:executable set to *
Line 
1#!/usr/bin/env python
2#
3# Merge multiple JavaScript source code files into one.
4#
5# Usage:
6# This script requires source files to have dependencies specified in them.
7#
8# Dependencies are specified with a comment of the form:
9#
10#     // @requires <file path>
11#
12#  e.g.
13#
14#    // @requires Geo/DataSource.js
15#
16#  or (ideally) within a class comment definition
17#
18#     /**
19#      * @class
20#      *
21#      * @requires OpenLayers/Layer.js
22#      */
23#
24# This script should be executed like so:
25#
26#     mergejs.py <output.js> <directory> [...]
27#
28# e.g.
29#
30#     mergejs.py openlayers.js Geo/ CrossBrowser/
31#
32#  This example will cause the script to walk the `Geo` and
33#  `CrossBrowser` directories--and subdirectories thereof--and import
34#  all `*.js` files encountered. The dependency declarations will be extracted
35#  and then the source code from imported files will be output to
36#  a file named `openlayers.js` in an order which fulfils the dependencies
37#  specified.
38#
39#
40# Note: This is a very rough initial version of this code.
41#
42# -- Copyright 2005-2007 MetaCarta, Inc. / OpenLayers project --
43#
44
45# TODO: Allow files to be excluded. e.g. `Crossbrowser/DebugMode.js`?
46# TODO: Report error when dependency can not be found rather than KeyError.
47
48import re
49import os
50import sys
51import glob
52
53SUFFIX_JAVASCRIPT = ".js"
54
55RE_REQUIRE = "@requires (.*)\n" # TODO: Ensure in comment?
56class SourceFile:
57    """
58    Represents a Javascript source code file.
59    """
60
61    def __init__(self, filepath, source):
62        """
63        """
64        self.filepath = filepath
65        self.source = source
66
67        self.requiredBy = []
68
69
70    def _getRequirements(self):
71        """
72        Extracts the dependencies specified in the source code and returns
73        a list of them.
74        """
75        # TODO: Cache?
76        return re.findall(RE_REQUIRE, self.source)
77
78    requires = property(fget=_getRequirements, doc="")
79
80
81
82def usage(filename):
83    """
84    Displays a usage message.
85    """
86    print "%s [-c <config file>] <output.js> <directory> [...]" % filename
87
88
89class Config:
90    """
91    Represents a parsed configuration file.
92
93    A configuration file should be of the following form:
94
95        [first]
96        3rd/prototype.js
97        core/application.js
98        core/params.js
99
100        [last]
101        core/api.js
102
103        [exclude]
104        3rd/logger.js
105
106    All headings are required.
107
108    The files listed in the `first` section will be forced to load
109    *before* all other files (in the order listed). The files in `last`
110    section will be forced to load *after* all the other files (in the
111    order listed).
112
113    The files list in the `exclude` section will not be imported.
114   
115    """
116
117    def __init__(self, filename):
118        """
119        Parses the content of the named file and stores the values.
120        """
121        lines = [line.strip() # Assumes end-of-line character is present
122                 for line in open(filename)
123                 if line.strip()] # Skip blank lines
124
125        self.forceFirst = lines[lines.index("[first]") + 1:lines.index("[last]")]
126
127        self.forceLast = lines[lines.index("[last]") + 1:lines.index("[include]")]
128        self.include =  lines[lines.index("[include]") + 1:lines.index("[exclude]")]
129        self.exclude =  lines[lines.index("[exclude]") + 1:]
130
131def run (sourceDirectory, outputFilename = None, configFile = None):
132    cfg = None
133    if configFile:
134        cfg = Config(configFile)
135
136    allFiles = []
137
138    ## Find all the Javascript source files
139    for root, dirs, files in os.walk(sourceDirectory):
140        for filename in files:
141            if filename.endswith(SUFFIX_JAVASCRIPT) and not filename.startswith("."):
142                filepath = os.path.join(root, filename)[len(sourceDirectory)+1:]
143                filepath = filepath.replace("\\", "/")
144                if cfg and cfg.include:
145                    include = False
146                    for included in cfg.include:
147                        if glob.fnmatch.fnmatch(filepath, included):
148                            include = True
149                    if include or filepath in cfg.forceFirst:
150                        allFiles.append(filepath)
151                elif (not cfg) or (filepath not in cfg.exclude):
152                    exclude = False
153                    for excluded in cfg.exclude:
154                        if glob.fnmatch.fnmatch(filepath, excluded):
155                            exclude = True
156                    if not exclude:
157                        allFiles.append(filepath)
158
159    ## Header inserted at the start of each file in the output
160    HEADER = "/* " + "=" * 70 + "\n    %s\n" + "   " + "=" * 70 + " */\n\n"
161
162    files = {}
163
164    order = [] # List of filepaths to output, in a dependency satisfying order
165
166    ## Import file source code
167    ## TODO: Do import when we walk the directories above?
168    for filepath in allFiles:
169        print "Importing: %s" % filepath
170        fullpath = os.path.join(sourceDirectory, filepath)
171        content = open(fullpath, "U").read() # TODO: Ensure end of line @ EOF?
172        files[filepath] = SourceFile(filepath, content) # TODO: Chop path?
173
174    print
175
176    from toposort import toposort
177
178    complete = False
179    resolution_pass = 1
180
181    while not complete:
182        order = [] # List of filepaths to output, in a dependency satisfying order
183        nodes = []
184        routes = []
185        ## Resolve the dependencies
186        print "Resolution pass %s... " % resolution_pass
187        resolution_pass += 1 
188
189        for filepath, info in files.items():
190            nodes.append(filepath)
191            for neededFilePath in info.requires:
192                routes.append((neededFilePath, filepath))
193
194        for dependencyLevel in toposort(nodes, routes):
195            for filepath in dependencyLevel:
196                order.append(filepath)
197                if not files.has_key(filepath):
198                    print "Importing: %s" % filepath
199                    fullpath = os.path.join(sourceDirectory, filepath)
200                    content = open(fullpath, "U").read() # TODO: Ensure end of line @ EOF?
201                    files[filepath] = SourceFile(filepath, content) # TODO: Chop path?
202       
203
204
205        # Double check all dependencies have been met
206        complete = True
207        try:
208            for fp in order:
209                if max([order.index(rfp) for rfp in files[fp].requires] +
210                       [order.index(fp)]) != order.index(fp):
211                    complete = False
212        except:
213            complete = False
214       
215        print   
216
217
218    ## Move forced first and last files to the required position
219    if cfg:
220        print "Re-ordering files..."
221        order = cfg.forceFirst + [item
222                     for item in order
223                     if ((item not in cfg.forceFirst) and
224                         (item not in cfg.forceLast))] + cfg.forceLast
225   
226    print
227    ## Output the files in the determined order
228    result = []
229
230    for fp in order:
231        f = files[fp]
232        print "Exporting: ", f.filepath
233        result.append(HEADER % f.filepath)
234        source = f.source
235        result.append(source)
236        if not source.endswith("\n"):
237            result.append("\n")
238
239    print "\nTotal files merged: %d " % len(files)
240
241    if outputFilename:
242        print "\nGenerating: %s" % (outputFilename)
243        open(outputFilename, "w").write("".join(result))
244    return "".join(result)
245
246if __name__ == "__main__":
247    import getopt
248
249    options, args = getopt.getopt(sys.argv[1:], "-c:")
250   
251    try:
252        outputFilename = args[0]
253    except IndexError:
254        usage(sys.argv[0])
255        raise SystemExit
256    else:
257        sourceDirectory = args[1]
258        if not sourceDirectory:
259            usage(sys.argv[0])
260            raise SystemExit
261
262    configFile = None
263    if options and options[0][0] == "-c":
264        configFile = options[0][1]
265        print "Parsing configuration file: %s" % filename
266
267    run( sourceDirectory, outputFilename, configFile )
Note: See TracBrowser for help on using the repository browser.