Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1076)

Side by Side Diff: gm/rebaseline_server/server.py

Issue 487853004: rebaseline_server: allow users to generate SKP diff patches on a shared instance (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: add TODOs for Stephan Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « gm/rebaseline_server/results.py ('k') | gm/rebaseline_server/static/constants.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 2
3 """ 3 """
4 Copyright 2013 Google Inc. 4 Copyright 2013 Google Inc.
5 5
6 Use of this source code is governed by a BSD-style license that can be 6 Use of this source code is governed by a BSD-style license that can be
7 found in the LICENSE file. 7 found in the LICENSE file.
8 8
9 HTTP server for our HTML rebaseline viewer. 9 HTTP server for our HTML rebaseline viewer.
10 """ 10 """
(...skipping 30 matching lines...) Expand all
41 # Server.results() property. See discussion at 41 # Server.results() property. See discussion at
42 # https://codereview.chromium.org/195943004/diff/1/gm/rebaseline_server/server.p y#newcode44 42 # https://codereview.chromium.org/195943004/diff/1/gm/rebaseline_server/server.p y#newcode44
43 # pylint: enable=C0301 43 # pylint: enable=C0301
44 import compare_configs 44 import compare_configs
45 import compare_rendered_pictures 45 import compare_rendered_pictures
46 import compare_to_expectations 46 import compare_to_expectations
47 import download_actuals 47 import download_actuals
48 import imagediffdb 48 import imagediffdb
49 import imagepairset 49 import imagepairset
50 import results as results_mod 50 import results as results_mod
51 import writable_expectations as writable_expectations_mod
52
51 53
52 PATHSPLIT_RE = re.compile('/([^/]+)/(.+)') 54 PATHSPLIT_RE = re.compile('/([^/]+)/(.+)')
53 55
54 # A simple dictionary of file name extensions to MIME types. The empty string 56 # A simple dictionary of file name extensions to MIME types. The empty string
55 # entry is used as the default when no extension was given or if the extension 57 # entry is used as the default when no extension was given or if the extension
56 # has no entry in this dictionary. 58 # has no entry in this dictionary.
57 MIME_TYPE_MAP = {'': 'application/octet-stream', 59 MIME_TYPE_MAP = {'': 'application/octet-stream',
58 'html': 'text/html', 60 'html': 'text/html',
59 'css': 'text/css', 61 'css': 'text/css',
60 'png': 'image/png', 62 'png': 'image/png',
61 'js': 'application/javascript', 63 'js': 'application/javascript',
62 'json': 'application/json' 64 'json': 'application/json'
63 } 65 }
64 66
65 # Keys that server.py uses to create the toplevel content header. 67 # Keys that server.py uses to create the toplevel content header.
66 # NOTE: Keep these in sync with static/constants.js 68 # NOTE: Keep these in sync with static/constants.js
67 KEY__EDITS__MODIFICATIONS = 'modifications' 69 KEY__EDITS__MODIFICATIONS = 'modifications'
68 KEY__EDITS__OLD_RESULTS_HASH = 'oldResultsHash' 70 KEY__EDITS__OLD_RESULTS_HASH = 'oldResultsHash'
69 KEY__EDITS__OLD_RESULTS_TYPE = 'oldResultsType' 71 KEY__EDITS__OLD_RESULTS_TYPE = 'oldResultsType'
72 KEY__LIVE_EDITS__MODIFICATIONS = 'modifications'
73 KEY__LIVE_EDITS__SET_A_DESCRIPTIONS = 'setA'
74 KEY__LIVE_EDITS__SET_B_DESCRIPTIONS = 'setB'
70 75
71 DEFAULT_ACTUALS_DIR = results_mod.DEFAULT_ACTUALS_DIR 76 DEFAULT_ACTUALS_DIR = results_mod.DEFAULT_ACTUALS_DIR
72 DEFAULT_GM_SUMMARIES_BUCKET = download_actuals.GM_SUMMARIES_BUCKET 77 DEFAULT_GM_SUMMARIES_BUCKET = download_actuals.GM_SUMMARIES_BUCKET
73 DEFAULT_JSON_FILENAME = download_actuals.DEFAULT_JSON_FILENAME 78 DEFAULT_JSON_FILENAME = download_actuals.DEFAULT_JSON_FILENAME
74 DEFAULT_PORT = 8888 79 DEFAULT_PORT = 8888
75 80
76 PARENT_DIRECTORY = os.path.dirname(os.path.realpath(__file__)) 81 PARENT_DIRECTORY = os.path.dirname(os.path.realpath(__file__))
77 TRUNK_DIRECTORY = os.path.dirname(os.path.dirname(PARENT_DIRECTORY)) 82 TRUNK_DIRECTORY = os.path.dirname(os.path.dirname(PARENT_DIRECTORY))
78 83
79 # Directory, relative to PARENT_DIRECTORY, within which the server will serve 84 # Directory, relative to PARENT_DIRECTORY, within which the server will serve
(...skipping 598 matching lines...) Expand 10 before | Expand all | Expand 10 after
678 def do_POST(self): 683 def do_POST(self):
679 """ Handles all POST requests, forwarding them to the appropriate 684 """ Handles all POST requests, forwarding them to the appropriate
680 do_POST_* dispatcher. """ 685 do_POST_* dispatcher. """
681 # All requests must be of this form: 686 # All requests must be of this form:
682 # /dispatcher 687 # /dispatcher
683 # where 'dispatcher' indicates which do_POST_* dispatcher to run. 688 # where 'dispatcher' indicates which do_POST_* dispatcher to run.
684 logging.debug('do_POST: path="%s"' % self.path) 689 logging.debug('do_POST: path="%s"' % self.path)
685 normpath = posixpath.normpath(self.path) 690 normpath = posixpath.normpath(self.path)
686 dispatchers = { 691 dispatchers = {
687 '/edits': self.do_POST_edits, 692 '/edits': self.do_POST_edits,
693 '/live-edits': self.do_POST_live_edits,
688 } 694 }
689 try: 695 try:
690 dispatcher = dispatchers[normpath] 696 dispatcher = dispatchers[normpath]
691 dispatcher() 697 dispatcher()
692 self.send_response(200)
693 except: 698 except:
694 self.send_error(404) 699 self.send_error(404)
695 raise 700 raise
696 701
697 def do_POST_edits(self): 702 def do_POST_edits(self):
698 """ Handle a POST request with modifications to GM expectations, in this 703 """ Handle a POST request with modifications to GM expectations, in this
699 format: 704 format:
700 705
701 { 706 {
702 KEY__EDITS__OLD_RESULTS_TYPE: 'all', # type of results that the client 707 KEY__EDITS__OLD_RESULTS_TYPE: 'all', # type of results that the client
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
742 raise Exception('results of type "%s" changed while the client was ' 747 raise Exception('results of type "%s" changed while the client was '
743 'making modifications. The client should reload the ' 748 'making modifications. The client should reload the '
744 'results and submit the modifications again.' % 749 'results and submit the modifications again.' %
745 oldResultsType) 750 oldResultsType)
746 _SERVER.results.edit_expectations(data[KEY__EDITS__MODIFICATIONS]) 751 _SERVER.results.edit_expectations(data[KEY__EDITS__MODIFICATIONS])
747 752
748 # Read the updated results back from disk. 753 # Read the updated results back from disk.
749 # We can do this in a separate thread; we should return our success message 754 # We can do this in a separate thread; we should return our success message
750 # to the UI as soon as possible. 755 # to the UI as soon as possible.
751 thread.start_new_thread(_SERVER.update_results, (True,)) 756 thread.start_new_thread(_SERVER.update_results, (True,))
757 self.send_response(200)
758
759 def do_POST_live_edits(self):
760 """ Handle a POST request with modifications to SKP expectations, in this
761 format:
762
763 {
764 KEY__LIVE_EDITS__SET_A_DESCRIPTIONS: {
765 # setA descriptions from the original data
766 },
767 KEY__LIVE_EDITS__SET_B_DESCRIPTIONS: {
768 # setB descriptions from the original data
769 },
770 KEY__LIVE_EDITS__MODIFICATIONS: [
771 # as needed by writable_expectations.modify()
772 ],
773 }
774
775 Raises an Exception if there were any problems.
776 """
777 content_type = self.headers[_HTTP_HEADER_CONTENT_TYPE]
778 if content_type != 'application/json;charset=UTF-8':
779 raise Exception('unsupported %s [%s]' % (
780 _HTTP_HEADER_CONTENT_TYPE, content_type))
781
782 content_length = int(self.headers[_HTTP_HEADER_CONTENT_LENGTH])
783 json_data = self.rfile.read(content_length)
784 data = json.loads(json_data)
785 logging.debug('do_POST_live_edits: received new GM expectations data [%s]' %
786 data)
787 with writable_expectations_mod.WritableExpectations(
788 data[KEY__LIVE_EDITS__SET_A_DESCRIPTIONS]) as writable_expectations:
789 writable_expectations.modify(data[KEY__LIVE_EDITS__MODIFICATIONS])
790 diffs = writable_expectations.get_diffs()
791 # TODO(stephana): Move to a simpler web framework so we don't have to
792 # call these functions. See http://skbug.com/2856 ('rebaseline_server:
793 # Refactor server to use a simple web framework')
794 self.send_response(200)
795 self.send_header('Content-type', 'text/plain')
796 self.end_headers()
797 self.wfile.write(diffs)
752 798
753 def redirect_to(self, url): 799 def redirect_to(self, url):
754 """ Redirect the HTTP client to a different url. 800 """ Redirect the HTTP client to a different url.
755 801
756 Args: 802 Args:
757 url: URL to redirect the HTTP client to 803 url: URL to redirect the HTTP client to
758 """ 804 """
759 self.send_response(301) 805 self.send_response(301)
760 self.send_header('Location', url) 806 self.send_header('Location', url)
761 self.end_headers() 807 self.end_headers()
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
898 reload_seconds=args.reload, config_pairs=config_pairs, 944 reload_seconds=args.reload, config_pairs=config_pairs,
899 builder_regex_list=args.builders, boto_file_path=args.boto, 945 builder_regex_list=args.builders, boto_file_path=args.boto,
900 imagediffdb_threads=args.threads) 946 imagediffdb_threads=args.threads)
901 if args.truncate: 947 if args.truncate:
902 _SERVER.truncate_results = True 948 _SERVER.truncate_results = True
903 _SERVER.run() 949 _SERVER.run()
904 950
905 951
906 if __name__ == '__main__': 952 if __name__ == '__main__':
907 main() 953 main()
OLDNEW
« no previous file with comments | « gm/rebaseline_server/results.py ('k') | gm/rebaseline_server/static/constants.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698