@@ -1,12 +1,12 @@
 # encoding: UTF-8
 # api: streamtuner2
 # title: Xiph.org
-# description: ICEcast radio directory. Now utilizes a cached JSON API.
+# description: ICEcast radios. Scans per JSON API, slow XML, or raw directory.
 # type: channel
 # url: http://dir.xiph.org/
-# version: 0.4
+# version: 0.5
 # category: radio
 # config: 
 #    { name: xiph_min_bitrate, value: 64, type: int, description: "Minimum bitrate; filter lesser quality streams.", category: filter }
 #    { name: xiph_source, value: cache, type: select, select: "cache=JSON cache srv|xml=Clunky XML blob|web=Forbidden fruits", description: "Source for station list extraction." }
 # priority: standard
@@ -15,25 +15,29 @@
 #   h61eQorGNBOTzbEt16ZrnR5Wq3mZD/3heziX//983znngyyov+eSbHEA5WKBhs4BKVy9gsqajqwiCwo0dA5IQX5u2s4moliMPPV1nCeDzxgNBFDHE2wsKMPzsGVefobjcnO7RMfeMuL341ZBrNEGRmPqqjdvsbbf
 #   w7irO4Oj+rdywNNNucmERsLUVndR8uYRU13PCew6hpgP8W02xMpIsik++qk5oweW6y3yob8WnXacZDKJWh1Cp4OtRUHsh19TUlUGViv09RGqKAenU5QnLKm+rK88LjgcUnxmr/h8iNO5XYJBRAQZ/qiVeptGWjty
 #   5cClDWLwugQRIRiU5UdPCoD6S89jhV6pks9WG6fuwtBtF5v72vC1v+B86SsM+jD56hjnyiM0lRrAbofeXjQJLdE/78jbXSU5166I6f5VeeDdKdq6GtlSd0QkVU+8XsQhlt9W6izbZ5aMKWgtp2WT/yUHd0xSYU7i
 #   dsPQ+1WMKIsJD08wEV2HGLeRyNMjawqRxhuKBfdgz1m7fI/4mVX+ZGxmgniOoJv+QZHGAMC7p60ZnHkC8HfzZmLTBCd9af9ccnqMc9HTdmFe4kLkJbH/4h0xVtcu+SP/C78AL6btab6woPcAAAAASUVORK5CYII=
 #
-# Xiph.org maintains the Ogg streaming standard and Vorbis
-# audio compression format, amongst others.  The ICEcast
-# server is an alternative to SHOUTcast.
+# Xiph.org maintains the Ogg streaming standard and Vorbis,
+# Opus, FLAC audio, and Theora video compression formats.
+# The ICEcast server is a modern alternative to SHOUTcast.
 #
 # It also provides a directory listing of known internet
 # radio stations, only a handful of them using Ogg though.
-# The category list is hardwired in this plugin.
+# The category list is hardwired in this plugin. And there
+# are three station fetching modes now:
 #
-# And there are three fetch-modes now:
-#  → "Cache" retrieves a refurbished JSON station list,
+#  → "JSON cache" retrieves a refurbished JSON station list,
 #    both sliceable genres and searchable.
-#  → "XML" fetches the olden YP.XML once, buffers it,
-#    and tries to uncover per-genre categories from it.
-#  → "HTML" extracts from the raw dir.xiph.org directory,
-#    where homepages and listener/max infos are available.
+#
+#  → "Clunky XML" fetches the olden YP.XML, which is really
+#    slow, then slices out genres. No search.
+#
+#  → "Forbidden Fruits" extracts from dir.xiph.org HTML pages,
+#    with homepages and listener/max infos available. Search
+#    is also possible.
+#
 
 
 from config import *
 from uikit import uikit
 import ahttp
@@ -176,20 +180,24 @@
   # uncover station homepages.
   #@use_rx
   def from_raw_html(self, cat, search=None, use_rx=False):
 
       # Build request URL
+      by_format = {t.lower(): t for t in self.categories[-1]}
       if search:
-          return []
-      elif cat in ("Ogg_Vorbis", "NSV", "WebM", "Opus"):
-          url = "http://dir.xiph.org/by_format/{}".format(cat)
+          url = "http://dir.xiph.org/search?search={}".format(search)
+          cat = "search"
+      elif by_format.get(cat):
+          url = "http://dir.xiph.org/by_format/{}".format(by_format[cat])
       elif cat:
           url = "http://dir.xiph.org/by_genre/{}".format(cat.title())
 
       # Collect all result pages
       html = ahttp.get(url)
       for i in range(1,4):
+          if html.find('page={}">{}</a></li>'.format(i, i+1)) < 0:
+              break
           self.status(i/5.1)
           html += ahttp.get(url, {"search": cat.title(), "page": i})
       try: html = html.encode("raw_unicode_escape").decode("utf-8")
       except: pass
 
@@ -207,11 +215,12 @@
           .*? Tags: (.*?) </div>
           .*? href="(/listen/\d+/listen.xspf)"
           .*? class="format"\s+title="([^"]+)"
           .*? /by_format/([^"]+)
       """, html, re.X|re.S)
-      
+      print ls
+            
       # Assemble
       for homepage, title, listeners, playing, tags, url, bits, fmt in ls:
           r.append(dict(
               genre = unhtml(tags),
               title = unhtml(title),
@@ -485,11 +494,12 @@
         [
             "punkrock",
             "oi"
         ],
         "darkwave",
-        "Ogg_Vorbis", "NSV", "WebM", "Opus",
+        "/FORMAT",
+        ["Ogg_Vorbis", "Ogg_Theora", "Opus", "NSV", "WebM"],
     ]
 
 
 
 # Helper functions for XML extraction mode