Martin Thorsen Ranang avatar Martin Thorsen Ranang committed 7ce9521

Updated best_match() by rewriting it to use the best match weighting from mimeparse 0.1.3. The corresponding change in 0.1.3 was commented with 'respect order of supported in the event of a tie' [mimeparse r17]. Also updated unit tests to adhere with mimeparse 0.1.3 ouput.

Comments (0)

Files changed (2)

paste/util/mimeparse.py

 
    http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1
 
-Based on mimeparse 0.1.2 by Joe Gregorio:
+Based on mimeparse 0.1.2 (and best_match() from 0.1.3) by Joe Gregorio:
 
     http://code.google.com/p/mimeparse/
 
     """
     if not supported:
         return ''
-    parsed_header = map(parse_media_range, header.split(','))
-    best_type = max([
-            (fitness_and_quality_parsed(mime_type, parsed_header), -n)
-            for n, mime_type in enumerate(supported)])
-    return best_type[0][1] and supported[-best_type[1]] or ''
+
+    split_header = _filter_blank(header.split(','))
+    parsed_header = [parse_media_range(r) for r in split_header]
+    weighted_matches = []
+    pos = 0
+    for mime_type in supported:
+        weighted_matches.append((fitness_and_quality_parsed(mime_type,
+                                 parsed_header), pos, mime_type))
+        pos += 1
+    weighted_matches.sort()
+
+    return weighted_matches[-1][0][1] and weighted_matches[-1][2] or ''
+
+def _filter_blank(i):
+    for s in i:
+        if s.strip():
+            yield s
 
 def desired_matches(desired, header):
     """Takes a list of desired mime-types in the order the server prefers to

tests/test_util/test_mimeparse.py

     assert bm(['application/xbel+xml', 'text/xml'],
         'text/*;q=0.5,*/*; q=0.1') == 'text/xml'
     assert bm(['application/xbel+xml', 'audio/mp3'],
-        'text/*;q=0.5,*/*; q=0.1') == 'application/xbel+xml'
+        'text/*;q=0.5,*/*; q=0.1') == 'audio/mp3'
     assert bm(['application/xbel+xml', 'audio/mp3'],
         'text/*;q=0.5,*/mp3; q=0.1') == 'audio/mp3'
     assert bm(['application/xbel+xml', 'text/plain', 'text/html'],
-        'text/*;q=0.5,*/plain; q=0.1') == 'text/plain'
+        'text/*;q=0.5,*/plain; q=0.1') == 'text/html'
     assert bm(['application/xbel+xml', 'text/html', 'text/xhtml'],
-        'text/*;q=0.1,*/xhtml; q=0.5') == 'text/html'
+        'text/*;q=0.1,*/xhtml; q=0.5') == 'text/xhtml'
     assert bm(['application/xbel+xml', 'text/html', 'text/xhtml'],
         '*/html;q=0.1,*/xhtml; q=0.5') == 'text/xhtml'
     assert bm(['application/xbel+xml', 'application/xml'],
     assert bm(['application/xbel+xml', 'application/xml'],
         'application/xml; q=1') == 'application/xml'
     assert bm(['application/xbel+xml', 'application/xml'],
-        'application/*; q=1') == 'application/xbel+xml'
+        'application/*; q=1') == 'application/xml'
     assert bm(['application/xbel+xml', 'application/xml'],
         '*/*, application/xml') == 'application/xml'
     assert bm(['application/xbel+xml', 'text/xml'],
         'application/json, text/html;q=0.9') == 'application/json'
     assert bm(['image/*', 'application/xml'], 'image/png') == 'image/*'
     assert bm(['image/*', 'application/xml'], 'image/*') == 'image/*'
-
+    assert bm(['application/json', 'text/html'],
+              'application/x-ms-application, image/jpeg, '
+              'application/xaml+xml, image/gif, image/pjpeg, '
+              'application/x-ms-xbap, */*') == 'text/html'
+    
 def test_illformed_best_match():
     bm = best_match
     assert bm(['image/png', 'image/jpeg', 'image/gif', 'text/html'],
-        'text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2') == 'image/jpeg'
+        'text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2') == 'text/html'
     assert bm(['image/png', 'image/jpg', 'image/tif', 'text/html'],
         'text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2') == 'text/html'
     assert bm(['image/png', 'image/jpg', 'image/tif', 'audio/mp3'],
-        'text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2') == 'image/png'
+        'text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2') == 'audio/mp3'
 
 def test_sorted_match():
     dm = desired_matches
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.