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

Side by Side Diff: gslib/commands/hash.py

Issue 698893003: Update checked in version of gsutil to version 4.6 (Closed) Base URL: http://dart.googlecode.com/svn/third_party/gsutil/
Patch Set: Created 6 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « gslib/commands/du.py ('k') | gslib/commands/help.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 # -*- coding: utf-8 -*-
2 # Copyright 2014 Google Inc. All Rights Reserved.
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 """Implementation of hash command for calculating hashes of local files."""
16
17 from hashlib import md5
18 import os
19
20 import crcmod
21
22 from gslib.command import Command
23 from gslib.cs_api_map import ApiSelector
24 from gslib.exception import CommandException
25 from gslib.hashing_helper import Base64EncodeHash
26 from gslib.hashing_helper import CalculateHashesFromContents
27 from gslib.hashing_helper import SLOW_CRCMOD_WARNING
28 from gslib.progress_callback import ConstructAnnounceText
29 from gslib.progress_callback import FileProgressCallbackHandler
30 from gslib.progress_callback import ProgressCallbackWithBackoff
31 from gslib.storage_url import StorageUrlFromString
32 from gslib.util import NO_MAX
33 from gslib.util import UsingCrcmodExtension
34
35 _DETAILED_HELP_TEXT = ("""
36 <B>SYNOPSIS</B>
37 gsutil [-c] [-h] [-m] hash filename...
38
39 <B>DESCRIPTION</B>
40 The hash command calculates hashes on a local file that can be used to compare
41 with gsutil ls -L output. If a specific hash option is not provided, this
42 command calculates all gsutil-supported hashes for the file.
43
44 Note that gsutil automatically performs hash validation when uploading or
45 downloading files, so this command is only needed if you want to write a
46 script that separately checks the hash for some reason.
47
48 If you calculate a CRC32c hash for the file without a precompiled crcmod
49 installation, hashing will be very slow. See "gsutil help crcmod" for details.
50
51 <B>OPTIONS</B>
52 -c Calculate a CRC32c hash for the file.
53
54 -h Output hashes in hex format. By default, gsutil uses base64.
55
56 -m Calculate a MD5 hash for the file.
57 """)
58
59
60 class HashCommand(Command):
61 """Implementation of gsutil hash command."""
62
63 # Command specification. See base class for documentation.
64 command_spec = Command.CreateCommandSpec(
65 'hash',
66 command_name_aliases=[],
67 min_args=1,
68 max_args=NO_MAX,
69 supported_sub_args='chm',
70 file_url_ok=True,
71 provider_url_ok=False,
72 urls_start_arg=0,
73 gs_api_support=[ApiSelector.JSON],
74 gs_default_api=ApiSelector.JSON,
75 )
76 # Help specification. See help_provider.py for documentation.
77 help_spec = Command.HelpSpec(
78 help_name='hash',
79 help_name_aliases=['checksum'],
80 help_type='command_help',
81 help_one_line_summary='Calculate file hashes',
82 help_text=_DETAILED_HELP_TEXT,
83 subcommand_help_text={},
84 )
85
86 @classmethod
87 def _ParseOpts(cls, sub_opts, logger):
88 """Returns behavior variables based on input options.
89
90 Args:
91 sub_opts: getopt sub-arguments for the command.
92 logger: logging.Logger for the command.
93
94 Returns:
95 Tuple of
96 calc_crc32c: Boolean, if True, command should calculate a CRC32c checksum.
97 calc_md5: Boolean, if True, command should calculate an MD5 hash.
98 format_func: Function used for formatting the hash in the desired format.
99 output_format: String describing the hash output format.
100 """
101 calc_crc32c = False
102 calc_md5 = False
103 format_func = lambda digest: Base64EncodeHash(digest.hexdigest())
104 found_hash_option = False
105 output_format = 'base64'
106
107 if sub_opts:
108 for o, unused_a in sub_opts:
109 if o == '-c':
110 calc_crc32c = True
111 found_hash_option = True
112 elif o == '-h':
113 output_format = 'hex'
114 format_func = lambda digest: digest.hexdigest()
115 elif o == '-m':
116 calc_md5 = True
117 found_hash_option = True
118
119 if not found_hash_option:
120 calc_crc32c = True
121 calc_md5 = True
122
123 if calc_crc32c and not UsingCrcmodExtension(crcmod):
124 logger.warn(SLOW_CRCMOD_WARNING)
125
126 return calc_crc32c, calc_md5, format_func, output_format
127
128 def _GetHashClassesFromArgs(self, calc_crc32c, calc_md5):
129 """Constructs the dictionary of hashes to compute based on the arguments.
130
131 Args:
132 calc_crc32c: If True, CRC32c should be included.
133 calc_md5: If True, MD5 should be included.
134
135 Returns:
136 Dictionary of {string: hash digester}, where string the name of the
137 digester algorithm.
138 """
139 hash_dict = {}
140 if calc_crc32c:
141 hash_dict['crc32c'] = crcmod.predefined.Crc('crc-32c')
142 if calc_md5:
143 hash_dict['md5'] = md5()
144 return hash_dict
145
146 def RunCommand(self):
147 """Command entry point for the hash command."""
148 (calc_crc32c, calc_md5, format_func, output_format) = (
149 self._ParseOpts(self.sub_opts, self.logger))
150
151 matched_one = False
152 for url_str in self.args:
153 if not StorageUrlFromString(url_str).IsFileUrl():
154 raise CommandException('"hash" command requires a file URL')
155
156 for file_ref in self.WildcardIterator(url_str).IterObjects():
157 matched_one = True
158 file_name = file_ref.storage_url.object_name
159 file_size = os.path.getsize(file_name)
160 callback_processor = ProgressCallbackWithBackoff(
161 file_size, FileProgressCallbackHandler(
162 ConstructAnnounceText('Hashing', file_name), self.logger).call)
163 hash_dict = self._GetHashClassesFromArgs(calc_crc32c, calc_md5)
164 with open(file_name, 'rb') as fp:
165 CalculateHashesFromContents(fp, hash_dict,
166 callback_processor=callback_processor)
167 print 'Hashes [%s] for %s:' % (output_format, file_name)
168 for name, digest in hash_dict.iteritems():
169 print '\tHash (%s):\t\t%s' % (name, format_func(digest))
170
171 if not matched_one:
172 raise CommandException('No files matched')
173
174 return 0
175
OLDNEW
« no previous file with comments | « gslib/commands/du.py ('k') | gslib/commands/help.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698