diff options
author | Jesusaves <cpntb1@ymail.com> | 2024-02-05 11:17:23 -0300 |
---|---|---|
committer | Jesusaves <cpntb1@ymail.com> | 2024-02-05 11:17:23 -0300 |
commit | 29ffe5de3c308013742b5bd97f7d75b09bd3b427 (patch) | |
tree | 7199cecaf204701770de171d007e561589b19762 /discord_rpc/util | |
parent | f6b8c0c64757c73b6f2063d3a6d93ce2f8f527d5 (diff) | |
download | tkinter-29ffe5de3c308013742b5bd97f7d75b09bd3b427.tar.gz tkinter-29ffe5de3c308013742b5bd97f7d75b09bd3b427.tar.bz2 tkinter-29ffe5de3c308013742b5bd97f7d75b09bd3b427.tar.xz tkinter-29ffe5de3c308013742b5bd97f7d75b09bd3b427.zip |
Some button aligning, a CI template, and Discord RPC
Diffstat (limited to 'discord_rpc/util')
-rw-r--r-- | discord_rpc/util/__init__.py | 0 | ||||
-rw-r--r-- | discord_rpc/util/backoff.py | 35 | ||||
-rw-r--r-- | discord_rpc/util/limits.py | 32 | ||||
-rw-r--r-- | discord_rpc/util/types.py | 349 | ||||
-rw-r--r-- | discord_rpc/util/utils.py | 180 |
5 files changed, 596 insertions, 0 deletions
diff --git a/discord_rpc/util/__init__.py b/discord_rpc/util/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/discord_rpc/util/__init__.py diff --git a/discord_rpc/util/backoff.py b/discord_rpc/util/backoff.py new file mode 100644 index 0000000..650a871 --- /dev/null +++ b/discord_rpc/util/backoff.py @@ -0,0 +1,35 @@ +from __future__ import absolute_import +import random +from .types import Int32, Int64 + + +class Backoff(object): + _min_amt = None + _max_amt = None + _current = None + _fails = Int32() + + def __init__(self, min_amt, max_amt): + min_amt = max(min_amt, 1) + max_amt = max(max_amt, 1) + self._min_amt = Int64(min_amt) + self._max_amt = Int64(max_amt) + self._current = Int64(min_amt) + + def reset(self): + self._fails = Int32(0) + self._current = self._min_amt.get_copy() + + def next_delay(self): + self._fails += 1 + delay = Int64(self._current.get_number() * 2.0 * random.random()) + self._current = Int64(min(self._current.get_number() + delay.get_number(), self._max_amt)) + return self._current + + @property + def fails(self): + return self._fails + + @property + def current(self): + return self._current diff --git a/discord_rpc/util/limits.py b/discord_rpc/util/limits.py new file mode 100644 index 0000000..6e84b30 --- /dev/null +++ b/discord_rpc/util/limits.py @@ -0,0 +1,32 @@ +def get_min_max(bit_size, unsigned=False): + if unsigned: + bit_min = 0 + bit_max = (2**bit_size) - 1 + else: + bit_min = -(2**(bit_size - 1)) + bit_max = 2**(bit_size - 1) - 1 + return bit_min, bit_max + + +# limits for c types +CHAR_MIN = -128 +CHAR_MAX = 127 +UCHAR_MAX = 255 + +SHORT_MIN = -32768 +SHORT_MAX = 32767 +USHORT_MAX = 65535 + +INT_MIN = -2147483648 +INT_MAX = 2147483647 +UINT_MAX = 4294967295 +INT32_MIN = INT_MIN +INT32_MAX = INT_MAX +UINT32_MAX = UINT_MAX + +LONG_MIN = -9223372036854775808 +LONG_MAX = 9223372036854775807 +ULONG_MAX = 18446744073709551615 +INT64_MIN = LONG_MIN +INT64_MAX = LONG_MAX +UINT64_MAX = ULONG_MAX diff --git a/discord_rpc/util/types.py b/discord_rpc/util/types.py new file mode 100644 index 0000000..fdfd246 --- /dev/null +++ b/discord_rpc/util/types.py @@ -0,0 +1,349 @@ +from __future__ import absolute_import +from .limits import INT32_MIN, INT32_MAX, UINT32_MAX, INT64_MIN, INT64_MAX, UINT64_MAX + + +_number_types = [int] +try: + _number_types.append(float) +except NameError: + pass +try: + _number_types.append(long) +except NameError: + pass +_number_types = tuple(_number_types) + + +class UnderflowError(ArithmeticError): + pass + + +class Number(object): + _min = None + _max = None + _bits = None + _raise_exceptions = False + + def __init__(self, number=0, raise_exceptions=False): + self._raise_exceptions = raise_exceptions + if isinstance(number, Number): + number = number.get_number() + else: + # validate number, ret_val should only be number, not a class + number = self._check_number(number, number_only=True) + if not isinstance(number, _number_types): + raise TypeError('Number must be of type int/float/long!') + self._number = number + + def _check_number(self, num, number_only=False): + if self._max is not None and self._min is not None: + if self._raise_exceptions: + if num > self._max: + raise OverflowError() + elif num < self._min: + raise UnderflowError() + if self._min == 0: + if not number_only: + return self.__class__(num & self._max) + else: + return num & self._max + else: + if num & (1 << (self._bits-1)): + if not number_only: + return self.__class__(num | ~self._max) + else: + return num | ~self._max + else: + if not number_only: + return self.__class__(num & self._max) + else: + return num & self._max + else: + # there are no min/max to check with, so just return the number + if not number_only: + return self.__class__(num) + else: + return num + + def __lt__(self, other): + if isinstance(other, Number): + other = other.get_number() + return self._number < other + + def __le__(self, other): + if isinstance(other, Number): + other = other.get_number() + return self._number <= other + + def __eq__(self, other): + if isinstance(other, Number): + other = other.get_number() + return self._number == other + + def __ne__(self, other): + if isinstance(other, Number): + other = other.get_number() + return self._number != other + + def __gt__(self, other): + if isinstance(other, Number): + other = other.get_number() + return self._number > other + + def __ge__(self, other): + if isinstance(other, Number): + other = other.get_number() + return self._number >= other + + def __bool__(self): + return self._number + + def __repr__(self): + return "{class_name}({number})".format(class_name=self.__class__.__name__, number=self._number) + + def __str__(self): + return str(self._number) + + def __cmp__(self, other): + if isinstance(other, Number): + other = other.get_number() + if self._number == other: + return 0 + elif self._number < other: + return -1 + elif self._number > other: + return 1 + + def __nonzero__(self): + return self._number != 0 + + def __add__(self, other): + if isinstance(other, Number): + other = other.get_number() + return self._check_number(self._number + other) + + def __sub__(self, other): + if isinstance(other, Number): + other = other.get_number() + return self._check_number(self._number - other) + + def __mul__(self, other): + if isinstance(other, Number): + other = other.get_number() + return self._check_number(self._number * other) + + def __div__(self, other): + if isinstance(other, Number): + other = other.get_number() + return self._check_number(self._number / other) + + def __truediv__(self, other): + if isinstance(other, Number): + other = other.get_number() + return self.__div__(other) + + def __floordiv__(self, other): + if isinstance(other, Number): + other = other.get_number() + return self._check_number(self._number // other) + + def __mod__(self, other): + if isinstance(other, Number): + other = other.get_number() + return self._check_number(self._number % other) + + def __divmod__(self, other): + if isinstance(other, Number): + other = other.get_number() + return self._check_number(divmod(self._number, other)) + + def __pow__(self, power, modulo=None): + if isinstance(power, Number): + power = power.get_number() + if modulo is not None and isinstance(modulo, Number): + modulo = modulo.get_number() + return self._check_number(pow(self._number, power, modulo)) + + def __lshift__(self, other): + if isinstance(other, Number): + other = other.get_number() + return self._check_number(self._number << other) + + def __rshift__(self, other): + if isinstance(other, Number): + other = other.get_number() + return self._check_number(self._number >> other) + + def __and__(self, other): + if isinstance(other, Number): + other = other.get_number() + return self._check_number(self._number & other) + + def __xor__(self, other): + if isinstance(other, Number): + other = other.get_number() + return self._check_number(self._number ^ other) + + def __or__(self, other): + if isinstance(other, Number): + other = other.get_number() + return self._check_number(self._number | other) + + def __radd__(self, other): + if isinstance(other, Number): + other = other.get_number() + return self._check_number(other + self._number) + + def __rsub__(self, other): + if isinstance(other, Number): + other = other.get_number() + return self._check_number(other - self._number) + + def __rmul__(self, other): + if isinstance(other, Number): + other = other.get_number() + return self._check_number(other * self._number) + + def __rdiv__(self, other): + if isinstance(other, Number): + other = other.get_number() + return self._check_number(other / self._number) + + def __rtruediv__(self, other): + if isinstance(other, Number): + other = other.get_number() + return self.__rdiv__(other) + + def __rfloordiv__(self, other): + if isinstance(other, Number): + other = other.get_number() + return self._check_number(other // self._number) + + def __rmod__(self, other): + if isinstance(other, Number): + other = other.get_number() + return self._check_number(other % self._number) + + def __rdivmod__(self, other): + if isinstance(other, Number): + other = other.get_number() + return self._check_number(divmod(other, self._number)) + + def __rpow__(self, other): + if isinstance(other, Number): + other = other.get_number() + return self._check_number(pow(other, self._number)) + + def __rlshift__(self, other): + if isinstance(other, Number): + other = other.get_number() + return self._check_number(other << self._number) + + def __rrshift__(self, other): + if isinstance(other, Number): + other = other.get_number() + return self._check_number(other >> self._number) + + def __rand__(self, other): + if isinstance(other, Number): + other = other.get_number() + return self._check_number(other & self._number) + + def __rxor__(self, other): + if isinstance(other, Number): + other = other.get_number() + return self._check_number(other ^ self._number) + + def __ror__(self, other): + if isinstance(other, Number): + other = other.get_number() + return self._check_number(other | self._number) + + def __neg__(self): + return self._check_number(-self._number) + + def __pos__(self): + return self._check_number(+self._number) + + def __abs__(self): + return self._check_number(abs(self._number)) + + def __invert__(self): + return self._check_number(~self._number) + + def __complex__(self): + return complex(self._number) + + def __int__(self): + return int(self._number) + + def __long__(self): + return long(self._number) + + def __float__(self): + return float(self._number) + + def __oct__(self): + return oct(self._number) + + def __hex__(self): + return hex(self._number) + + def __round__(self, ndigits=None): + if ndigits is not None and isinstance(ndigits, Number): + ndigits = ndigits.get_number() + return round(self._number, ndigits) + + def __trunc__(self): + from math import trunc + return trunc(self._number) + + def __floor__(self): + from math import floor + return floor(self._number) + + def __ceil__(self): + from math import ceil + return ceil(self._number) + + def get_number(self): + return self._number + + def get_copy(self): + return self.__class__(self._number) + + +class _Int(Number): + def __init__(self, number=0, raise_exceptions=False): + if isinstance(number, Number): + number = number.get_number() + number = int(number) + Number.__init__(self, number, raise_exceptions) + + def _check_number(self, num, number_only=False): + if isinstance(num, Number): + num = num.get_number() + num = int(num) + return Number._check_number(self, num, number_only) + + +class Int32(_Int): + _min = INT32_MIN + _max = INT32_MAX + _bits = 32 + + +class Int64(_Int): + _min = INT64_MIN + _max = INT64_MAX + _bits = 64 + + +class UInt32(_Int): + _min = 0 + _max = UINT32_MAX + + +class UInt64(_Int): + _min = 0 + _max = UINT64_MAX diff --git a/discord_rpc/util/utils.py b/discord_rpc/util/utils.py new file mode 100644 index 0000000..8142596 --- /dev/null +++ b/discord_rpc/util/utils.py @@ -0,0 +1,180 @@ +from copy import deepcopy +import json +from os import getenv, getpid, path +import platform +from sys import version_info, argv + + +class Empty(Exception): + pass + + +class DummyQueue(object): + """ + Dummy queue thread that does nothing. Should only be used if imports fail. + """ + + def __init__(self, maxsize=0): + pass + + def qsize(self): + return 0 + + def empty(self): + return True + + def full(self): + return False + + def put(self, obj, *args, **kwargs): + pass + + def put_nowait(self, obj): + pass + + def get(self, *args, **kwargs): + raise Empty + + def get_nowait(self): + raise Empty + + def task_done(self): + pass + + def join(self): + pass + + +def is_python3(): + return version_info[0] == 3 + + +def is_windows(): + return platform.system() == 'Windows' + + +def is_linux(): + return platform.system() == 'Linux' + + +def is_mac_osx(): + # this may not be accurate, just going off of what I find off the internet + return platform.system() == 'Darwin' + + +def get_temp_path(): + if is_windows(): + return None + for val in ('XDG_RUNTIME_DIR', 'TMPDIR', 'TMP', 'TEMP'): + tmp = getenv(val) + if tmp is not None: + return tmp + return '/tmp' + + +def get_process_id(): + return getpid() + + +def is_callable(obj): + try: + # for Python 2.x or Python 3.2+ + return callable(obj) + except Exception: + # for Python version: 3 - 3.2 + return hasattr(obj, '__call__') + + +# python 2 + 3 compatibility +if is_python3(): + unicode = str + bytes = bytes +else: + bytes = str + unicode = unicode + + +def to_bytes(obj): + if isinstance(obj, type(b'')): + return obj + if hasattr(obj, 'encode') and is_callable(obj.encode): + return obj.encode('ascii', 'replace') + raise TypeError('Could not convert object type "{}" to bytes!'.format(type(obj))) + + +def to_unicode(obj): + if isinstance(obj, type(u'')): + return obj + if hasattr(obj, 'decode') and is_callable(obj.decode): + return obj.decode(encoding='utf-8') + raise TypeError('Could not convert object type "{}" to unicode!'.format(type(obj))) + + +def iter_keys(obj): + if not isinstance(obj, dict): + raise TypeError('Object must be of type dict!') + if is_python3(): + return obj.keys() + return obj.iterkeys() + + +def iter_items(obj): + if not isinstance(obj, dict): + raise TypeError('Object must be of type dict!') + if is_python3(): + return obj.items() + return obj.iteritems() + + +def iter_values(obj): + if not isinstance(obj, dict): + raise TypeError('Object must be of type dict!') + if is_python3(): + return obj.values() + return obj.itervalues() + + +def _py_dict(obj): + if not isinstance(obj, dict): + raise TypeError('Object must be of type dict!') + new_dict = dict() + for name, val in iter_items(obj): + if isinstance(name, type(b'')) and is_python3(): + name = to_unicode(name) + elif isinstance(name, type(u'')) and not is_python3(): + name = to_bytes(name) + if isinstance(val, dict): + val = _py_dict(val) + elif isinstance(val, type(b'')) and is_python3(): + val = to_unicode(val) + elif isinstance(val, type(u'')) and not is_python3(): + val = to_bytes(val) + new_dict[name] = val + return deepcopy(new_dict) + + +def json2dict(obj): + if isinstance(obj, dict): + return deepcopy(_py_dict(obj)) + if obj is None: + return dict() + if hasattr(obj, 'strip'): + if obj.strip() == '': + return dict() + else: + return deepcopy(_py_dict(deepcopy(json.loads(obj)))) + raise TypeError('Object must be of string type!') + + +if not is_python3(): + range = xrange +else: + range = range + + +def get_executable_directory(): + return path.abspath(path.dirname(argv[0])) + + +def get_executable_path(): + return path.join(get_executable_directory(), argv[0]) |