<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -81,7 +81,7 @@ class S3Page(base.BasePage):
 			
 			# Get handler for format
 		if format == 'rss': handler = RSSResponse(self)
-		elif format == 'xspf': handler = tape.XSPFResponse(self)
+		elif format.startswith('xspf'): handler = tape.XSPFResponse(self)
 		elif format == 'tape': handler = tape.TapeResponse(self)
 		elif format == 'json': handler = JSONResponse(self)
 		elif format == 'error': handler = ErrorResponse(self)</diff>
      <filename>app/controllers/s3.py</filename>
    </modified>
    <modified>
      <diff>@@ -10,58 +10,58 @@ from app.controllers.base import BaseResponse, JSONResponse
 
 class TapeResponse(BaseResponse):
 
-	def __init__(self, request_handler):
-		self.request_handler = request_handler
-		
 	def handle(self, s3response):
 	
 		list_url = self.request_handler.request.path_url
-		xspf_url = '%s?format=xspf' % list_url
-		
-		tracks = []
-		id3_urls = []
-		for file in s3response.files:
-			if file.extension == 'mp3':
-				tracks.append(file.xspf_track)
-				id3_urls.append('%s?format=id3-json' % file.appspot_url)
-				
+		xspf_url = '%s?format=xspfm' % list_url
+
+		tracks = [file.xspf_track for file in s3response.files if file.extension == 'mp3']
+		id3_urls = ['%s?format=id3-json' % file.appspot_url for file in s3response.files if file.extension == 'mp3']
+
 		values = dict(title='Mix Tape (%s)' % s3response.path, xspf_url=xspf_url, list_url=list_url, tracks=tracks, id3_urls=id3_urls, s3response=s3response)
-		
+
 		self.render(&quot;muxtape.mako&quot;, values)
-		
-		
+
+
 class XSPFResponse(BaseResponse):
 
 	def handle(self, s3response):
 		url = s3response.url
 		files = s3response.files
 		path = s3response.path
-		
+
+		exts = self.request.get('exts', None)
+		extensions = None
+		if exts:
+			extensions = exts.split(',')
+
+		# Special case for muxtape; Not sure why player can't handle larger param values.
+		if self.request.get('format', '') == 'xspfm':
+			extensions = ['mp3']
+
 		files.sort(cmp=lambda x, y: shrub.utils.file_comparator(x, y, 'name', True))
-		
-		tracks = []
-		
-		for file in files:
-			tracks.append(file.xspf_track)
-			
+
+		tracks = [file.xspf_track for file in files if not extensions or file.extension in extensions]
+		logging.info(&quot;Tracks: %s&quot; % ([str(track) for track in tracks]))
+
 		values = dict(title=path, creator='Shrub', info='http://shrub.appspot.com', location=url, tracks=tracks)
-		
+
 		self.render(&quot;xspf.mako&quot;, values, 'text/xml; charset=utf-8')
-		
-		
+
+
 class ID3Response(JSONResponse):
 
 	def load_url(self, url, format='json', cache_key=None):
-	
+
 		if self.render_json_from_cache(cache_key):
 			return
-			
+
 		callback = self.request.get(&quot;callback&quot;, None)
 		
 		logging.info(&quot;Loading url: %s&quot; % url)
 		fetch_headers = dict(Range='bytes=0-1024')
 		response = urlfetch.fetch(url, headers=fetch_headers, allow_truncated=True)
-		
+
 		try:
 			data = id3data.ID3Data(response.content)
 			id3r = id3reader.Reader(data, only_v2=True)
@@ -70,18 +70,18 @@ class ID3Response(JSONResponse):
 				self.render_json(dict(error='Not found'))
 				return
 				
