1# Copyright (C) 2010 Google Inc. All rights reserved. 2# 3# Redistribution and use in source and binary forms, with or without 4# modification, are permitted provided that the following conditions are 5# met: 6# 7# * Redistributions of source code must retain the above copyright 8# notice, this list of conditions and the following disclaimer. 9# * Redistributions in binary form must reproduce the above 10# copyright notice, this list of conditions and the following disclaimer 11# in the documentation and/or other materials provided with the 12# distribution. 13# * Neither the name of Google Inc. nor the names of its 14# contributors may be used to endorse or promote products derived from 15# this software without specific prior written permission. 16# 17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29from datetime import datetime 30import logging 31import urllib 32import urllib2 33 34from google.appengine.ext import db 35 36SVN_PATH_DASHBOARD = ("http://src.chromium.org/viewvc/chrome/trunk/tools/" 37 "dashboards/") 38 39 40class DashboardFile(db.Model): 41 name = db.StringProperty() 42 data = db.BlobProperty() 43 date = db.DateTimeProperty(auto_now_add=True) 44 45 @classmethod 46 def get_files(cls, name, limit=1): 47 query = DashboardFile.all() 48 if name: 49 query = query.filter("name =", name) 50 return query.order("-date").fetch(limit) 51 52 @classmethod 53 def add_file(cls, name, data): 54 file = DashboardFile() 55 file.name = name 56 file.data = db.Blob(data) 57 file.put() 58 59 logging.debug("Dashboard file saved, name: %s.", name) 60 61 return file 62 63 @classmethod 64 def grab_file_from_svn(cls, name): 65 logging.debug("Grab file from SVN, name: %s.", name) 66 67 url = SVN_PATH_DASHBOARD + urllib.quote_plus(name) 68 69 logging.info("Grab file from SVN, url: %s.", url) 70 try: 71 file = urllib2.urlopen(url) 72 if not file: 73 logging.error("Failed to grab dashboard file: %s.", url) 74 return None 75 76 return file.read() 77 except urllib2.HTTPError, e: 78 logging.error("Failed to grab dashboard file: %s", str(e)) 79 except urllib2.URLError, e: 80 logging.error("Failed to grab dashboard file: %s", str(e)) 81 82 return None 83 84 @classmethod 85 def update_file(cls, name): 86 data = cls.grab_file_from_svn(name) 87 if not data: 88 return False 89 90 logging.info("Got file from SVN.") 91 92 files = cls.get_files(name) 93 if not files: 94 logging.info("No existing file, added as new file.") 95 if cls.add_file(name, data): 96 return True 97 return False 98 99 logging.debug("Updating existing file.") 100 file = files[0] 101 file.data = data 102 file.date = datetime.now() 103 file.put() 104 105 logging.info("Dashboard file replaced, name: %s.", name) 106 107 return True 108 109 @classmethod 110 def delete_file(cls, name): 111 files = cls.get_files(name) 112 if not files: 113 logging.warning("File not found, name: %s.", name) 114 return False 115 116 for file in files: 117 file.delete() 118 119 return True 120