OLD | NEW |
---|---|
(Empty) | |
1 #!/usr/bin/python | |
rmistry
2014/01/22 22:00:30
The file name is confusing to me, how about someth
epoger
2014/01/23 05:00:53
Good thoughts; let's discuss live.
One more optio
rmistry
2014/01/23 12:48:23
Feel free to grab me anytime today.
epoger
2014/01/23 15:34:19
Discussed live: I will go with file:/// URLs, and
epoger
2014/01/24 02:00:46
Done. I use file:/// URLs for the unittest. I ke
| |
2 | |
3 """ | |
4 Copyright 2014 Google Inc. | |
5 | |
6 Use of this source code is governed by a BSD-style license that can be | |
7 found in the LICENSE file. | |
8 | |
9 Utility module for handling paths that may be either URL paths or local | |
10 filepaths. | |
11 | |
12 TODO(epoger): Move this module to some common place so we can use it more widely | |
13 """ | |
14 | |
15 # System-level imports | |
16 import contextlib | |
17 import os | |
18 import posixpath | |
19 import shutil | |
20 import urllib | |
21 import urllib2 | |
22 import urlparse | |
23 | |
24 def is_url(path): | |
25 """ Returns true if path looks like a URL. """ | |
26 scheme = urlparse.urlparse(path).scheme | |
rmistry
2014/01/22 22:00:30
return True if urlparse.urlparse(path).scheme else
epoger
2014/01/23 05:00:53
Done.
| |
27 if scheme: | |
28 return True | |
29 else: | |
30 return False | |
31 | |
32 def join(first, *remaining): | |
33 """ Joins two or more URL or pathname components. If the first component | |
34 looks like a valid URL, we assemble a URL; otherwise, we assemble it as | |
35 a pathname to a local file. | |
36 | |
37 Args: | |
38 first: string; first component of the URL/path | |
39 remaining: variable number of strings; remaining URL/path components | |
40 | |
41 Returns: | |
42 The complete URL or filename path. | |
43 """ | |
44 if is_url(first): | |
45 return posixpath.join(first, *remaining) | |
46 else: | |
47 return os.path.join(first, *remaining) | |
48 | |
49 def create_filepath_url(filepath): | |
50 """ Returns a file:/// URL pointing at the given filepath on local disk. | |
51 | |
52 Args: | |
53 filepath: string; path to a file on local disk (may be absolute or relative, | |
54 and the file does not need to exist) | |
55 | |
56 Returns: | |
57 A file:/// URL pointing at the file. Regardless of whether filepath was | |
58 specified as a relative or absolute path, the URL will contain an | |
59 absolute path to the file. | |
60 | |
61 Raises: | |
62 An Exception, if filepath is already a URL. | |
63 """ | |
64 if is_url(filepath): | |
65 raise Exception('"%s" is already a URL' % filepath) | |
66 return urlparse.urljoin( | |
67 'file:', urllib.pathname2url(os.path.abspath(filepath))) | |
68 | |
69 def read_as_string(path): | |
70 """ Reads in the full contents of the URL or filepath 'path', returning those | |
71 contents as a single string. | |
72 | |
73 Args: | |
74 path: string; complete URL or filepath (if filepath, may be absolute or | |
75 relative) | |
76 | |
77 Returns: | |
78 Complete contents of the URL or filepath as a string. | |
79 | |
80 Raises: | |
81 Some subclass of Exception if unable to read the contents (URL/file not | |
82 found, etc.) | |
83 """ | |
84 if is_url(path): | |
85 try: | |
86 return urllib2.urlopen(path).read() | |
87 except Exception, e: | |
88 e.msg += ' for URL ' + path | |
89 raise | |
90 else: | |
91 return open(path, 'r').read() | |
92 | |
93 def copy_contents(source_path, dest_path, create_subdirs_if_needed=False): | |
94 """ Copies the full contents of the URL or filepath 'source_path' into | |
95 filepath 'dest_path'. | |
96 | |
97 Args: | |
98 source_path: string; complete URL or filepath to read from (if filepath, | |
99 may be absolute or relative) | |
100 dest_path: string; complete filepath to write to (may be absolute or | |
101 relative) | |
102 create_subdirs_if_needed: boolean; whether to create subdirectories as | |
103 needed to create dest_path | |
104 | |
105 Raises: | |
106 Some subclass of Exception if unable to read source_path (URL/file not | |
107 found, etc.) or write dest_path. | |
108 """ | |
109 if create_subdirs_if_needed: | |
110 dest_dir = os.path.dirname(dest_path) | |
111 if not os.path.exists(dest_dir): | |
112 os.makedirs(dest_dir) | |
113 if is_url(source_path): | |
114 with contextlib.closing(urllib.urlopen(source_path)) as source_handle: | |
115 with open(dest_path, 'wb') as dest_handle: | |
116 shutil.copyfileobj(fsrc=source_handle, fdst=dest_handle) | |
117 else: | |
118 shutil.copyfile(source_path, dest_path) | |
OLD | NEW |