Handler to return the latest snapshot

Change-Id: I1770d0976c39905958637fbc88c389c1d1503120
diff --git a/fudash/main.py b/fudash/main.py
index b3af22f..f19d501 100644
--- a/fudash/main.py
+++ b/fudash/main.py
@@ -19,6 +19,7 @@
     autoescape=True)
 
 BASE_URL = 'https://luci-scheduler.appspot.com/jobs/'
+SNAPSHOT_URL = 'https://storage.googleapis.com/fuchsia/jiri/snapshots'
 
 TARGETS = {
     'fuchsia': [
@@ -45,6 +46,7 @@
     ]
 }
 
+
 class BuildResult:
     """This is an enum of sorts, except the values match css class names."""
     Pass = "pass"
@@ -52,12 +54,15 @@
     ServerError = "server_error"
     ParserError = "parser_error"
 
+
 class LuciResultParser(HTMLParser):
     """Parses the HTML of the LUCI scheduler page to get the build results."""
 
-    def __init__(self):
+    def __init__(self, success_only=False):
         HTMLParser.__init__(self)
+        self.success_only = success_only
         self.parsing_invocations = False
+        self.parsing_row = False
         self.stop_parsing = False
         self.result = BuildResult.ParserError
 
@@ -69,29 +74,68 @@
                     self.parsing_invocations = True
         elif tag == 'tr' and self.parsing_invocations:
             for k, v in attrs:
-                if k == 'class' and v == 'danger':
+                if k == 'class' and v == 'danger' and not self.success_only:
                     self.result = BuildResult.Fail
-                    self.stop_parsing = True
+                    self.parsing_invocations = False
+                    self.parsing_row = True
                 if k == 'class' and v == 'success':
                     self.result = BuildResult.Pass
+                    self.parsing_invocations = False
+                    self.parsing_row = True
+        elif tag == 'a' and self.parsing_row:
+            for k, v in attrs:
+                if k == 'href':
+                    self.link = v
+                if k == 'class' and 'label' in v:
                     self.stop_parsing = True
 
+
+def getBuildResult(target, success_only=False):
+    try:
+        resp = urlfetch.fetch(BASE_URL + target, deadline=5)
+        if resp.status_code != 200:
+            return BuildResult.ServerError, '#'
+        parser = LuciResultParser(success_only)
+        parser.feed(resp.content)
+        parser.close()
+        return parser.result, parser.link
+    except:
+        return BuildResult.ServerError, '#'
+
+
+class MiloResultParser(HTMLParser):
+    """Parses the HTML of the Milo steps to get the snapshot link."""
+
+    def __init__(self):
+        HTMLParser.__init__(self)
+        self.stop_parsing = False
+        self.link = None
+
+    def handle_starttag(self, tag, attrs):
+        if self.stop_parsing: return
+        if tag == 'a':
+            for k, v in attrs:
+                if k == 'href' and v.startswith(SNAPSHOT_URL):
+                    self.link = v
+                    self.stop_parsing= True
+
+
+def getSnapshot(href):
+    try:
+        resp = urlfetch.fetch(href, deadline=5)
+        if resp.status_code != 200:
+            return BuildResult.ServerError
+        parser = MiloResultParser()
+        parser.feed(resp.content)
+        parser.close()
+        return parser.link
+    except:
+        return BuildResult.ServerError
+
+
 class MainPage(webapp2.RequestHandler):
     """The main handler."""
 
-    @staticmethod
-    def getBuildResult(target):
-        try:
-            resp = urlfetch.fetch(BASE_URL + target, deadline=5)
-            if resp.status_code != 200:
-                return BuildResult.ServerError
-            parser = LuciResultParser()
-            parser.feed(resp.content)
-            parser.close()
-            return parser.result
-        except:
-            return BuildResult.ServerError
-
     def get(self):
         template_values = {
             'clock': time.strftime("%H:%M UTC", time.gmtime()),
@@ -102,10 +146,11 @@
             for job in TARGETS[t]:
                 url_suffix = job[0]
                 display_name = job[1]
+                result, link = getBuildResult(url_suffix)
                 result = {
                     'name': display_name,
-                    'result': MainPage.getBuildResult(url_suffix),
-                    'href': BASE_URL + url_suffix,
+                    'result': result,
+                    'href': link,
                 }
                 build_jobs.append(result)
             target = {
@@ -118,6 +163,22 @@
         self.response.write(template.render(template_values))
 
 
+class SnapshotPage(webapp2.RequestHandler):
+    """The snapshot handler."""
+
+    def get(self, target):
+        snapshot_found = False
+        for t in sorted(TARGETS):
+            for j in TARGETS[t]:
+                if target == j[1]:
+                    result, link = getBuildResult(j[0], True)
+                    self.redirect(getSnapshot(link))
+                    snapshot_found = True
+        if not snapshot_found:
+            self.abort(404)
+
+
 app = webapp2.WSGIApplication([
         ('/', MainPage),
+        (r'/lkgs/([a-z0-9-_]+)', SnapshotPage),
 ], debug=True)