WebKitTools/TestResultServer/handlers/testfilehandler.py
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     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 
       
    29 import logging
       
    30 import urllib
       
    31 
       
    32 from google.appengine.api import users
       
    33 from google.appengine.ext import blobstore
       
    34 from google.appengine.ext import webapp
       
    35 from google.appengine.ext.webapp import blobstore_handlers
       
    36 from google.appengine.ext.webapp import template
       
    37 
       
    38 from model.testfile import TestFile
       
    39 
       
    40 PARAM_BUILDER = "builder"
       
    41 PARAM_DIR = "dir"
       
    42 PARAM_FILE = "file"
       
    43 PARAM_NAME = "name"
       
    44 PARAM_KEY = "key"
       
    45 PARAM_TEST_TYPE = "testtype"
       
    46 
       
    47 
       
    48 class DeleteFile(webapp.RequestHandler):
       
    49     """Delete test file for a given builder and name from datastore (metadata) and blobstore (file data)."""
       
    50 
       
    51     def get(self):
       
    52         key = self.request.get(PARAM_KEY)
       
    53         builder = self.request.get(PARAM_BUILDER)
       
    54         test_type = self.request.get(PARAM_TEST_TYPE)
       
    55         name = self.request.get(PARAM_NAME)
       
    56 
       
    57         logging.debug(
       
    58             "Deleting File, builder: %s, test_type: %s, name: %s, blob key: %s.",
       
    59             builder, test_type, name, key)
       
    60 
       
    61         TestFile.delete_file(key, builder, test_type, name, 100)
       
    62 
       
    63         # Display file list after deleting the file.
       
    64         self.redirect("/testfile?builder=%s&testtype=%s&name=%s"
       
    65             % (builder, test_type, name))
       
    66 
       
    67 
       
    68 class GetFile(blobstore_handlers.BlobstoreDownloadHandler):
       
    69     """Get file content or list of files for given builder and name."""
       
    70 
       
    71     def _get_file_list(self, builder, test_type, name):
       
    72         """Get and display a list of files that matches builder and file name.
       
    73 
       
    74         Args:
       
    75             builder: builder name
       
    76             test_type: type of the test
       
    77             name: file name
       
    78         """
       
    79 
       
    80         files = TestFile.get_files(builder, test_type, name, 100)
       
    81         if not files:
       
    82             logging.info("File not found, builder: %s, test_type: %s, name: %s.",
       
    83                          builder, test_type, name)
       
    84             self.response.out.write("File not found")
       
    85             return
       
    86 
       
    87         template_values = {
       
    88             "admin": users.is_current_user_admin(),
       
    89             "builder": builder,
       
    90             "test_type": test_type,
       
    91             "name": name,
       
    92             "files": files,
       
    93         }
       
    94         self.response.out.write(template.render("templates/showfilelist.html",
       
    95                                                 template_values))
       
    96 
       
    97     def _get_file_content(self, builder, test_type, name):
       
    98         """Return content of the file that matches builder and file name.
       
    99 
       
   100         Args:
       
   101             builder: builder name
       
   102             test_type: type of the test
       
   103             name: file name
       
   104         """
       
   105 
       
   106         files = TestFile.get_files(builder, test_type, name, 1)
       
   107         if not files:
       
   108             logging.info("File not found, builder: %s, test_type: %s, name: %s.",
       
   109                          builder, test_type, name)
       
   110             return
       
   111 
       
   112         blob_key = files[0].blob_key
       
   113         blob_info = blobstore.get(blob_key)
       
   114         if blob_info:
       
   115             self.send_blob(blob_info, "text/plain")
       
   116 
       
   117     def get(self):
       
   118         builder = self.request.get(PARAM_BUILDER)
       
   119         test_type = self.request.get(PARAM_TEST_TYPE)
       
   120         name = self.request.get(PARAM_NAME)
       
   121         dir = self.request.get(PARAM_DIR)
       
   122 
       
   123         logging.debug(
       
   124             "Getting files, builder: %s, test_type: %s, name: %s.",
       
   125             builder, test_type, name)
       
   126 
       
   127         # If parameter "dir" is specified or there is no builder or filename
       
   128         # specified in the request, return list of files, otherwise, return
       
   129         # file content.
       
   130         if dir or not builder or not name:
       
   131             return self._get_file_list(builder, test_type, name)
       
   132         else:
       
   133             return self._get_file_content(builder, test_type, name)
       
   134 
       
   135 
       
   136 class GetUploadUrl(webapp.RequestHandler):
       
   137     """Get an url for uploading file to blobstore. A special url is required for each blobsotre upload."""
       
   138 
       
   139     def get(self):
       
   140         upload_url = blobstore.create_upload_url("/testfile/upload")
       
   141         logging.info("Getting upload url: %s.", upload_url)
       
   142         self.response.out.write(upload_url)
       
   143 
       
   144 
       
   145 class Upload(blobstore_handlers.BlobstoreUploadHandler):
       
   146     """Upload file to blobstore."""
       
   147 
       
   148     def post(self):
       
   149         uploaded_files = self.get_uploads("file")
       
   150         if not uploaded_files:
       
   151             return self._upload_done([("Missing upload file field.")])
       
   152 
       
   153         builder = self.request.get(PARAM_BUILDER)
       
   154         if not builder:
       
   155             for blob_info in uploaded_files:
       
   156                 blob_info.delete()
       
   157     
       
   158             return self._upload_done([("Missing builder parameter in upload request.")])
       
   159 
       
   160         test_type = self.request.get(PARAM_TEST_TYPE)
       
   161 
       
   162         logging.debug(
       
   163             "Processing upload request, builder: %s, test_type: %s.",
       
   164             builder, test_type)
       
   165 
       
   166         errors = []
       
   167         for blob_info in uploaded_files:
       
   168             tf = TestFile.update_file(builder, test_type, blob_info)
       
   169             if not tf:
       
   170                 errors.append(
       
   171                     "Upload failed, builder: %s, test_type: %s, name: %s." %
       
   172                     (builder, test_type, blob_info.filename))
       
   173                 blob_info.delete()
       
   174 
       
   175         return self._upload_done(errors)
       
   176 
       
   177     def _upload_done(self, errors):
       
   178         logging.info("upload done.")
       
   179 
       
   180         error_messages = []
       
   181         for error in errors:
       
   182             logging.info(error)
       
   183             error_messages.append("error=%s" % urllib.quote(error))
       
   184 
       
   185         if error_messages:
       
   186             redirect_url = "/uploadfail?%s" % "&".join(error_messages)
       
   187         else:
       
   188             redirect_url = "/uploadsuccess"
       
   189 
       
   190         logging.info(redirect_url)
       
   191         # BlobstoreUploadHandler requires redirect at the end.
       
   192         self.redirect(redirect_url)
       
   193 
       
   194 
       
   195 class UploadForm(webapp.RequestHandler):
       
   196     """Show a form so user can submit a file to blobstore."""
       
   197 
       
   198     def get(self):
       
   199         upload_url = blobstore.create_upload_url("/testfile/upload")
       
   200         template_values = {
       
   201             "upload_url": upload_url,
       
   202         }
       
   203         self.response.out.write(template.render("templates/uploadform.html",
       
   204                                                 template_values))
       
   205 
       
   206 class UploadStatus(webapp.RequestHandler):
       
   207     """Return status of file uploading"""
       
   208 
       
   209     def get(self):
       
   210         logging.debug("Update status")
       
   211 
       
   212         if self.request.path == "/uploadsuccess":
       
   213             self.response.set_status(200)
       
   214             self.response.out.write("OK")
       
   215         else:
       
   216             errors = self.request.params.getall("error")
       
   217             if errors:
       
   218                 messages = "FAIL: " + "; ".join(errors)
       
   219                 logging.warning(messages)
       
   220                 self.response.set_status(500, messages)
       
   221                 self.response.out.write("FAIL")