-			values = dict(album=id3r.getValue('album'),
-			performer=id3r.getValue('performer'),
-			title=id3r.getValue('title'),
-			track=id3r.getValue('track'),
-			year=id3r.getValue('year'),
-			isTruncated=id3r.is_truncated,
+			values = dict(
+				album=id3r.getValue('album'),
+				performer=id3r.getValue('performer'),
+				title=id3r.getValue('title'),
+				track=id3r.getValue('track'),
+				year=id3r.getValue('year'),
+				isTruncated=id3r.is_truncated,
 			)
-			
+
 			if format == 'json':
 				self.render_json(values, cache_key=cache_key, callback=callback)
-				
+
 		except id3reader.Id3Error, detail:
 			self.render_json(dict(error=str(detail)))
-			
 </diff>
      <filename>app/controllers/tape.py</filename>
    </modified>
    <modified>
      <diff>@@ -8,4 +8,4 @@ def to_json(context, value):
 	return simplejson.dumps(value)
 
 def shrub_version(context):
-	return &quot;1.2.8&quot;
\ No newline at end of file
+	return &quot;1.2.9&quot;
\ No newline at end of file</diff>
      <filename>app/helpers/base.py</filename>
    </modified>
    <modified>
      <diff>@@ -148,6 +148,20 @@ myCallback({&quot;maxKeys&quot;: &quot;1000&quot;, &quot;prefix&quot;: &quot;&quot;, ...})
           For example, &lt;a href=&quot;/m1xes/sub-pop-mix-1/?format=xspf&quot;&gt;http://shrub.appspot.com/m1xes/sub-pop-mix-1/?format=xspf&lt;/a&gt;
           &lt;/p&gt;
           &lt;br/&gt;
+          &lt;h3&gt;URL parameters&lt;/h3&gt;
+          
+          &lt;table class=&quot;tabular&quot;&gt;
+            &lt;thead&gt;
+              &lt;tr&gt;&lt;th&gt;Parameter&lt;/th&gt; &lt;th&gt;Description&lt;/th&gt;&lt;/tr&gt;
+            &lt;tbody&gt;
+            &lt;tr&gt;
+              &lt;td&gt;exts&lt;/td&gt;
+              &lt;td&gt;List of extensions to filter (comma-delimited). For example, exts=mp3,foo,bar
+              &lt;/td&gt;
+            &lt;/tr&gt;
+            &lt;/tbody&gt;
+          &lt;/table&gt;
+          &lt;br/&gt;
           &lt;br/&gt;
           
 &lt;pre style=&quot;overflow:auto; width=380px&quot;&gt;</diff>
      <filename>app/views/index.mako</filename>
    </modified>
    <modified>
      <diff>@@ -268,6 +268,7 @@ var shrubTape = (function() {
     },  	    
     
     onMetaChange: function(track, time) {
+      if (isNaN(time)) return;
       var node = $(&quot;#song-&quot; + track + &quot; .song-duration&quot;);
       node.html(time);
       if (time == &quot;0:00&quot;) node.addClass(&quot;unknown&quot;);
@@ -275,6 +276,7 @@ var shrubTape = (function() {
     },
     
     onLoadedChange: function(track, percentage) {
+      if (isNaN(percentage)) return;
       var node = $(&quot;#song-&quot; + track + &quot; .song-loaded&quot;);
       node.html(percentage + &quot;%&quot;)
       if (percentage &gt; 0) node.removeClass(&quot;unknown&quot;);</diff>
      <filename>public/javascripts/shrub.js</filename>
    </modified>
    <modified>
      <diff>@@ -7,4 +7,7 @@ class Track:
 		self.meta = meta
 		self.title = title
 		self.info = info
+		
+	def __str__(self):
+		return 'location=%s,meta=%s,title=%s,info=%s' % (self.location, self.meta, self.title, self.info)
 </diff>
      <filename>shrub/feeds/xspf.py</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>dd4f7926f1cb9eda5fd4a41998c9b2acb87e69f0</id>
    </parent>
  </parents>
  <author>
    <name>Gabriel Handford</name>
    <email>gabrielh@gmail.com</email>
  </author>
  <url>http://github.com/gabriel/shrub/commit/2612eb778869ef53dbce5437f71018c4ca27f473</url>
  <id>2612eb778869ef53dbce5437f71018c4ca27f473</id>
  <committed-date>2009-03-02T22:56:18-08:00</committed-date>
  <authored-date>2009-03-02T22:56:18-08:00</authored-date>
  <message>Fixing tape bug when other files are present</message>
  <tree>09140e19f2637a831458c517715f328787ed0853</tree>
  <committer>
    <name>Gabriel Handford</name>
    <email>gabrielh@gmail.com</email>
  </committer>
</commit>
