mirror of
https://github.com/arsenetar/dupeguru.git
synced 2026-01-22 14:41:39 +00:00
Reorganized hscommon documentation
Removed hscommon's "docs" folder and moved all documentation directly into docstrings. Then, in dupeGuru's developer documentation, added autodoc references to relevant modules. The result is a much more usable hscommon documentation.
This commit is contained in:
103
hscommon/util.py
103
hscommon/util.py
@@ -18,14 +18,16 @@ from datetime import timedelta
|
||||
from .path import Path, pathify, log_io_error
|
||||
|
||||
def nonone(value, replace_value):
|
||||
''' Returns value if value is not None. Returns replace_value otherwise.
|
||||
'''
|
||||
"""Returns ``value`` if ``value`` is not ``None``. Returns ``replace_value`` otherwise.
|
||||
"""
|
||||
if value is None:
|
||||
return replace_value
|
||||
else:
|
||||
return value
|
||||
|
||||
def tryint(value, default=0):
|
||||
"""Tries to convert ``value`` to in ``int`` and returns ``default`` if it fails.
|
||||
"""
|
||||
try:
|
||||
return int(value)
|
||||
except (TypeError, ValueError):
|
||||
@@ -39,8 +41,10 @@ def minmax(value, min_value, max_value):
|
||||
#--- Sequence related
|
||||
|
||||
def dedupe(iterable):
|
||||
'''Returns a list of elements in iterable with all dupes removed.
|
||||
'''
|
||||
"""Returns a list of elements in ``iterable`` with all dupes removed.
|
||||
|
||||
The order of the elements is preserved.
|
||||
"""
|
||||
result = []
|
||||
seen = {}
|
||||
for item in iterable:
|
||||
@@ -51,11 +55,11 @@ def dedupe(iterable):
|
||||
return result
|
||||
|
||||
def flatten(iterables, start_with=None):
|
||||
'''Takes a list of lists 'lists' and returns a list containing elements of every list.
|
||||
"""Takes a list of lists ``iterables`` and returns a list containing elements of every list.
|
||||
|
||||
If start_with is not None, the result will start with start_with items, exactly as if
|
||||
start_with would be the first item of lists.
|
||||
'''
|
||||
If ``start_with`` is not ``None``, the result will start with ``start_with`` items, exactly as
|
||||
if ``start_with`` would be the first item of lists.
|
||||
"""
|
||||
result = []
|
||||
if start_with:
|
||||
result.extend(start_with)
|
||||
@@ -64,7 +68,7 @@ def flatten(iterables, start_with=None):
|
||||
return result
|
||||
|
||||
def first(iterable):
|
||||
"""Returns the first item of 'iterable'
|
||||
"""Returns the first item of ``iterable``.
|
||||
"""
|
||||
try:
|
||||
return next(iter(iterable))
|
||||
@@ -116,10 +120,13 @@ def trailiter(iterable, skipfirst=False):
|
||||
#--- String related
|
||||
|
||||
def escape(s, to_escape, escape_with='\\'):
|
||||
"""Returns ``s`` with characters in ``to_escape`` all prepended with ``escape_with``.
|
||||
"""
|
||||
return ''.join((escape_with + c if c in to_escape else c) for c in s)
|
||||
|
||||
def get_file_ext(filename):
|
||||
"""Returns the lowercase extension part of filename, without the dot."""
|
||||
"""Returns the lowercase extension part of filename, without the dot.
|
||||
"""
|
||||
pos = filename.rfind('.')
|
||||
if pos > -1:
|
||||
return filename[pos + 1:].lower()
|
||||
@@ -127,7 +134,8 @@ def get_file_ext(filename):
|
||||
return ''
|
||||
|
||||
def rem_file_ext(filename):
|
||||
"""Returns the filename without extension."""
|
||||
"""Returns the filename without extension.
|
||||
"""
|
||||
pos = filename.rfind('.')
|
||||
if pos > -1:
|
||||
return filename[:pos]
|
||||
@@ -135,12 +143,13 @@ def rem_file_ext(filename):
|
||||
return filename
|
||||
|
||||
def pluralize(number, word, decimals=0, plural_word=None):
|
||||
"""Returns a string with number in front of s, and adds a 's' to s if number > 1
|
||||
"""Returns a pluralized string with ``number`` in front of ``word``.
|
||||
|
||||
number: The number to go in front of s
|
||||
word: The word to go after number
|
||||
decimals: The number of digits after the dot
|
||||
plural_word: If the plural rule for word is more complex than adding a 's', specify a plural
|
||||
Adds a 's' to s if ``number`` > 1.
|
||||
``number``: The number to go in front of s
|
||||
``word``: The word to go after number
|
||||
``decimals``: The number of digits after the dot
|
||||
``plural_word``: If the plural rule for word is more complex than adding a 's', specify a plural
|
||||
"""
|
||||
number = round(number, decimals)
|
||||
format = "%%1.%df %%s" % decimals
|
||||
@@ -154,7 +163,7 @@ def pluralize(number, word, decimals=0, plural_word=None):
|
||||
def format_time(seconds, with_hours=True):
|
||||
"""Transforms seconds in a hh:mm:ss string.
|
||||
|
||||
If `with_hours` if false, the format is mm:ss.
|
||||
If ``with_hours`` if false, the format is mm:ss.
|
||||
"""
|
||||
minus = seconds < 0
|
||||
if minus:
|
||||
@@ -171,7 +180,8 @@ def format_time(seconds, with_hours=True):
|
||||
return r
|
||||
|
||||
def format_time_decimal(seconds):
|
||||
"""Transforms seconds in a strings like '3.4 minutes'"""
|
||||
"""Transforms seconds in a strings like '3.4 minutes'.
|
||||
"""
|
||||
minus = seconds < 0
|
||||
if minus:
|
||||
seconds *= -1
|
||||
@@ -193,11 +203,15 @@ SIZE_VALS = tuple(1024 ** i for i in range(1,9))
|
||||
def format_size(size, decimal=0, forcepower=-1, showdesc=True):
|
||||
"""Transform a byte count in a formatted string (KB, MB etc..).
|
||||
|
||||
size is the number of bytes to format.
|
||||
decimal is the number digits after the dot.
|
||||
forcepower is the desired suffix. 0 is B, 1 is KB, 2 is MB etc.. if kept at -1, the suffix will
|
||||
be automatically chosen (so the resulting number is always below 1024).
|
||||
if showdesc is True, the suffix will be shown after the number.
|
||||
``size`` is the number of bytes to format.
|
||||
``decimal`` is the number digits after the dot.
|
||||
``forcepower`` is the desired suffix. 0 is B, 1 is KB, 2 is MB etc.. if kept at -1, the suffix
|
||||
will be automatically chosen (so the resulting number is always below 1024).
|
||||
if ``showdesc`` is ``True``, the suffix will be shown after the number.
|
||||
Usage example::
|
||||
|
||||
>>> format_size(1234, decimal=2, showdesc=True)
|
||||
'1.21 KB'
|
||||
"""
|
||||
if forcepower < 0:
|
||||
i = 0
|
||||
@@ -234,16 +248,16 @@ def remove_invalid_xml(s, replace_with=' '):
|
||||
def multi_replace(s, replace_from, replace_to=''):
|
||||
"""A function like str.replace() with multiple replacements.
|
||||
|
||||
replace_from is a list of things you want to replace. Ex: ['a','bc','d']
|
||||
replace_to is a list of what you want to replace to.
|
||||
If replace_to is a list and has the same length as replace_from, replace_from
|
||||
items will be translated to corresponding replace_to. A replace_to list must
|
||||
have the same length as replace_from
|
||||
If replace_to is a basestring, all replace_from occurence will be replaced
|
||||
``replace_from`` is a list of things you want to replace. Ex: ['a','bc','d']
|
||||
``replace_to`` is a list of what you want to replace to.
|
||||
If ``replace_to`` is a list and has the same length as ``replace_from``, ``replace_from``
|
||||
items will be translated to corresponding ``replace_to``. A ``replace_to`` list must
|
||||
have the same length as ``replace_from``
|
||||
If ``replace_to`` is a string, all ``replace_from`` occurence will be replaced
|
||||
by that string.
|
||||
replace_from can also be a str. If it is, every char in it will be translated
|
||||
as if replace_from would be a list of chars. If replace_to is a str and has
|
||||
the same length as replace_from, it will be transformed into a list.
|
||||
``replace_from`` can also be a str. If it is, every char in it will be translated
|
||||
as if ``replace_from`` would be a list of chars. If ``replace_to`` is a str and has
|
||||
the same length as ``replace_from``, it will be transformed into a list.
|
||||
"""
|
||||
if isinstance(replace_to, str) and (len(replace_from) != len(replace_to)):
|
||||
replace_to = [replace_to for r in replace_from]
|
||||
@@ -298,8 +312,8 @@ def find_in_path(name, paths=None):
|
||||
@log_io_error
|
||||
@pathify
|
||||
def delete_if_empty(path: Path, files_to_delete=[]):
|
||||
''' Deletes the directory at 'path' if it is empty or if it only contains files_to_delete.
|
||||
'''
|
||||
"""Deletes the directory at 'path' if it is empty or if it only contains files_to_delete.
|
||||
"""
|
||||
if not path.exists() or not path.isdir():
|
||||
return
|
||||
contents = path.listdir()
|
||||
@@ -311,10 +325,16 @@ def delete_if_empty(path: Path, files_to_delete=[]):
|
||||
return True
|
||||
|
||||
def open_if_filename(infile, mode='rb'):
|
||||
"""
|
||||
infile can be either a string or a file-like object.
|
||||
if it is a string, a file will be opened with mode.
|
||||
Returns a tuple (shouldbeclosed,infile) infile is a file object
|
||||
"""If ``infile`` is a string, it opens and returns it. If it's already a file object, it simply returns it.
|
||||
|
||||
This function returns ``(file, should_close_flag)``. The should_close_flag is True is a file has
|
||||
effectively been opened (if we already pass a file object, we assume that the responsibility for
|
||||
closing the file has already been taken). Example usage::
|
||||
|
||||
fp, shouldclose = open_if_filename(infile)
|
||||
dostuff()
|
||||
if shouldclose:
|
||||
fp.close()
|
||||
"""
|
||||
if isinstance(infile, Path):
|
||||
return (infile.open(mode), True)
|
||||
@@ -349,6 +369,13 @@ def delete_files_with_pattern(folder_path, pattern, recursive=True):
|
||||
delete_files_with_pattern(p, pattern, True)
|
||||
|
||||
class FileOrPath:
|
||||
"""Does the same as :func:`open_if_filename`, but it can be used with a ``with`` statement.
|
||||
|
||||
Example::
|
||||
|
||||
with FileOrPath(infile):
|
||||
dostuff()
|
||||
"""
|
||||
def __init__(self, file_or_path, mode='rb'):
|
||||
self.file_or_path = file_or_path
|
||||
self.mode = mode
|
||||
|
||||
Reference in New Issue
Block a user