OLD | NEW |
| (Empty) |
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 # Use of this source code is governed by a BSD-style license that can be | |
3 # found in the LICENSE file. | |
4 | |
5 import cgi | |
6 import csv | |
7 import logging | |
8 import os | |
9 import re | |
10 import StringIO | |
11 | |
12 from google.appengine.ext import webapp | |
13 from google.appengine.ext.webapp import template | |
14 from google.appengine.api import memcache | |
15 from google.appengine.api import urlfetch | |
16 | |
17 class Issue(object): | |
18 def __init__(self, id, title): | |
19 self.id = id | |
20 self.title = title | |
21 | |
22 KNOWN_ISSUES_CSV_URL = \ | |
23 'http://code.google.com/p/chromium/issues/csv?can=1&' \ | |
24 'q=Hotlist%3DKnownIssue%20Feature%3DApps' | |
25 KNOWN_ISSUES_CACHE_KEY = 'known-issues' | |
26 KNOWN_ISSUES_CACHE_TIME = 300 # seconds | |
27 | |
28 class Handler(webapp.RequestHandler): | |
29 def get(self): | |
30 open_issues, closed_issues = self.getKnownIssues() | |
31 | |
32 template_path = os.path.join( | |
33 os.path.dirname(__file__), 'app_known_issues_template.html') | |
34 self.response.out.write(template.render(template_path, { | |
35 'open_issues': open_issues, | |
36 'closed_issues': closed_issues, | |
37 })) | |
38 self.response.headers.add_header('Content-Type', 'text/html') | |
39 self.response.headers.add_header('Access-Control-Allow-Origin', '*') | |
40 | |
41 def getKnownIssues(self): | |
42 cached_result = memcache.get(KNOWN_ISSUES_CACHE_KEY) | |
43 if cached_result: return cached_result | |
44 | |
45 logging.info('re-fetching known issues') | |
46 | |
47 open_issues = [] | |
48 closed_issues = [] | |
49 | |
50 response = urlfetch.fetch(KNOWN_ISSUES_CSV_URL, deadline=10) | |
51 | |
52 if response.status_code != 200: | |
53 return [], [] | |
54 | |
55 issues_reader = csv.DictReader(StringIO.StringIO(response.content)) | |
56 | |
57 for issue_dict in issues_reader: | |
58 is_fixed = issue_dict.get('Status', '') == 'Fixed' | |
59 id = issue_dict.get('ID', '') | |
60 title = issue_dict.get('Summary', '') | |
61 | |
62 if not id or not title: | |
63 continue | |
64 | |
65 issue = Issue(id, title) | |
66 if is_fixed: | |
67 closed_issues.append(issue) | |
68 else: | |
69 open_issues.append(issue) | |
70 | |
71 open_issues.sort(key=lambda issue:issue.title) | |
72 closed_issues.sort(key=lambda issue:issue.title) | |
73 | |
74 result = (open_issues, closed_issues) | |
75 memcache.add(KNOWN_ISSUES_CACHE_KEY, result, KNOWN_ISSUES_CACHE_TIME) | |
76 return result | |
OLD | NEW |