1#!/usr/bin/python
2
3"""
4Copyright 2014 Google Inc.
5
6Use of this source code is governed by a BSD-style license that can be
7found in the LICENSE file.
8
9Utilities for working with URLs.
10
11TODO(epoger): move this into tools/utils for broader use?
12"""
13
14# System-level imports
15import contextlib
16import os
17import shutil
18import urllib
19import urlparse
20
21
22def create_filepath_url(filepath):
23  """ Returns a file:/// URL pointing at the given filepath on local disk.
24
25  Args:
26    filepath: string; path to a file on local disk (may be absolute or relative,
27        and the file does not need to exist)
28
29  Returns:
30    A file:/// URL pointing at the file.  Regardless of whether filepath was
31        specified as a relative or absolute path, the URL will contain an
32        absolute path to the file.
33
34  Raises:
35    An Exception, if filepath is already a URL.
36  """
37  if urlparse.urlparse(filepath).scheme:
38    raise Exception('"%s" is already a URL' % filepath)
39  return urlparse.urljoin(
40      'file:', urllib.pathname2url(os.path.abspath(filepath)))
41
42
43def copy_contents(source_url, dest_path, create_subdirs_if_needed=False):
44  """ Copies the full contents of the URL 'source_url' into
45  filepath 'dest_path'.
46
47  Args:
48    source_url: string; complete URL to read from
49    dest_path: string; complete filepath to write to (may be absolute or
50        relative)
51    create_subdirs_if_needed: boolean; whether to create subdirectories as
52        needed to create dest_path
53
54  Raises:
55    Some subclass of Exception if unable to read source_url or write dest_path.
56  """
57  if create_subdirs_if_needed:
58    dest_dir = os.path.dirname(dest_path)
59    if not os.path.exists(dest_dir):
60      os.makedirs(dest_dir)
61  with contextlib.closing(urllib.urlopen(source_url)) as source_handle:
62    with open(dest_path, 'wb') as dest_handle:
63      shutil.copyfileobj(fsrc=source_handle, fdst=dest_handle)
64