forked from CGM_Public/pretix_original
Python 3 style type hinting
This commit is contained in:
@@ -3,6 +3,8 @@ import hashlib
|
|||||||
|
|
||||||
from django.core.cache import caches
|
from django.core.cache import caches
|
||||||
|
|
||||||
|
from tixlbase.models import Event
|
||||||
|
|
||||||
|
|
||||||
class EventRelatedCache:
|
class EventRelatedCache:
|
||||||
"""
|
"""
|
||||||
@@ -17,12 +19,12 @@ class EventRelatedCache:
|
|||||||
instantiate it as many times as you want.
|
instantiate it as many times as you want.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, event, cache='default'):
|
def __init__(self, event: Event, cache: str='default'):
|
||||||
self.cache = caches[cache]
|
self.cache = caches[cache]
|
||||||
self.event = event
|
self.event = event
|
||||||
self.prefixkey = 'event:%d' % self.event.pk
|
self.prefixkey = 'event:%d' % self.event.pk
|
||||||
|
|
||||||
def _prefix_key(self, original_key):
|
def _prefix_key(self, original_key: str) -> str:
|
||||||
# Race conditions can happen here, but should be very very rare.
|
# Race conditions can happen here, but should be very very rare.
|
||||||
# We could only handle this by going _really_ lowlevel using
|
# We could only handle this by going _really_ lowlevel using
|
||||||
# memcached's `add` keyword instead of `set`.
|
# memcached's `add` keyword instead of `set`.
|
||||||
@@ -39,7 +41,7 @@ class EventRelatedCache:
|
|||||||
return key
|
return key
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _strip_prefix(key):
|
def _strip_prefix(key: str) -> str:
|
||||||
return key.split(":", 3)[-1] if 'event:' in key else key
|
return key.split(":", 3)[-1] if 'event:' in key else key
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
@@ -49,35 +51,35 @@ class EventRelatedCache:
|
|||||||
prefix = int(time.time())
|
prefix = int(time.time())
|
||||||
self.cache.set(self.prefixkey, prefix)
|
self.cache.set(self.prefixkey, prefix)
|
||||||
|
|
||||||
def set(self, key, value, timeout=3600):
|
def set(self, key: str, value: str, timeout: int=3600):
|
||||||
return self.cache.set(self._prefix_key(key), value, timeout)
|
return self.cache.set(self._prefix_key(key), value, timeout)
|
||||||
|
|
||||||
def get(self, key):
|
def get(self, key: str) -> str:
|
||||||
return self.cache.get(self._prefix_key(key))
|
return self.cache.get(self._prefix_key(key))
|
||||||
|
|
||||||
def get_many(self, keys):
|
def get_many(self, keys: "list[str]") -> "dict[str, str]":
|
||||||
values = self.cache.get_many([self._prefix_key(key) for key in keys])
|
values = self.cache.get_many([self._prefix_key(key) for key in keys])
|
||||||
newvalues = {}
|
newvalues = {}
|
||||||
for k, v in values.items():
|
for k, v in values.items():
|
||||||
newvalues[self._strip_prefix(k)] = v
|
newvalues[self._strip_prefix(k)] = v
|
||||||
return newvalues
|
return newvalues
|
||||||
|
|
||||||
def set_many(self, values, timeout=3600):
|
def set_many(self, values: "dict[str, str]", timeout=3600):
|
||||||
newvalues = {}
|
newvalues = {}
|
||||||
for k, v in values.items():
|
for k, v in values.items():
|
||||||
newvalues[self._prefix_key(k)] = v
|
newvalues[self._prefix_key(k)] = v
|
||||||
return self.cache.set_many(newvalues, timeout)
|
return self.cache.set_many(newvalues, timeout)
|
||||||
|
|
||||||
def delete(self, key): # NOQA
|
def delete(self, key: str): # NOQA
|
||||||
return self.cache.delete(self._prefix_key(key))
|
return self.cache.delete(self._prefix_key(key))
|
||||||
|
|
||||||
def delete_many(self, keys): # NOQA
|
def delete_many(self, keys: "list[str]"): # NOQA
|
||||||
return self.cache.delete_many([self._prefix_key(key) for key in keys])
|
return self.cache.delete_many([self._prefix_key(key) for key in keys])
|
||||||
|
|
||||||
def incr(self, key, by=1): # NOQA
|
def incr(self, key: str, by: int=1): # NOQA
|
||||||
return self.cache.incr(self._prefix_key(key), by)
|
return self.cache.incr(self._prefix_key(key), by)
|
||||||
|
|
||||||
def decr(self, key, by=1): # NOQA
|
def decr(self, key: str, by: int=1): # NOQA
|
||||||
return self.cache.decr(self._prefix_key(key), by)
|
return self.cache.decr(self._prefix_key(key), by)
|
||||||
|
|
||||||
def close(self): # NOQA
|
def close(self): # NOQA
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ class LocaleMiddleware(BaseLocaleMiddleware):
|
|||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
def get_language_from_request(request):
|
def get_language_from_request(request) -> str:
|
||||||
"""
|
"""
|
||||||
Analyzes the request to find what language the user wants the system to
|
Analyzes the request to find what language the user wants the system to
|
||||||
show. Only languages listed in settings.LANGUAGES are taken into account.
|
show. Only languages listed in settings.LANGUAGES are taken into account.
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ class User(AbstractBaseUser, PermissionsMixin):
|
|||||||
self.identifier = self.identifier.lower()
|
self.identifier = self.identifier.lower()
|
||||||
super().save(*args, **kwargs)
|
super().save(*args, **kwargs)
|
||||||
|
|
||||||
def get_short_name(self):
|
def get_short_name(self) -> str:
|
||||||
if self.givenname:
|
if self.givenname:
|
||||||
return self.givenname
|
return self.givenname
|
||||||
elif self.familyname:
|
elif self.familyname:
|
||||||
@@ -127,7 +127,7 @@ class User(AbstractBaseUser, PermissionsMixin):
|
|||||||
else:
|
else:
|
||||||
return self.username
|
return self.username
|
||||||
|
|
||||||
def get_full_name(self):
|
def get_full_name(self) -> str:
|
||||||
if self.givenname and not self.familyname:
|
if self.givenname and not self.familyname:
|
||||||
return self.givenname
|
return self.givenname
|
||||||
elif not self.givenname and self.familyname:
|
elif not self.givenname and self.familyname:
|
||||||
@@ -295,18 +295,18 @@ class Event(models.Model):
|
|||||||
self.get_cache().clear()
|
self.get_cache().clear()
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
def get_plugins(self):
|
def get_plugins(self) -> "list[str]":
|
||||||
if self.plugins is None:
|
if self.plugins is None:
|
||||||
return []
|
return []
|
||||||
return self.plugins.split(",")
|
return self.plugins.split(",")
|
||||||
|
|
||||||
def get_date_from_display(self):
|
def get_date_from_display(self) -> str:
|
||||||
return _date(
|
return _date(
|
||||||
self.date_from,
|
self.date_from,
|
||||||
"DATETIME_FORMAT" if self.show_times else "DATE_FORMAT"
|
"DATETIME_FORMAT" if self.show_times else "DATE_FORMAT"
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_date_to_display(self):
|
def get_date_to_display(self) -> str:
|
||||||
if not self.show_date_to:
|
if not self.show_date_to:
|
||||||
return ""
|
return ""
|
||||||
return _date(
|
return _date(
|
||||||
@@ -314,7 +314,7 @@ class Event(models.Model):
|
|||||||
"DATETIME_FORMAT" if self.show_times else "DATE_FORMAT"
|
"DATETIME_FORMAT" if self.show_times else "DATE_FORMAT"
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_cache(self):
|
def get_cache(self) -> "tixlbase.cache.EventRelatedCache":
|
||||||
from tixlbase.cache import EventRelatedCache
|
from tixlbase.cache import EventRelatedCache
|
||||||
return EventRelatedCache(self)
|
return EventRelatedCache(self)
|
||||||
|
|
||||||
@@ -579,7 +579,7 @@ class Item(models.Model):
|
|||||||
self.active = False
|
self.active = False
|
||||||
return super().save()
|
return super().save()
|
||||||
|
|
||||||
def get_all_variations(self, use_cache=False):
|
def get_all_variations(self, use_cache: bool=False) -> "list[VariationDict]":
|
||||||
"""
|
"""
|
||||||
This method returns a list containing all variations of this
|
This method returns a list containing all variations of this
|
||||||
item. The list contains one VariationDict per variation, where
|
item. The list contains one VariationDict per variation, where
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ class PluginType(Enum):
|
|||||||
RESTRICTION = 1
|
RESTRICTION = 1
|
||||||
|
|
||||||
|
|
||||||
def get_all_plugins():
|
def get_all_plugins() -> "class":
|
||||||
plugins = []
|
plugins = []
|
||||||
for app in apps.get_app_configs():
|
for app in apps.get_app_configs():
|
||||||
if hasattr(app, 'TixlPluginMeta'):
|
if hasattr(app, 'TixlPluginMeta'):
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ RUN_LOCAL = ('SAUCE_USERNAME' not in os.environ)
|
|||||||
|
|
||||||
if RUN_LOCAL:
|
if RUN_LOCAL:
|
||||||
# could add Chrome, PhantomJS etc... here
|
# could add Chrome, PhantomJS etc... here
|
||||||
BROWSERS = ['Chrome']
|
BROWSERS = ['Chrome', 'Firefox']
|
||||||
else:
|
else:
|
||||||
from sauceclient import SauceClient
|
from sauceclient import SauceClient
|
||||||
USERNAME = os.environ.get('SAUCE_USERNAME')
|
USERNAME = os.environ.get('SAUCE_USERNAME')
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ class VariationDict(dict):
|
|||||||
code calling this method.
|
code calling this method.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def relevant_items(self):
|
def relevant_items(self) -> "list[(int, PropertyValue)]":
|
||||||
"""
|
"""
|
||||||
Iterate over all items with numeric keys.
|
Iterate over all items with numeric keys.
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@ class VariationDict(dict):
|
|||||||
if type(i[0]) is int:
|
if type(i[0]) is int:
|
||||||
yield i
|
yield i
|
||||||
|
|
||||||
def relevant_values(self):
|
def relevant_values(self) -> "list[PropertyValue]":
|
||||||
"""
|
"""
|
||||||
Iterate over all values with numeric keys.
|
Iterate over all values with numeric keys.
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ class VariationDict(dict):
|
|||||||
if type(i[0]) is int:
|
if type(i[0]) is int:
|
||||||
yield i[1]
|
yield i[1]
|
||||||
|
|
||||||
def identify(self):
|
def identify(self) -> str:
|
||||||
"""
|
"""
|
||||||
Build a simple and unique identifier for this dict. This can be any string
|
Build a simple and unique identifier for this dict. This can be any string
|
||||||
used to compare one VariationDict to others.
|
used to compare one VariationDict to others.
|
||||||
@@ -42,7 +42,7 @@ class VariationDict(dict):
|
|||||||
str(v[1].pk) for v in sorted(self.relevant_items(), key=order_key)
|
str(v[1].pk) for v in sorted(self.relevant_items(), key=order_key)
|
||||||
))
|
))
|
||||||
|
|
||||||
def key(self):
|
def key(self) -> str:
|
||||||
"""
|
"""
|
||||||
Build an identifier for this dict which exactly specifies the combination
|
Build an identifier for this dict which exactly specifies the combination
|
||||||
for this variation without any doubt. This can be used to "talk" about a
|
for this variation without any doubt. This can be used to "talk" about a
|
||||||
@@ -62,7 +62,7 @@ class VariationDict(dict):
|
|||||||
else:
|
else:
|
||||||
return super().__eq__(other)
|
return super().__eq__(other)
|
||||||
|
|
||||||
def ordered_values(self):
|
def ordered_values(self) -> "list[ItemVariation]":
|
||||||
"""
|
"""
|
||||||
Returns a list of values ordered by their keys
|
Returns a list of values ordered by their keys
|
||||||
"""
|
"""
|
||||||
@@ -74,7 +74,7 @@ class VariationDict(dict):
|
|||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
def copy(self):
|
def copy(self) -> "VariationDict":
|
||||||
"""
|
"""
|
||||||
Return a one-level deep copy of this object (create a new
|
Return a one-level deep copy of this object (create a new
|
||||||
VariationDict but make a shallow copy of the dict inside it).
|
VariationDict but make a shallow copy of the dict inside it).
|
||||||
|
|||||||
@@ -22,6 +22,16 @@ class LoginFormBrowserTest(BrowserTest):
|
|||||||
self.driver.find_element_by_css_selector('button[type="submit"]').click()
|
self.driver.find_element_by_css_selector('button[type="submit"]').click()
|
||||||
self.driver.find_element_by_class_name("navbar-right")
|
self.driver.find_element_by_class_name("navbar-right")
|
||||||
|
|
||||||
|
def test_login_fail(self):
|
||||||
|
self.driver.implicitly_wait(10)
|
||||||
|
self.driver.get('%s%s' % (self.live_server_url, '/control/login'))
|
||||||
|
username_input = self.driver.find_element_by_name("email")
|
||||||
|
username_input.send_keys('dummy@dummy.dummy')
|
||||||
|
password_input = self.driver.find_element_by_name("password")
|
||||||
|
password_input.send_keys('wrong')
|
||||||
|
self.driver.find_element_by_css_selector('button[type="submit"]').click()
|
||||||
|
self.driver.find_element_by_class_name("alert-danger")
|
||||||
|
|
||||||
|
|
||||||
class LoginFormTest(TestCase):
|
class LoginFormTest(TestCase):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -52,10 +52,10 @@ class EventUpdate(EventPermissionRequiredMixin, UpdateView):
|
|||||||
template_name = 'tixlcontrol/event/settings.html'
|
template_name = 'tixlcontrol/event/settings.html'
|
||||||
permission = 'can_change_settings'
|
permission = 'can_change_settings'
|
||||||
|
|
||||||
def get_object(self, queryset=None):
|
def get_object(self, queryset=None) -> Event:
|
||||||
return self.request.event
|
return self.request.event
|
||||||
|
|
||||||
def get_success_url(self):
|
def get_success_url(self) -> str:
|
||||||
return reverse('control:event.settings', kwargs={
|
return reverse('control:event.settings', kwargs={
|
||||||
'organizer': self.get_object().organizer.slug,
|
'organizer': self.get_object().organizer.slug,
|
||||||
'event': self.get_object().slug,
|
'event': self.get_object().slug,
|
||||||
@@ -72,7 +72,7 @@ class EventPlugins(EventPermissionRequiredMixin, TemplateView, SingleObjectMixin
|
|||||||
def get_object(self, queryset=None):
|
def get_object(self, queryset=None):
|
||||||
return self.request.event
|
return self.request.event
|
||||||
|
|
||||||
def get_context_data(self, *args, **kwargs):
|
def get_context_data(self, *args, **kwargs) -> dict:
|
||||||
from tixlbase.plugins import get_all_plugins
|
from tixlbase.plugins import get_all_plugins
|
||||||
context = super().get_context_data(*args, **kwargs)
|
context = super().get_context_data(*args, **kwargs)
|
||||||
context['plugins'] = [p for p in get_all_plugins() if not p.name.startswith('.')]
|
context['plugins'] = [p for p in get_all_plugins() if not p.name.startswith('.')]
|
||||||
@@ -98,7 +98,7 @@ class EventPlugins(EventPermissionRequiredMixin, TemplateView, SingleObjectMixin
|
|||||||
self.object.save()
|
self.object.save()
|
||||||
return redirect(self.get_success_url())
|
return redirect(self.get_success_url())
|
||||||
|
|
||||||
def get_success_url(self):
|
def get_success_url(self) -> str:
|
||||||
return reverse('control:event.settings.plugins', kwargs={
|
return reverse('control:event.settings.plugins', kwargs={
|
||||||
'organizer': self.get_object().organizer.slug,
|
'organizer': self.get_object().organizer.slug,
|
||||||
'event': self.get_object().slug,
|
'event': self.get_object().slug,
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ from tixlbase.models import ItemVariation, PropertyValue, Item
|
|||||||
|
|
||||||
|
|
||||||
class TolerantFormsetModelForm(forms.ModelForm):
|
class TolerantFormsetModelForm(forms.ModelForm):
|
||||||
def has_changed(self):
|
def has_changed(self) -> bool:
|
||||||
"""
|
"""
|
||||||
Returns True if data differs from initial. Contrary to the default
|
Returns True if data differs from initial. Contrary to the default
|
||||||
implementation, the ORDER field is being ignored.
|
implementation, the ORDER field is being ignored.
|
||||||
@@ -231,11 +231,11 @@ class VariationsField(forms.ModelMultipleChoiceField):
|
|||||||
kwargs['widget'] = VariationsSelectMultiple
|
kwargs['widget'] = VariationsSelectMultiple
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
def set_item(self, item):
|
def set_item(self, item: Item):
|
||||||
self.item = item
|
self.item = item
|
||||||
self._set_choices(self._get_choices())
|
self._set_choices(self._get_choices())
|
||||||
|
|
||||||
def _get_choices(self):
|
def _get_choices(self) -> "list[(str, VariationDict)]":
|
||||||
"""
|
"""
|
||||||
We can't use a normal QuerySet as there theoretically might be
|
We can't use a normal QuerySet as there theoretically might be
|
||||||
two types of variations: Some who already have a ItemVariation
|
two types of variations: Some who already have a ItemVariation
|
||||||
@@ -255,7 +255,7 @@ class VariationsField(forms.ModelMultipleChoiceField):
|
|||||||
) for v in variations
|
) for v in variations
|
||||||
)
|
)
|
||||||
|
|
||||||
def clean(self, value):
|
def clean(self, value: "list[int]"):
|
||||||
"""
|
"""
|
||||||
At cleaning time, we have to clean up the mess we produced with our
|
At cleaning time, we have to clean up the mess we produced with our
|
||||||
_get_choices implementation. In the case of ItemVariation object ids
|
_get_choices implementation. In the case of ItemVariation object ids
|
||||||
|
|||||||
Reference in New Issue
Block a user