mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-08-14 02:26:58 -07:00
Add Imgur rate limiting
This commit is contained in:
parent
dec5931fd4
commit
80df2b0fad
4 changed files with 105 additions and 6 deletions
59
lib/ratelimit/__init__.py
Normal file
59
lib/ratelimit/__init__.py
Normal file
|
@ -0,0 +1,59 @@
|
|||
from math import floor
|
||||
|
||||
import time
|
||||
import sys
|
||||
import threading
|
||||
import functools
|
||||
|
||||
|
||||
def clamp(value):
|
||||
'''
|
||||
Clamp integer between 1 and max
|
||||
|
||||
There must be at least 1 method invocation
|
||||
made over the time period. Make sure the
|
||||
value passed is at least 1 and is not a
|
||||
fraction of an invocation.
|
||||
|
||||
:param float value: The number of method invocations.
|
||||
:return: Clamped number of invocations.
|
||||
:rtype: int
|
||||
'''
|
||||
return max(1, min(sys.maxsize, floor(value)))
|
||||
|
||||
|
||||
class RateLimitDecorator:
|
||||
def __init__(self, period=1, every=1.0):
|
||||
self.frequency = abs(every) / float(clamp(period))
|
||||
self.last_called = 0.0
|
||||
self.lock = threading.RLock()
|
||||
|
||||
def __call__(self, func):
|
||||
'''
|
||||
Extend the behaviour of the following
|
||||
function, forwarding method invocations
|
||||
if the time window hes elapsed.
|
||||
|
||||
:param function func: The function to decorate.
|
||||
:return: Decorated function.
|
||||
:rtype: function
|
||||
'''
|
||||
@functools.wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
'''Decorator wrapper function'''
|
||||
with self.lock:
|
||||
elapsed = time.time() - self.last_called
|
||||
left_to_wait = self.frequency - elapsed
|
||||
if left_to_wait > 0:
|
||||
time.sleep(left_to_wait)
|
||||
self.last_called = time.time()
|
||||
return func(*args, **kwargs)
|
||||
return wrapper
|
||||
|
||||
|
||||
rate_limited = RateLimitDecorator
|
||||
|
||||
|
||||
__all__ = [
|
||||
'rate_limited'
|
||||
]
|
9
lib/ratelimit/version.py
Normal file
9
lib/ratelimit/version.py
Normal file
|
@ -0,0 +1,9 @@
|
|||
class Version(object):
|
||||
'''Version of the package'''
|
||||
|
||||
def __setattr__(self, *args):
|
||||
raise TypeError('cannot modify immutable instance')
|
||||
__delattr__ = __setattr__
|
||||
|
||||
def __init__(self, num):
|
||||
super(Version, self).__setattr__('number', num)
|
Loading…
Add table
Add a link
Reference in a new issue