upsies.utils

Swiss Army knife

Modules

argtypes

CLI argument types

bbcode

Helper functions for generating BBcode

browser

Open a URL in a web browser

config

Provide access to user configuration loaded from INI files

country

Look up country information

daemon

Background workers to keep the UI responsive

disc

Get information from "BDMV" and "VIDEO_TS" directory trees

fs

File system helpers

html

HTML parsing

http

HTTP methods with caching

image

Dump frames from video file

mediainfo

predbs

Scene release search and verification

release

Release name parsing and formatting

signal

Managing callbacks

string

String formatting and parsing

subproc

Execute external commands

torrent

Create torrent file

types

CLI argument types

update

Find most recent version

webdbs

API for querying services like IMDb

Functions

upsies.utils.as_groups(sequence, group_sizes, default=None)[source]

Iterate over items from sequence in equally sized groups

Params sequence:

List of items to group

Params group_sizes:

Sequence of acceptable number of items in a group

Find the group size with the lowest number of default items in the last group. That group size is then used for all groups.

Parameters:

default – Value to pad last group with if len(sequence) % group_size != 0

Example:

>>> sequence = range(1, 10)
>>> for group in as_groups(sequence, [4, 5], default="_"):
...     print(group)
(1, 2, 3, 4, 5)
(6, 7, 8, 9, '_')
>>> for group in as_groups(sequence, [3, 4], default="_"):
...     print(group)
(1, 2, 3)
(4, 5, 6)
(7, 8, 9)
upsies.utils.blocking_memoize(coro_func)[source]

Asynchronous memoization decorator that blocks concurrent calls with the same arguments

The first call calls the decorated function while subsequent calls wait until the first call returns and the return value is cached. Subsequent calls then get the return value from the cache.

Exceptions raised by coro_func are also cached and re-raised on subsequent calls.

The decorated function provides a clear_cache method that removes any cached return values.

upsies.utils.closest_number(n, ns, max=None, default=0)[source]

Return the number from ns that is closest to n

Parameters:
  • n – Given number

  • ns – Sequence of allowed numbers

  • max – Remove any item from ns that is larger than max

  • default – Return value in case ns is empty

upsies.utils.deduplicate(seq, key=None)[source]

Return sequence seq with all duplicate items removed while maintaining the original order

Parameters:

key – Callable that gets each item and returns a hashable identifier for that item

upsies.utils.flatten_nested_lists(thing)[source]

Return flattened list

Parameters:

thing – Arbitrarily nested iterables

If thing is not an iterable (and not a string), it is returned inside a list.

upsies.utils.is_running_in_development_environment()[source]

Whether we are running in a development environment or in production

This is determined by looking for a UPSIES_DEV variable and interpreting its value as a Bool. The default is False.

upsies.utils.is_sequence(obj)[source]

Return whether obj is a sequence and not a string

upsies.utils.merge_dicts(a, b, path=())[source]

Merge nested dictionaries a and b into new dictionary with same structure

upsies.utils.os_family()[source]

Return “windows” or “unix”

async upsies.utils.run_async(function, *args, **kwargs)[source]

Run synchronous function asynchronously in a thread

See asyncio.BaseEventLoop.run_in_executor().

upsies.utils.run_task(coro, callback)[source]

Run awaitable in background task and return immediately

This method should be used to call coroutine functions and other awaitables in a synchronous context.

The returned task must be collected (e.g. in a list) and awaited or cancelled eventually.

Parameters:
  • coro – Any awaitable object

  • callback – Callable that is called with the returned task when coro returns, is cancelled or raises any other exception

Returns:

asyncio.Task instance

upsies.utils.semantic_hash(obj)[source]

Return SHA256 hash for obj that stays the same between Python interpreter sessions

https://github.com/schollii/sandals/blob/master/json_sem_hash.py

upsies.utils.subclasses(basecls, modules)[source]

Find subclasses in modules

Parameters:
  • basecls (type) – Class that all returned classes are a subclass of

  • modules (list of module objects) – Modules to search

upsies.utils.submodules(package)[source]

Return list of submodules and subpackages in package

Parameters:

package (str) – Fully qualified name of parent package, e.g. “upsies.imagehosts”

Classes

class upsies.utils.LazyModule(module, namespace, name=None)[source]

Bases: ModuleType

Lazily import module to decrease execution time

Parameters:
  • module (str) – Name of the module

  • namespace (mapping) – Usually the return value of globals()

  • name (str) – Name of the module in namespace; defaults to module

class upsies.utils.MonitoredList(*args, callback, **kwargs)[source]

Bases: MutableSequence

list that calls callback after every change

Parameters:

callback – Callable that gets the instance as a positional argument

insert(index, value)[source]

S.insert(index, value) – insert value before index

class upsies.utils.PrettyEnum(value)[source]

Bases: Enum

classmethod from_string(string)[source]

Convert human-readable string back to enum

>>> TrumpableReason.from_string(
...     str(TrumpableReason.HARDCODED_SUBTITLES)
... )
<TrumpableReason.HARDCODED_SUBTITLES: 4>
Raises:

AttributeError – if string is not known