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