| OLD | NEW |
| (Empty) | |
| 1 # Copyright 2013 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 json |
| 6 |
| 7 import svn_constants |
| 8 from appengine_wrappers import GetAppVersion |
| 9 from object_store_creator import ObjectStoreCreator |
| 10 |
| 11 PATCH_BASEURL = '_patch/' |
| 12 PATCH_CHANNEL_NAME = 'trunk' |
| 13 CHROMIUM_REPO_BASEURLS = [ |
| 14 'https://src.chromium.org/svn/trunk/src/', |
| 15 'http://src.chromium.org/svn/trunk/src/', |
| 16 'svn://svn.chromium.org/chrome/trunk/src', |
| 17 'https://chromium.googlesource.com/chromium/src.git@master', |
| 18 'http://git.chromium.org/chromium/src.git@master', |
| 19 ] |
| 20 DOCS_PATHS = [ |
| 21 svn_constants.API_PATH, |
| 22 svn_constants.INTRO_PATH, |
| 23 svn_constants.ARTICLE_PATH, |
| 24 svn_constants.PUBLIC_TEMPLATE_PATH, |
| 25 svn_constants.PRIVATE_TEMPLATE_PATH, |
| 26 svn_constants.JSON_PATH, |
| 27 svn_constants.STATIC_PATH |
| 28 ] |
| 29 RIETVELD_ISSUE_JSON = 'api/%s' |
| 30 RIETVELD_PATCHSET_JSON = 'api/%s/%s' |
| 31 |
| 32 class RietveldUtility(object): |
| 33 def __init__(self, fetcher, object_store=None): |
| 34 self._fetcher = fetcher |
| 35 if object_store is None: |
| 36 object_store = (ObjectStoreCreator.SharedFactory(GetAppVersion()). |
| 37 Create(RietveldUtility).Create()) |
| 38 self._object_store = object_store |
| 39 |
| 40 def GetPatchsetFromIssue(self, issue): |
| 41 patchset = self._object_store.Get(issue).Get() |
| 42 if patchset is not None: |
| 43 return patchset |
| 44 |
| 45 try: |
| 46 issue_json = json.loads(self._fetcher.Fetch( |
| 47 RIETVELD_ISSUE_JSON % issue).content) |
| 48 except Exception as e: |
| 49 return None |
| 50 |
| 51 if issue_json.get('closed'): |
| 52 return None |
| 53 |
| 54 patchsets = issue_json.get('patchsets') |
| 55 if not isinstance(patchsets, list) or len(patchsets) == 0: |
| 56 return None |
| 57 |
| 58 if not issue_json.get('base_url') in CHROMIUM_REPO_BASEURLS: |
| 59 return None |
| 60 |
| 61 patchset = patchsets[-1] |
| 62 self._object_store.Set(issue, patchset) |
| 63 return patchset |
| 64 |
| 65 # (docs_files, changes) |
| 66 def GetPatchsetDetails(self, issue, patchset): |
| 67 key = '%s@%s' % (issue, patchset) |
| 68 details = self._object_store.Get(key).Get() |
| 69 if details is not None: |
| 70 return details |
| 71 |
| 72 try: |
| 73 patchset_json = json.loads(self._fetcher.Fetch( |
| 74 RIETVELD_PATCHSET_JSON % (issue, patchset)).content) |
| 75 except Exception as e: |
| 76 return ([], {}) |
| 77 |
| 78 files = patchset_json.get('files') |
| 79 if files is None or not isinstance(files, dict): |
| 80 return ([], {}) |
| 81 |
| 82 docs_files = [] |
| 83 changes = {} |
| 84 for f in files: |
| 85 f = f.split(svn_constants.EXTENSIONS_PATH + '/', 1)[1] |
| 86 if (f.startswith(svn_constants.DOCS_PATH) or |
| 87 f.startswith(svn_constants.API_PATH)): |
| 88 docs_files.append(f) |
| 89 for p in DOCS_PATHS: |
| 90 if not changes.get(p) and f.startswith(p): |
| 91 changes[p] = True |
| 92 if len(docs_files) == 0: |
| 93 return ([], {}) |
| 94 |
| 95 details = (docs_files, changes) |
| 96 self._object_store.Set(key, details) |
| 97 return details |
| 98 |
| 99 @staticmethod |
| 100 def SplitPatchFromPath(path): |
| 101 if path.startswith(PATCH_BASEURL): |
| 102 remaining_path = path.split(PATCH_BASEURL, 1)[1] |
| 103 if not '/' in remaining_path: |
| 104 return (None, None, None) |
| 105 issue, real_path = remaining_path.split('/', 1) |
| 106 if not issue.isdigit() or len(real_path) == 0: |
| 107 return (None, None, None) |
| 108 return (PATCH_CHANNEL_NAME, issue, real_path) |
| 109 else: |
| 110 return (None, None, None) |
| OLD | NEW |