Permalink
Browse files

ignore bad file structure in macros (don't raise unobious error). Allow

the possibility to have binary files in couchapp outside _attachments.
Files are b64encoded in couchdb and decoded when cloned. Files content
b64encoded start with  "base64-encoded;" string.
  • Loading branch information...
benoitc committed Jun 24, 2009
1 parent 3c03cbf commit d5d8f556b207a8a88997b9830a2597e09114408e
Showing with 35 additions and 18 deletions.
  1. +20 −8 src/couchapp/app.py
  2. +1 −1 src/couchapp/macros.py
  3. +14 −9 src/couchapp/ui.py
View
@@ -215,6 +215,7 @@ def push(self, dbstring, app_name, **kwargs):
self.send_attachments(db, design_doc)
else:
self.encode_attachments(db, design_doc, new_doc)
+
db[docid] = new_doc
self.extensions.notify("post-push", self.ui, self, db=db)
@@ -360,6 +361,7 @@ def mycallbacl(app_dir, app_name, design_doc, verbose=verbose):
if 'lists' in design_doc:
package_shows(design_doc, design_doc['lists'], self.app_dir, objects, self.ui)
+
if 'validate_doc_update' in design_doc:
tmp_dict = dict(validate_doc_update=design_doc["validate_doc_update"])
@@ -369,15 +371,16 @@ def mycallbacl(app_dir, app_name, design_doc, verbose=verbose):
if 'views' in design_doc:
package_views(design_doc, design_doc["views"], self.app_dir, objects, self.ui)
+
couchapp = design_doc.get('couchapp', {})
couchapp.update({
'manifest': manifest,
'objects': objects
})
design_doc['couchapp'] = couchapp
-
self.attachments(design_doc, attach_dir, docid)
+
self.vendor_attachments(design_doc, docid)
# what we do after retrieving design_doc from app_dir
@@ -395,11 +398,9 @@ def dir_to_fields(self, current_dir='', depth=0,
for name in self.ui.listdir(current_dir):
current_path = self.ui.rjoin(current_dir, name)
rel_path = current_path.split("%s/" % self.app_dir)[1]
- if name == '.couchapprc':
+ if name.startswith("."):
continue
- elif name == ".couchapp_ignore":
- continue
- elif name.startswith('_'):
+ elif depth == 0 and name.startswith('_'):
# files starting with "_" are always "special"
continue
elif depth == 0 and (name == 'couchapp' or name == 'couchapp.json'):
@@ -440,7 +441,15 @@ def dir_to_fields(self, current_dir='', depth=0,
try:
content = self.ui.read(current_path)
except UnicodeDecodeError, e:
- self.ui.logger.error(str(e))
+ self.ui.logger.error("%s isn't encoded in utf8" % current_path)
+ content = self.ui.read(current_path, utf8=False)
+ try:
+ content.encode('utf-8')
+ except UnicodeError, e:
+ self.ui.logger.error("plan B didn't work, %s is a binary" % current_path)
+ self.ui.logger.error("use plan C: encode to base64")
+ content = "base64-encoded;%s" % base64.b64encode(content)
+
if name.endswith('.json'):
try:
content = json.loads(content)
@@ -450,7 +459,7 @@ def dir_to_fields(self, current_dir='', depth=0,
# remove extension
name, ext = os.path.splitext(name)
- if name in fields:
+ if name in fields and ext in ('.txt'):
if self.ui.verbose >= 2:
self.ui.logger.error("%(name)s is already in properties. Can't add (%(name)s%(ext)s)" % {
"name": name, "ext": ext })
@@ -533,7 +542,7 @@ def designdoc_to_fs(self, db, design_doc):
if manifest:
for filename in manifest:
if self.ui.verbose >=2:
- print "clone property: %s" % filename
+ self.ui.logger.info("clone property: %s" % filename)
file_path = self.ui.rjoin(self.app_dir, filename)
if filename.endswith('/'):
if not self.ui.isdir(file_path):
@@ -563,6 +572,9 @@ def designdoc_to_fs(self, db, design_doc):
_ref = md5(to_bytestring(content)).hexdigest()
if objects and _ref in objects:
content = objects[_ref]
+
+ if content.startswith('base64-encoded;'):
+ content = base64.b64decode(content[15:])
if fname.endswith('.json'):
content = json.dumps(content)
View
@@ -37,7 +37,7 @@ def apply_lib(doc, funcs, app_dir, objs, ui):
raise MacroError("Error running !code or !json on function \"%s\": %s" % (k, e))
if old_v != funcs[k]:
objs[md5(to_bytestring(funcs[k])).hexdigest()] = old_v
-
+
def run_code_macros(f_string, app_dir, ui):
def rreq(mo):
# just read the file and return it
View
@@ -130,18 +130,23 @@ def sign(self, fpath):
:return: string, md5 hexdigest
"""
if self.isfile(fpath):
- content = self.read(fpath)
+ content = self.read(fpath, force_read=True)
return md5(to_bytestring(content)).hexdigest()
return ''
- def read(self, fname):
+ def read(self, fname, utf8=True, force_read=False):
""" read file content"""
- try:
- f = codecs.open(fname, 'rb', "utf-8")
- data = f.read()
- f.close()
- except:
- f = open(fname, 'rb')
+ if utf8:
+ try:
+ f = codecs.open(fname, 'rb', "utf-8")
+ data = f.read()
+ f.close()
+ except UnicodeError, e:
+ if force_read:
+ return self.read(fname, utf8=False)
+ raise
+ else:
+ f = open(fname, 'rn')
data = f.read()
f.close()
@@ -177,7 +182,7 @@ def read_json(self, fname, use_environment=False):
:return: dict or list
"""
try:
- data = self.read(fname)
+ data = self.read(fname, force_read=True)
except IOError, e:
if e[0] == 2:
return {}

0 comments on commit d5d8f55

Please sign in to comment.