Skip to content
This repository
Browse code

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...
commit d5d8f556b207a8a88997b9830a2597e09114408e 1 parent 3c03cbf
Benoit Chesneau authored June 24, 2009
28  src/couchapp/app.py
@@ -215,6 +215,7 @@ def push(self, dbstring, app_name, **kwargs):
215 215
                 self.send_attachments(db, design_doc)
216 216
             else:
217 217
                 self.encode_attachments(db, design_doc, new_doc)
  218
+                
218 219
                 db[docid] = new_doc
219 220
                 
220 221
             self.extensions.notify("post-push", self.ui, self, db=db)
@@ -360,6 +361,7 @@ def mycallbacl(app_dir, app_name, design_doc, verbose=verbose):
360 361
 
361 362
         if 'lists' in design_doc:
362 363
             package_shows(design_doc, design_doc['lists'], self.app_dir, objects, self.ui)
  364
+        
363 365
 
364 366
         if 'validate_doc_update' in design_doc:
365 367
             tmp_dict = dict(validate_doc_update=design_doc["validate_doc_update"])
@@ -369,6 +371,7 @@ def mycallbacl(app_dir, app_name, design_doc, verbose=verbose):
369 371
         if 'views' in design_doc:
370 372
             package_views(design_doc, design_doc["views"], self.app_dir, objects, self.ui)
371 373
             
  374
+       
372 375
             
373 376
         couchapp = design_doc.get('couchapp', {})
374 377
         couchapp.update({
@@ -376,8 +379,8 @@ def mycallbacl(app_dir, app_name, design_doc, verbose=verbose):
376 379
             'objects': objects
377 380
         })
378 381
         design_doc['couchapp'] = couchapp
379  
-     
380 382
         self.attachments(design_doc, attach_dir, docid)
  383
+        
381 384
         self.vendor_attachments(design_doc, docid)
382 385
         
383 386
         # what we do after retrieving design_doc from app_dir 
@@ -395,11 +398,9 @@ def dir_to_fields(self, current_dir='', depth=0,
395 398
         for name in self.ui.listdir(current_dir):
396 399
             current_path = self.ui.rjoin(current_dir, name)
397 400
             rel_path = current_path.split("%s/" % self.app_dir)[1]
398  
-            if name == '.couchapprc':
  401
+            if name.startswith("."):
399 402
                 continue
400  
-            elif name == ".couchapp_ignore":
401  
-                continue
402  
-            elif name.startswith('_'):
  403
+            elif depth == 0 and name.startswith('_'):
403 404
                 # files starting with "_" are always "special"
404 405
                 continue
405 406
             elif depth == 0 and (name == 'couchapp' or name == 'couchapp.json'):
@@ -440,7 +441,15 @@ def dir_to_fields(self, current_dir='', depth=0,
440 441
                 try:
441 442
                     content = self.ui.read(current_path)
442 443
                 except UnicodeDecodeError, e:
443  
-                    self.ui.logger.error(str(e))
  444
+                    self.ui.logger.error("%s isn't encoded in utf8" % current_path)
  445
+                    content = self.ui.read(current_path, utf8=False)
  446
+                    try:
  447
+                        content.encode('utf-8')
  448
+                    except UnicodeError, e:
  449
+                        self.ui.logger.error("plan B didn't work, %s is a binary" % current_path)
  450
+                        self.ui.logger.error("use plan C: encode to base64")   
  451
+                        content = "base64-encoded;%s" % base64.b64encode(content)
  452
+                        
444 453
                 if name.endswith('.json'):
445 454
                     try:
446 455
                         content = json.loads(content)
@@ -450,7 +459,7 @@ def dir_to_fields(self, current_dir='', depth=0,
450 459
                 
451 460
                 # remove extension
452 461
                 name, ext = os.path.splitext(name)
453  
-                if name in fields:
  462
+                if name in fields and ext in ('.txt'):
454 463
                     if self.ui.verbose >= 2:
455 464
                         self.ui.logger.error("%(name)s is already in properties. Can't add (%(name)s%(ext)s)" % {
456 465
                             "name": name, "ext": ext })
@@ -533,7 +542,7 @@ def designdoc_to_fs(self, db, design_doc):
533 542
         if manifest:
534 543
             for filename in manifest:
535 544
                 if self.ui.verbose >=2:
536  
-                    print "clone property: %s" % filename
  545
+                    self.ui.logger.info("clone property: %s" % filename)
537 546
                 file_path = self.ui.rjoin(self.app_dir, filename)
538 547
                 if filename.endswith('/'): 
539 548
                     if not self.ui.isdir(file_path):
@@ -563,6 +572,9 @@ def designdoc_to_fs(self, db, design_doc):
563 572
                             _ref = md5(to_bytestring(content)).hexdigest()
564 573
                             if objects and _ref in objects:
565 574
                                 content = objects[_ref]
  575
+                                
  576
+                        if content.startswith('base64-encoded;'):
  577
+                            content = base64.b64decode(content[15:])
566 578
 
567 579
                         if fname.endswith('.json'):
568 580
                             content = json.dumps(content)
2  src/couchapp/macros.py
@@ -37,7 +37,7 @@ def apply_lib(doc, funcs, app_dir, objs, ui):
37 37
                 raise MacroError("Error running !code or !json on function \"%s\": %s" % (k, e))
38 38
             if old_v != funcs[k]:
39 39
                 objs[md5(to_bytestring(funcs[k])).hexdigest()] = old_v
40  
-
  40
+           
41 41
 def run_code_macros(f_string, app_dir, ui):
42 42
    def rreq(mo):
43 43
        # just read the file and return it
23  src/couchapp/ui.py
@@ -130,18 +130,23 @@ def sign(self, fpath):
130 130
         :return: string, md5 hexdigest
131 131
         """
132 132
         if self.isfile(fpath):
133  
-            content = self.read(fpath)
  133
+            content = self.read(fpath, force_read=True)
134 134
             return md5(to_bytestring(content)).hexdigest()
135 135
         return ''
136 136
         
137  
-    def read(self, fname):
  137
+    def read(self, fname, utf8=True, force_read=False):
138 138
         """ read file content"""
139  
-        try:
140  
-            f = codecs.open(fname, 'rb', "utf-8")
141  
-            data = f.read()
142  
-            f.close()
143  
-        except:
144  
-            f = open(fname, 'rb')
  139
+        if utf8:
  140
+            try:
  141
+                f = codecs.open(fname, 'rb', "utf-8")
  142
+                data = f.read()
  143
+                f.close()
  144
+            except UnicodeError, e:
  145
+                if force_read:
  146
+                    return self.read(fname, utf8=False)
  147
+                raise
  148
+        else:
  149
+            f = open(fname, 'rn')
145 150
             data = f.read()
146 151
             f.close()
147 152
             
@@ -177,7 +182,7 @@ def read_json(self, fname, use_environment=False):
177 182
         :return: dict or list
178 183
         """
179 184
         try:
180  
-            data = self.read(fname)
  185
+            data = self.read(fname, force_read=True)
181 186
         except IOError, e:
182 187
             if e[0] == 2:
183 188
                 return {}

0 notes on commit d5d8f55

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