diff options
Diffstat (limited to 'mvc/utils.py')
-rw-r--r-- | mvc/utils.py | 230 |
1 files changed, 0 insertions, 230 deletions
diff --git a/mvc/utils.py b/mvc/utils.py deleted file mode 100644 index e0a64f3..0000000 --- a/mvc/utils.py +++ /dev/null @@ -1,230 +0,0 @@ -import ctypes -import itertools -import logging -import os -import sys - -def hms_to_seconds(hours, minutes, seconds): - return (hours * 3600 + - minutes * 60 + - seconds) - - -def round_even(num): - """This takes a number, converts it to an integer, then makes - sure it's even. - - Additional rules: this helper always rounds down to avoid stray black - pixels (see bz18122). - - This function makes sure that the value returned is always >= 0. - """ - num = int(num) - val = num - (num % 2) - return val if val > 0 else 0 - - -def rescale_video((source_width, source_height), - (target_width, target_height), - dont_upsize=True): - """ - Rescale a video given a (width, height) target. This returns the largest - (width, height) which maintains the original aspect ratio while fitting - within the target size. - - If dont_upsize is set, then don't resize it such that the rescaled size - will be larger than the original size. - """ - if source_width is None or source_height is None: - return (round_even(target_width), round_even(target_height)) - - if target_width is None or target_height is None: - return (round_even(source_width), round_even(source_height)) - - if (dont_upsize and - (source_width <= target_width or source_height <= target_height)): - return (round_even(source_width), round_even(source_height)) - - width_ratio = float(source_width) / float(target_width) - height_ratio = float(source_height) / float(target_height) - ratio = max(width_ratio, height_ratio) - return round_even(source_width / ratio), round_even(source_height / ratio) - -def line_reader(handle): - """Builds a line reading generator for the given handle. This - generator breaks on empty strings, \\r and \\n. - - This a little weird, but it makes it really easy to test error - checking and progress monitoring. - """ - def _readlines(): - chars = [] - c = handle.read(1) - while True: - if c in ["", "\r", "\n"]: - if chars: - yield "".join(chars) - if not c: - break - chars = [] - else: - chars.append(c) - c = handle.read(1) - return _readlines() - - -class Matrix(object): - """2 Dimensional matrix. - - Matrix objects are accessed like a list, except tuples are used as - indices, for example: - - >>> m = Matrix(5, 5) - >>> m[3, 4] = 'foo' - >>> m - None, None, None, None, None - None, None, None, None, None - None, None, None, None, None - None, None, None, None, None - None, None, None, 'foo', None - """ - - def __init__(self, columns, rows, initial_value=None): - self.columns = columns - self.rows = rows - self.data = [ initial_value ] * (columns * rows) - - def __getitem__(self, key): - return self.data[(key[0] * self.rows) + key[1]] - - def __setitem__(self, key, value): - self.data[(key[0] * self.rows) + key[1]] = value - - def __iter__(self): - return iter(self.data) - - def __repr__(self): - return "\n".join([", ".join([repr(r) - for r in list(self.row(i))]) - for i in xrange(self.rows)]) - - def remove(self, value): - """This sets the value to None--it does NOT remove the cell - from the Matrix because that doesn't make any sense. - """ - i = self.data.index(value) - self.data[i] = None - - def row(self, row): - """Iterator that yields all the objects in a row.""" - for i in xrange(self.columns): - yield self[i, row] - - def column(self, column): - """Iterator that yields all the objects in a column.""" - for i in xrange(self.rows): - yield self[column, i] - - -class Cache(object): - def __init__(self, size): - self.size = size - self.dict = {} - self.counter = itertools.count() - self.access_times = {} - self.invalidators = {} - - def get(self, key, invalidator=None): - if key in self.dict: - existing_invalidator = self.invalidators[key] - if (existing_invalidator is None or - not existing_invalidator(key)): - self.access_times[key] = self.counter.next() - return self.dict[key] - - value = self.create_new_value(key, invalidator=invalidator) - self.set(key, value, invalidator=invalidator) - return value - - def set(self, key, value, invalidator=None): - if len(self.dict) == self.size: - self.shrink_size() - self.access_times[key] = self.counter.next() - self.dict[key] = value - self.invalidators[key] = invalidator - - def remove(self, key): - if key in self.dict: - del self.dict[key] - del self.access_times[key] - if key in self.invalidators: - del self.invalidators[key] - - def keys(self): - return self.dict.iterkeys() - - def shrink_size(self): - # shrink by LRU - to_sort = self.access_times.items() - to_sort.sort(key=lambda m: m[1]) - new_dict = {} - new_access_times = {} - new_invalidators = {} - latest_times = to_sort[len(self.dict) // 2:] - for (key, time) in latest_times: - new_dict[key] = self.dict[key] - new_invalidators[key] = self.invalidators[key] - new_access_times[key] = time - self.dict = new_dict - self.access_times = new_access_times - - def create_new_value(self, val, invalidator=None): - raise NotImplementedError() - - -def size_string(nbytes): - # when switching from the enclosure reported size to the - # downloader reported size, it takes a while to get the new size - # and the downloader returns -1. the user sees the size go to -1B - # which is weird.... better to return an empty string. - if nbytes == -1 or nbytes == 0: - return "" - - # FIXME this is a repeat of util.format_size_for_user ... should - # probably ditch one of them. - if nbytes >= (1 << 30): - value = "%.1f" % (nbytes / float(1 << 30)) - return "%(size)s GB" % {"size": value} - elif nbytes >= (1 << 20): - value = "%.1f" % (nbytes / float(1 << 20)) - return "%(size)s MB" % {"size": value} - elif nbytes >= (1 << 10): - value = "%.1f" % (nbytes / float(1 << 10)) - return "%(size)s KB" % {"size": value} - else: - return "%(size)s B" % {"size": nbytes} - -def convert_path_for_subprocess(path): - """Convert a path to a form suitable for passing to a subprocess. - - This method converts unicode paths to bytestrings according to the system - fileencoding. On windows, it converts the path to a short filename for - maximum compatibility - - This method should only be called on a path that exists on the filesystem. - """ - if not os.path.exists(path): - raise ValueError("path %r doesn't exist" % path) - if not isinstance(path, unicode): - # path already is a bytestring, just return it - return path - if sys.platform != 'win32': - return path.encode(sys.getfilesystemencoding()) - else: - buf_size = 1024 - short_path_buf = ctypes.create_unicode_buffer(buf_size) - ctypes.windll.kernel32.GetShortPathNameW(path, - short_path_buf, buf_size) - logging.info("convert_path_for_subprocess: got short path %r", - short_path_buf.value) - return short_path_buf.value.encode('ascii') |