blob: 3a4b29b0b4a7d69d04a9c2f3dcbd6f27ae13b438 [file] [log] [blame]
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import os
import re
import urlparse
class Page(object):
def __init__(self, url, page_set, attributes=None, base_dir=None):
self.url = url
self.page_set = page_set
self._base_dir = base_dir
# These attributes can be set dynamically by the page.
self.credentials = None
self.disabled = False
self.name = None
self.script_to_evaluate_on_commit = None
if attributes:
for k, v in attributes.iteritems():
setattr(self, k, v)
if not self._scheme:
raise ValueError('Must prepend the URL with scheme (e.g. file://)')
def __getattr__(self, name):
# Inherit attributes from the page set.
if self.page_set and hasattr(self.page_set, name):
return getattr(self.page_set, name)
raise AttributeError(
'%r object has no attribute %r' % (self.__class__, name))
def __lt__(self, other):
return self.url < other.url
def __cmp__(self, other):
x = cmp(self.name, other.name)
if x != 0:
return x
return cmp(self.url, other.url)
def __str__(self):
return self.url
@property
def _scheme(self):
return urlparse.urlparse(self.url).scheme
@property
def is_file(self):
"""Returns True iff this URL points to a file."""
return self._scheme == 'file'
@property
def is_local(self):
"""Returns True iff this URL is local. This includes chrome:// URLs."""
return self._scheme == 'file' or self._scheme == 'chrome'
@property
def file_path(self):
"""Returns the path of the file, stripping the scheme and query string."""
assert self.is_file
# Because ? is a valid character in a filename,
# we have to treat the url as a non-file by removing the scheme.
parsed_url = urlparse.urlparse(self.url[7:])
return os.path.normpath(os.path.join(
self._base_dir, parsed_url.netloc + parsed_url.path))
@property
def file_path_url(self):
"""Returns the file path, including the params, query, and fragment."""
assert self.is_file
file_path_url = os.path.normpath(os.path.join(self._base_dir, self.url[7:]))
# Preserve trailing slash or backslash.
# It doesn't matter in a file path, but it does matter in a URL.
if self.url.endswith('/'):
file_path_url += os.sep
return file_path_url
@property
def serving_dir(self):
file_path = os.path.realpath(self.file_path)
if os.path.isdir(file_path):
return file_path
else:
return os.path.dirname(file_path)
@property
def file_safe_name(self):
"""A version of display_name that's safe to use as a filename."""
# Just replace all special characters in the url with underscore.
return re.sub('[^a-zA-Z0-9]', '_', self.display_name)
@property
def display_name(self):
if self.name:
return self.name
if not self.is_file:
return self.url
all_urls = [p.url.rstrip('/') for p in self.page_set if p.is_file]
common_prefix = os.path.dirname(os.path.commonprefix(all_urls))
return self.url[len(common_prefix):].strip('/')
@property
def archive_path(self):
return self.page_set.WprFilePathForPage(self)