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

Side by Side Diff: gstools.py

Issue 12042069: Scripts to download files from google storage based on sha1 sums (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: Review fixes Created 7 years, 9 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
OLDNEW
(Empty)
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
M-A Ruel 2013/03/03 02:13:14 Do you mind putting the content of this file in on
Ryan Tseng 2013/03/04 21:43:54 Moved
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 """Utility functions common to the Google storage scripts."""
6
7 import hashlib
8 import os
9 import re
10 import sys
11
12 import subprocess2
13
14
15 class Gsutil(object):
16 """Call gsutil with some predefined settings."""
17 def __init__(self, path, boto_path=None, timeout=None):
18 if not os.path.exists(path):
19 raise OSError('GSUtil not found in %s' % path)
20 self.path = path
21 self.timeout = timeout
22 self.boto_path = boto_path
23
24 def call(self, *args):
25 env = os.environ.copy()
26 if self.boto_path is not None:
27 env['AWS_CREDENTIAL_FILE'] = self.boto_path
28 return subprocess2.call((sys.executable, self.path) + args,
29 env=env,
30 timeout=self.timeout)
31
32 def check_call(self, *args):
33 env = os.environ.copy()
34 if self.boto_path is not None:
35 env['AWS_CREDENTIAL_FILE'] = self.boto_path
36 ((out, err), code) = subprocess2.communicate(
37 (sys.executable, self.path) + args,
38 stdout=subprocess2.PIPE,
39 stderr=subprocess2.PIPE,
40 env=env,
41 timeout=self.timeout)
42
43 # Parse output.
44 status_code_match = re.search('status=([0-9]+)', err)
45 if status_code_match:
46 return int(status_code_match.groups(1))
47 elif ('You are attempting to access protected data with '
48 'no configured credentials.' in err):
49 return (403, out, err)
50 elif 'No such object' in err:
51 return (404, out, err)
52 else:
53 return (code, out, err)
54
55 def clone(self):
56 return Gsutil(self.path, self.boto_path, self.timeout)
57
58
59 def CheckBucketPermissions(bucket, gsutil):
60 if not bucket:
61 print >> sys.stderr, 'Missing bucket %s.'
62 return (None, 1)
63 base_url = 'gs://%s' % bucket
64
65 # Check if we have permissions to the Google Storage bucket.
66 code, _, ls_err = gsutil.check_call('ls', base_url)
67 if code == 403:
68 code, _, _ = gsutil.call('config')
69 if code != 0:
70 print >> sys.stderr, 'Error while authenticating to %s.' % base_url
71 elif code == 404:
72 print >> sys.stderr, '%s not found.' % base_url
73 elif code != 0:
74 print >> sys.stderr, ls_err
75 return (base_url, code)
76
77
78 def GetSHA1(filename):
79 sha1 = hashlib.sha1()
80 with open(filename, 'rb') as f:
81 while True:
82 # Read in 1mb chunks, so it doesn't all have to be loaded into memory.
83 chunk = f.read(1024*1024)
84 if not chunk:
85 break
86 sha1.update(chunk)
87 return sha1.hexdigest()
88
89
90 def GetMD5(filename, lock):
91 md5_calculator = hashlib.md5()
92 with lock:
93 with open(filename, 'rb') as f:
94 while True:
95 chunk = f.read(1024*1024)
96 if not chunk:
97 break
98 md5_calculator.update(chunk)
99 return md5_calculator.hexdigest()
100
101
102 def GetMD5Cached(filename, lock):
103 """Don't calculate the MD5 if we can find a .md5 file."""
104 # See if we can find an existing MD5 sum stored in a file.
105 if os.path.exists('%s.md5' % filename):
106 with open('%s.md5' % filename) as f:
107 md5_match = re.search('([a-z0-9]{32})', f.read())
108 if md5_match:
109 return md5_match.group(1)
110 else:
111 md5_hash = GetMD5(filename, lock)
112 with open('%s.md5' % filename, 'w') as f:
113 f.write(md5_hash)
114 return md5_hash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698