Skip to content
This repository
Browse code

remove from last cherry picking

  • Loading branch information...
commit 49e4dcd1264e221ec766803c4246c291d1331e7b 1 parent 00f6728
Benoit Chesneau benoitc authored

Showing 1 changed file with 0 additions and 795 deletions. Show diff stats Hide diff stats

  1. +0 795 python/couchapp/file_manager.py
795 python/couchapp/file_manager.py
... ... @@ -1,795 +0,0 @@
1   -#!/usr/bin/env python
2   -# -*- coding: utf-8 -*-
3   -#
4   -# Copyright 2009 Benoit Chesneau <benoitc@e-engura.org>
5   -#
6   -# This software is licensed as described in the file LICENSE, which
7   -# you should have received as part of this distribution.
8   -#
9   -
10   -import glob
11   -import httplib
12   -import os
13   -import re
14   -import shutil
15   -import socket
16   -import sys
17   -import time
18   -import urllib
19   -
20   -# python 2.6
21   -try:
22   - import json
23   -except ImportError:
24   - import simplejson as json
25   -
26   -
27   -import httplib2
28   -from couchdb import Server, ResourceNotFound
29   -
30   -from couchapp.config import get_userconf, get_config
31   -from couchapp.utils import _md5, to_bytestring
32   -from couchapp.utils import *
33   -
34   -__all__ = ['DEFAULT_SERVER_URI', 'FileManager']
35   -
36   -DEFAULT_SERVER_URI = 'http://127.0.0.1:5984/'
37   -
38   -DEFAULT_LOCATIONS = {
39   - "template": ['app-template', '../../app-template'],
40   - "vendor": ['vendor', '../../vendor']
41   -}
42   -
43   -
44   -def _server(server_uri):
45   - if "@" in server_uri:
46   - http = httplib2.Http()
47   - username, password, server_uri = parse_auth(server_uri)
48   - couchdb_server = Server(server_uri)
49   - http.add_credentials(username, password)
50   - couchdb_server.resource.http = http
51   - else:
52   - couchdb_server = Server(server_uri)
53   - return couchdb_server
54   -
55   -class Couchapp(object):
56   -
57   - def __init__(self, app_dir=".", generate=False, verbose=False):
58   - self.app_dir = ""
59   - if generate:
60   - self.generate(verbose=verbose)
61   -
62   - def initialize(self, default_conf=None, verbose=False):
63   - if not os.path.isdir(self.app_dir):
64   - print>>sys.stderr, "%s directory doesn't exist." % self.app_dir
65   - return
66   -
67   - default_conf = default_conf or {}
68   -
69   - rc_file = '%s/.couchapprc' % self.app_dir
70   - if not os.path.isfile(rc_file):
71   - write_json(rc_file, default_conf)
72   - elif verbose:
73   - print>>sys.stderr, "CouchApp already initialized in %s." % app_dir
74   -
75   -
76   - def generate(self, verbose=False):
77   - """ Generates a CouchApp in app_dir """
78   -
79   - locations = {}
80   - for location, paths in DEFAULT_LOCATIONS.items():
81   - found = False
82   - location_dir = ""
83   - for path in paths:
84   - location_dir = os.path.normpath(os.path.join(
85   - os.path.dirname(__file__), path))
86   - if os.path.isdir(location_dir):
87   - found = True
88   - break
89   - if found:
90   - if location == "template":
91   - dest_dir = self.app_dir
92   - else:
93   - dest_dir = os.path.join(self.app_dir, 'vendor')
94   -
95   - try:
96   - shutil.copytree(location_dir, dest_dir)
97   - except OSError, e:
98   - errno, message = e
99   - print >>sys.stderr, "Can't create a CouchApp in %s: %s" % (
100   - app_dir, message)
101   - return
102   - self.initialize(verbose=verbose)
103   -
104   - def clone(self, design_doc, verbose=None):
105   - app_name = get_appname(design_doc['_id'])
106   - if verbose >= 1:
107   - print "Cloning %s to %s..." % (app_name, self.app_dir)
108   -
109   -
110   - if not self.app_dir:
111   - app_dir = os.path.normpath(os.path.join(os.getcwd(), app_name))
112   -
113   -
114   -
115   -class FileManager(object):
116   -
117   - def __init__(self, dbstring, app_dir='.'):
118   - self.app_dir = app_dir
119   -
120   - # load conf
121   - self.conf = get_conf(app_dir)
122   -
123   - if not dbstring or not "/" in dbstring:
124   - env = self.conf.get('env', {})
125   - if dbstring:
126   - if dbstring in env:
127   - db_env = env[dbstring]['db']
128   - else:
129   - db_env = "%s/%s" % (DEFAULT_SERVER_URI, dbstring)
130   - else:
131   - if 'default' in env:
132   - db_env = env['default']['db']
133   - else:
134   - raise ValueError("database isn't specified")
135   -
136   - if isinstance(db_env, basestring):
137   - self.db_url = [db_env]
138   - else:
139   - self.db_url = db_env
140   - else:
141   - self.db_url = [dbstring]
142   -
143   - db = []
144   - for s in self.db_url:
145   - server_uri, db_name, docid = parse_uri(s)
146   -
147   - couchdb_server = _server(server_uri)
148   -
149   - # create dbs if it don't exist
150   - try:
151   - _db = couchdb_server.create(db_name)
152   - except: # db already exist
153   - _db = couchdb_server[db_name]
154   - db.append(_db)
155   - self.db = db
156   -
157   -
158   - @classmethod
159   - def generate_app(cls, app_dir):
160   - """Generates a CouchApp in app_dir"""
161   - template_paths = ['app-template', '../../app-template']
162   - vendor_paths = ['vendor', '../../vendor']
163   -
164   - for path in template_paths:
165   - template_dir = os.path.normpath(os.path.join(
166   - os.path.dirname(__file__), path))
167   - if os.path.isdir(template_dir): break
168   -
169   - for path in vendor_paths:
170   - vendor_dir = os.path.normpath(os.path.join(
171   - os.path.dirname(__file__), path))
172   - if os.path.isdir(vendor_dir): break
173   -
174   - try:
175   - shutil.copytree(template_dir, app_dir)
176   - except OSError, e:
177   - errno, message = e
178   - print >>sys.stderr, "Can't create a CouchApp in %s: %s" % (
179   - app_dir, message)
180   - return
181   -
182   - if vendor_dir:
183   - vendor_path = os.path.join(app_dir, 'vendor')
184   - try:
185   - shutil.copytree(vendor_dir, vendor_path)
186   - except OSError, e:
187   - errno, message = e
188   - print >>sys.stderr, "Can't create a CouchApp, bad vendor dir: %s" % message
189   - return
190   -
191   - cls.init(app_dir)
192   -
193   - @classmethod
194   - def init(cls, app_dir, db_url=''):
195   - """Initializes the .couchapprc, usually called after generate"""
196   - if not os.path.isdir(app_dir):
197   - print>>sys.stderr, "%s directory doesn't exist." % app_dir
198   - return
199   -
200   - userconf = get_userconf()
201   - if 'default' in userconf:
202   - conf = {
203   - "env": {
204   - "default": userconf['env']['default']
205   - }
206   - }
207   - else:
208   - conf = {}
209   -
210   - rc_file = '%s/.couchapprc' % app_dir
211   - if not os.path.isfile(rc_file):
212   - if db_url:
213   - conf.update({ "env": {
214   - "default": {
215   - "db": db_url
216   - }
217   - }})
218   -
219   - write_json(rc_file, conf)
220   - else:
221   - print>>sys.stderr, "CouchApp already initialized in %s." % app_dir
222   -
223   -
224   -
225   - def push_app(self, app_dir, app_name, verbose=False, **kwargs):
226   - """Pushes the app specified to the CouchDB instance"""
227   - docid = '_design/%s' % app_name
228   -
229   - attach_dir = os.path.join(app_dir, '_attachments')
230   -
231   - manifest = []
232   - self.doc = doc = self.dir_to_fields(app_dir, manifest=manifest,
233   - verbose=verbose)
234   -
235   - self.objects = {}
236   - if 'shows' in doc:
237   - self.package_shows(doc['shows'], app_dir, verbose=verbose)
238   -
239   - if 'lists' in doc:
240   - self.package_shows(doc['lists'], app_dir, verbose=verbose)
241   -
242   - if 'validate_doc_update' in doc:
243   - tmp_dict = dict(validate_doc_update=doc["validate_doc_update"])
244   - self.package_shows(tmp_dict, app_dir, verbose=verbose)
245   - doc.update(tmp_dict)
246   -
247   - if 'views' in doc:
248   - self.package_views(doc["views"], app_dir, verbose=verbose)
249   -
250   -
251   - for db in self.db:
252   - if verbose >= 1:
253   - print "Pushing CouchApp in %s to design doc:\n%s/_design/%s" % (app_dir,
254   - db.resource.uri, app_name)
255   - couchapp = doc.get('couchapp', False)
256   - if couchapp:
257   - index = couchapp.get('index', False)
258   - else:
259   - index = False
260   - index_url = self.make_index_url(db.resource.uri, app_name, attach_dir, index)
261   - if index_url:
262   - print "Visit your CouchApp here:\n%s" % index_url
263   -
264   - new_doc = doc.copy()
265   -
266   - if docid in db:
267   - design = db[docid]
268   -
269   - _app_meta = design.get('couchapp', {})
270   -
271   - app_meta = {
272   - 'manifest': manifest,
273   - 'signatures': _app_meta.get('signatures', {}),
274   - 'objects': self.objects
275   - }
276   -
277   - new_doc.update({
278   - '_id': docid,
279   - '_rev': design['_rev'],
280   - 'couchapp': app_meta,
281   - '_attachments': design.get('_attachments', {})
282   - })
283   - else:
284   - new_doc.update({
285   - 'couchapp': {
286   - 'manifest': manifest,
287   - 'objects': self.objects
288   - }
289   - })
290   -
291   - if 'couchapp' in doc:
292   - new_doc['couchapp'].update(doc['couchapp'])
293   -
294   - db[docid] = new_doc
295   -
296   -
297   - self.push_directory(attach_dir, docid, verbose=verbose)
298   - self.vendor_attachments(app_dir, docid, verbose=verbose)
299   -
300   -
301   - @classmethod
302   - def clone(cls, app_uri, app_dir, verbose=False):
303   - """Clone a CouchApp from app_uri into app_dir"""
304   - server_uri, db_name, docid = parse_uri(app_uri)
305   - couchdb_server = _server(server_uri)
306   -
307   - try:
308   - db = couchdb_server.create(db_name)
309   - except: # db already exist
310   - db = couchdb_server[db_name]
311   -
312   - app_name = get_appname(docid)
313   - if verbose >= 1:
314   - print "Cloning %s to %s..." % (app_name, app_dir)
315   - if not app_dir:
316   - app_dir = os.path.normpath(os.path.join(os.getcwd(), app_name))
317   -
318   - rc_file = os.path.join(app_dir, '.couchapprc')
319   -
320   - if not os.path.isdir(app_dir):
321   - os.makedirs(app_dir)
322   - else:
323   - # delete only if there is .couchapp folder
324   - if os.path.isfile(rc_file):
325   - for root, dirs, files in os.walk(app_dir,
326   - topdown=False):
327   - if root == app_dir:
328   - if '_attachments' in dirs:
329   - dirs.remove('_attachments')
330   - if '.couchapprc' in files:
331   - files.remove('.couchapprc')
332   - for name in files:
333   - os.remove(os.path.join(root, name))
334   -
335   - for name in dirs:
336   - os.rmdir(os.path.join(root, name))
337   -
338   - try:
339   - design = db[docid]
340   - except ResourceNotFound:
341   - print >>sys.stderr, "%s don't exist" % app_name
342   - return
343   -
344   - metadata = design.get('couchapp', {})
345   -
346   - # get manifest
347   - manifest = metadata.get('manifest', {})
348   -
349   - # get signatures
350   - signatures = metadata.get('signatures', {})
351   -
352   - # get objects refs
353   - objects = metadata.get('objects', {})
354   -
355   - conf = read_json(rc_file)
356   - if not 'env' in conf:
357   - conf['env'] = {}
358   - conf['env'].update({
359   - 'origin': {
360   - 'db': db.resource.uri
361   - }
362   - })
363   -
364   - write_json(rc_file, conf)
365   -
366   - # create files from manifest
367   - if manifest:
368   - for filename in manifest:
369   - if verbose >=2:
370   - print "clone property: %s" % filename
371   - file_path = os.path.join(app_dir, filename)
372   - if filename.endswith('/'):
373   - if not os.path.isdir(file_path):
374   - os.makedirs(file_path)
375   - elif filename == "couchapp.json":
376   - continue
377   - else:
378   - parts = filename.split('/')
379   - fname = parts.pop()
380   - v = design
381   - while 1:
382   - try:
383   - for key in parts:
384   - v = v[key]
385   - except KeyError:
386   - break
387   -
388   - # remove extension
389   - last_key, ext = os.path.splitext(fname)
390   -
391   - # make sure key exist
392   - try:
393   - content = v[last_key]
394   - except KeyError:
395   - break
396   -
397   - if isinstance(content, basestring):
398   - _ref = _md5(to_bytestring(content)).hexdigest()
399   - if objects and _ref in objects:
400   - content = objects[_ref]
401   -
402   - if fname.endswith('.json'):
403   - content = json.dumps(content)
404   -
405   - del v[last_key]
406   -
407   - # make sure file dir have been created
408   - file_dir = os.path.dirname(file_path)
409   - if not os.path.isdir(file_dir):
410   - os.makedirs(file_dir)
411   -
412   - write_content(file_path, content)
413   -
414   - # remove the key from design doc
415   - temp = design
416   - for key2 in parts:
417   - if key2 == key:
418   - if not temp[key2]:
419   - del temp[key2]
420   - break
421   - temp = temp[key2]
422   -
423   - # second pass for missing key or in case
424   - # manifest isn't in app
425   - for key in design.iterkeys():
426   - if key.startswith('_'):
427   - continue
428   - elif key in ('couchapp'):
429   - app_meta = design['couchapp'].copy()
430   - if 'signatures' in app_meta:
431   - del app_meta['signatures']
432   - if 'manifest' in app_meta:
433   - del app_meta['manifest']
434   - if 'objects' in app_meta:
435   - del app_meta['objects']
436   - if app_meta:
437   - couchapp_file = os.path.join(app_dir, 'couchapp.json')
438   - write_json(couchapp_file, app_meta)
439   - elif key in ('views'):
440   - vs_dir = os.path.join(app_dir, key)
441   - if not os.path.isdir(vs_dir):
442   - os.makedirs(vs_dir)
443   - for vsname, vs_item in design[key].iteritems():
444   - vs_item_dir = os.path.join(vs_dir, vsname)
445   - if not os.path.isdir(vs_item_dir):
446   - os.makedirs(vs_item_dir)
447   - for func_name, func in vs_item.iteritems():
448   - filename = os.path.join(vs_item_dir, '%s.js' %
449   - func_name)
450   - open(filename, 'w').write(func)
451   - if verbose >=2:
452   - print "clone view not in manifest: %s" % filename
453   - elif key in ('shows', 'lists'):
454   - dir = os.path.join(app_dir, key)
455   - if not os.path.isdir(dir):
456   - os.makedirs(dir)
457   - for func_name, func in design[key].iteritems():
458   - filename = os.path.join(dir, '%s.js' %
459   - func_name)
460   - open(filename, 'w').write(func)
461   - if verbose >=2:
462   - print "clone show or list not in manifest: %s" % filename
463   - else:
464   - file_dir = os.path.join(app_dir, key)
465   - if verbose >=2:
466   - print "clone property not in manifest: %s" % key
467   - if isinstance(design[key], (list, tuple,)):
468   - write_json(file_dir + ".json", design[key])
469   - elif isinstance(design[key], dict):
470   - if not os.path.isdir(file_dir):
471   - os.makedirs(file_dir)
472   - for field, value in design[key].iteritems():
473   - field_path = os.path.join(file_dir, field)
474   - if isinstance(value, basestring):
475   - write_content(field_path, value)
476   - else:
477   - write_json(field_path + '.json', value)
478   - else:
479   - value = design[key]
480   - if not isinstance(value, basestring):
481   - value = str(value)
482   - write_content(file_dir, value)
483   -
484   -
485   - # get attachments
486   - if '_attachments' in design:
487   - attach_dir = os.path.join(app_dir, '_attachments')
488   - if not os.path.isdir(attach_dir):
489   - os.makedirs(attach_dir)
490   - for filename in design['_attachments'].iterkeys():
491   - if filename.startswith('vendor'):
492   - attach_parts = filename.split('/')
493   - vendor_attach_dir = os.path.join(app_dir, attach_parts.pop(0),
494   - attach_parts.pop(0), '_attachments')
495   - file_path = os.path.join(vendor_attach_dir, '/'.join(attach_parts))
496   - else:
497   - file_path = os.path.join(attach_dir, filename)
498   - current_dir = os.path.dirname(file_path)
499   - if not os.path.isdir(current_dir):
500   - os.makedirs(current_dir)
501   -
502   - if signatures.get(filename) != sign_file(file_path):
503   - content = db.get_attachment(docid, filename)
504   - write_content(file_path, content)
505   - if verbose>=2:
506   - print "clone attachment: %s" % filename
507   -
508   - def dir_to_fields(self, app_dir, current_dir='', depth=0,
509   - manifest=[], verbose=False):
510   - fields={}
511   - if not current_dir:
512   - current_dir = app_dir
513   - for name in os.listdir(current_dir):
514   - current_path = os.path.join(current_dir, name)
515   - rel_path = current_path.split("%s/" % app_dir)[1]
516   - if name.startswith('.'):
517   - continue
518   - elif name.startswith('_'):
519   - # files starting with "_" are always "special"
520   - continue
521   - elif depth == 0 and name in ('couchapp', 'couchapp.json'):
522   - # we are in app_meta
523   - if name == "couchapp":
524   - manifest.append('%s/' % rel_path)
525   - content = self.dir_to_fields(app_dir, current_path,
526   - depth=depth+1, manifest=manifest)
527   - else:
528   - manifest.append(rel_path)
529   - content = read_json(current_path)
530   - if not isinstance(content, dict):
531   - content = { "meta": content }
532   - if 'signatures' in content:
533   - del content['signatures']
534   -
535   - if 'manifest' in content:
536   - del content['manifest']
537   -
538   - if 'objects' in content:
539   - del content['objects']
540   -
541   - if 'couchapp' in fields:
542   - fields['couchapp'].update(content)
543   - else:
544   - fields['couchapp'] = content
545   - elif os.path.isdir(current_path):
546   - manifest.append('%s/' % rel_path)
547   - fields[name] = self.dir_to_fields(app_dir, current_path,
548   - depth=depth+1, manifest=manifest,
549   - verbose=verbose)
550   - else:
551   - if verbose >= 2:
552   - print >>sys.stderr, "push %s" % rel_path
553   - content = ''
554   - try:
555   - content = read_file(current_path)
556   - except UnicodeDecodeError, e:
557   - print >>sys.stderr, str(e)
558   - if name.endswith('.json'):
559   - try:
560   - content = json.loads(content)
561   - except ValueError:
562   - if verbose >= 2:
563   - print >>sys.stderr, "Json invalid in %s" % current_path
564   -
565   - # remove extension
566   - name, ext = os.path.splitext(name)
567   - if name in fields:
568   - if verbose >= 2:
569   - print >>sys.stderr, "%(name)s is already in properties. Can't add (%(name)s%(ext)s)" % {
570   - "name": name,
571   - "ext": ext
572   - }
573   - else:
574   - manifest.append(rel_path)
575   - fields[name] = content
576   - return fields
577   -
578   - def _put_attachment(self, db, doc, content, filename):
579   - nb_try = 0
580   - while True:
581   - error = False
582   - try:
583   - db.put_attachment(doc, content, filename)
584   - except (socket.error, httplib.BadStatusLine):
585   - time.sleep(0.4)
586   - error = True
587   -
588   - nb_try = nb_try +1
589   - if not error:
590   - break
591   -
592   - if nb_try > 3:
593   - if verbose >= 2:
594   - print >>sys.stderr, "%s file not uploaded, sorry." % filename
595   - break
596   -
597   - def vendor_attachments(self, app_dir, docid, verbose):
598   - vendor_dir = os.path.join(app_dir, 'vendor')
599   - if not os.path.isdir(vendor_dir):
600   - return
601   -
602   - for name in os.listdir(vendor_dir):
603   - current_path = os.path.join(vendor_dir, name)
604   - if os.path.isdir(current_path):
605   - attach_dir = os.path.join(current_path, '_attachments')
606   - if os.path.isdir(attach_dir):
607   - self.push_directory(attach_dir, docid, verbose,
608   - vendor=name)
609   -
610   - def push_directory(self, attach_dir, docid, verbose=False, vendor=None):
611   - # get attachments
612   - _signatures = {}
613   - _attachments = {}
614   - all_signatures = {}
615   - for root, dirs, files in os.walk(attach_dir):
616   - if files:
617   - for filename in files:
618   - if filename.startswith('.'):
619   - continue
620   - else:
621   - file_path = os.path.join(root, filename)
622   - name = file_path.split('%s/' % attach_dir)[1]
623   - if vendor is not None:
624   - name = os.path.join('vendor/%s' % vendor, name)
625   - signature = sign_file(file_path)
626   - _signatures[name] = signature
627   - _attachments[name] = open(file_path, 'rb')
628   -
629   - # detect attachments to be removed and keep
630   - # only new version attachments to update.
631   - for db in self.db:
632   - design = db[docid]
633   - metadata = design.get('couchapp', {})
634   - attachments = _attachments.copy()
635   - if 'signatures' in metadata:
636   - all_signatures = metadata['signatures'].copy()
637   - for filename in metadata['signatures'].iterkeys():
638   - if vendor is not None:
639   - if filename.startswith('vendor/%s' % vendor):
640   - del all_signatures[filename]
641   - if filename not in _signatures:
642   - db.delete_attachment(design, filename)
643   - elif _signatures[filename] == metadata['signatures'][filename]:
644   - del attachments[filename]
645   -
646   - else:
647   - if not filename.startswith('vendor'):
648   - del all_signatures[filename]
649   - if filename not in _signatures:
650   - db.delete_attachment(design, filename)
651   - else:
652   - if _signatures[filename] == metadata['signatures'][filename]:
653   - del attachments[filename]
654   -
655   - for filename, value in attachments.iteritems():
656   - if verbose >= 2:
657   - print "Attaching %s" % filename
658   -
659   - # fix issue with httplib that raises BadStatusLine
660   - # error because it didn't close the connection
661   - self._put_attachment(db, design, value, filename)
662   -
663   - # update signatures
664   - design = db[docid]
665   - if not 'couchapp' in design:
666   - design['couchapp'] = {}
667   -
668   - all_signatures.update(_signatures)
669   -
670   - design['couchapp'].update({'signatures': all_signatures})
671   - db[docid] = design
672   -
673   - def package_shows(self, funcs, app_dir, verbose=False):
674   - self.apply_lib(funcs, app_dir, verbose=verbose)
675   -
676   - def package_views(self, views, app_dir, verbose=False):
677   - for view, funcs in views.iteritems():
678   - self.apply_lib(funcs, app_dir, verbose=verbose)
679   -
680   -
681   - def apply_lib(self, funcs, app_dir, verbose=False):
682   - if not hasattr(self, "objects"):
683   - self.objects = {}
684   - for k, v in funcs.iteritems():
685   - if not isinstance(v, basestring):
686   - continue
687   - old_v = v
688   - try:
689   - funcs[k] = self.run_json_macros(
690   - self.run_code_macros(v, app_dir, verbose=verbose),
691   - app_dir, verbose=verbose)
692   - except ValueError, e:
693   - print >>sys.stderr, "Error running !code or !json on function \"%s\": %s" % (k, e)
694   - sys.exit(-1)
695   - if old_v != funcs[k]:
696   - self.objects[_md5(to_bytestring(funcs[k])).hexdigest()] = old_v
697   -
698   - def run_code_macros(self, f_string, app_dir, verbose=False):
699   - def rreq(mo):
700   - # just read the file and return it
701   - path = os.path.join(app_dir, mo.group(2).strip(' '))
702   - library = ''
703   - filenum = 0
704   - for filename in glob.iglob(path):
705   - if verbose>=2:
706   - print "process code macro: %s" % filename
707   - try:
708   - library += read_file(filename)
709   - except IOError, e:
710   - print >>sys.stderr, e
711   - sys.exit(-1)
712   - filenum += 1
713   -
714   - if not filenum:
715   - print >>sys.stderr, "Processing code: No file matching '%s'" % mo.group(2)
716   - sys.exit(-1)
717   -
718   - return library
719   -
720   - re_code = re.compile('(\/\/|#)\ ?!code (.*)')
721   - return re_code.sub(rreq, f_string)
722   -
723   - def run_json_macros(self, f_string, app_dir, verbose=False):
724   - included = {}
725   - varstrings = []
726   -
727   - def rjson(mo):
728   - if mo.group(2).startswith('_attachments'):
729   - # someone want to include from attachments
730   - path = os.path.join(app_dir, mo.group(2).strip(' '))
731   - filenum = 0
732   - for filename in glob.iglob(path):
733   - library = ''
734   - try:
735   - if filename.endswith('.json'):
736   - library = read_json(filename)
737   - else:
738   - library = read_file(filename)
739   - except IOError, e:
740   - print >>sys.stderr, e
741   - sys.exit(1)
742   - filenum += 1
743   - current_file = filename.split(app_dir)[1]
744   - fields = current_file.split('/')
745   - count = len(fields)
746   - include_to = included
747   - for i, field in enumerate(fields):
748   - if i+1 < count:
749   - include_to[field] = {}
750   - include_to = include_to[field]
751   - else:
752   - include_to[field] = library
753   - if not filenum:
754   - print >>sys.stderr, "Processing code: No file matching '%s'" % mo.group(2)
755   - sys.exit(-1)
756   - else:
757   - fields = mo.group(2).split('.')
758   - library = self.doc
759   - count = len(fields)
760   - include_to = included
761   - for i, field in enumerate(fields):
762   - if not field in library: break
763   - library = library[field]
764   - if i+1 < count:
765   - include_to[field] = include_to.get(field, {})
766   - include_to = include_to[field]
767   - else:
768   - include_to[field] = library
769   -
770   - return f_string
771   -
772   - def rjson2(mo):
773   - return '\n'.join(varstrings)
774   -
775   - re_json = re.compile('(\/\/|#)\ ?!json (.*)')
776   - re_json.sub(rjson, f_string)
777   -
778   - if not included:
779   - return f_string
780   -
781   - for k, v in included.iteritems():
782   - varstrings.append("var %s = %s;" % (k, json.dumps(v)))
783   -
784   - return re_json.sub(rjson2, f_string)
785   -
786   - def make_index_url(self, uri, app_name, attach_dir, index):
787   - if index:
788   - return "%s/%s/%s/%s" % (uri, '_design', app_name, index)
789   - else:
790   - index_fpath = os.path.join(attach_dir, 'index.html')
791   - if os.path.isfile(index_fpath):
792   - return "%s/%s/%s/%s" % (uri, '_design', app_name, 'index.html')
793   - else:
794   -
795   - return False

0 comments on commit 49e4dcd

Please sign in to comment.
Something went wrong with that request. Please try again.