Dalai Felinto
1de4f84144
URL: /api/v1/extensions/<extension_id>/versions/new/ Method: POST Parameters: * version_file * release_notes Ref: !138 Reviewed-by: Oleg-Komarov
124 lines
4.0 KiB
Python
124 lines
4.0 KiB
Python
import itertools
|
|
from typing import Tuple
|
|
|
|
import django.urls as urls
|
|
from django.utils.functional import cached_property
|
|
from django.utils.regex_helper import normalize
|
|
|
|
from apitokens.models import UserToken
|
|
|
|
|
|
try: # Django 2.0
|
|
url_resolver_types = (urls.URLResolver,)
|
|
DJANGO_2 = True
|
|
except AttributeError: # Django 1.11
|
|
url_resolver_types = (urls.RegexURLResolver,)
|
|
DJANGO_2 = False
|
|
|
|
|
|
class URLEntry:
|
|
def __init__(self, url_bits):
|
|
self.bits = url_bits[:]
|
|
self.name = url_bits[-1].name
|
|
|
|
def normalize(self):
|
|
return normalize(self.merged_pattern)
|
|
|
|
@cached_property
|
|
def namespace(self):
|
|
return getattr(self.bits[0], 'namespace', None)
|
|
|
|
@cached_property
|
|
def qualified_name(self):
|
|
if self.name and self.namespace:
|
|
return '{namespace}:{name}'.format(namespace=self.namespace, name=self.name)
|
|
return self.name
|
|
|
|
@cached_property
|
|
def regexes(self):
|
|
if DJANGO_2:
|
|
return [bit.pattern.regex for bit in self.bits]
|
|
else:
|
|
return [bit.regex for bit in self.bits]
|
|
|
|
@cached_property
|
|
def merged_pattern(self):
|
|
return ''.join(re.pattern.lstrip('^').rstrip('$') for re in self.regexes)
|
|
|
|
@cached_property
|
|
def named_groups(self):
|
|
keys = (re.groupindex.keys() for re in self.regexes)
|
|
return set(itertools.chain(*keys))
|
|
|
|
@cached_property
|
|
def group_count(self):
|
|
return sum(re.groups for re in self.regexes)
|
|
|
|
|
|
def _extract_urls(urlpatterns, parents):
|
|
for pattern in urlpatterns:
|
|
path = parents[:] + [pattern]
|
|
if isinstance(pattern, url_resolver_types):
|
|
yield from _extract_urls(pattern.url_patterns, path)
|
|
else:
|
|
yield URLEntry(path)
|
|
|
|
|
|
def extract_urls(urlpatterns=None):
|
|
"""Extract URLEntry objects from the given iterable of Django URL pattern objects.
|
|
|
|
If no iterable is given, the patterns exposed by the root resolver are used, i.e.
|
|
all of the URLs routed in the project.
|
|
:param urlpatterns: Iterable of URLPattern objects
|
|
:return: Generator of `URLEntry` objects.
|
|
:rtype: list[URLEntry]
|
|
"""
|
|
if urlpatterns is None:
|
|
urlpatterns = urls.get_resolver(None).url_patterns
|
|
yield from _extract_urls(urlpatterns, [])
|
|
|
|
|
|
def _get_all_form_errors(response):
|
|
return (
|
|
{
|
|
key: [
|
|
response.context[key].errors,
|
|
getattr(response.context[key], 'non_form_errors', lambda: None)(),
|
|
]
|
|
for key in response.context.keys()
|
|
if key.endswith('_formset') or key == 'form' or key.endswith('_form')
|
|
}
|
|
if response.context
|
|
else None
|
|
)
|
|
|
|
|
|
class CheckFilePropertiesMixin:
|
|
def _test_file_properties(self, file, **kwargs):
|
|
if 'content_type' in kwargs:
|
|
self.assertEqual(file.content_type, kwargs.get('content_type'))
|
|
if 'get_status_display' in kwargs:
|
|
self.assertEqual(file.get_status_display(), kwargs.get('get_status_display'))
|
|
if 'get_type_display' in kwargs:
|
|
self.assertEqual(file.get_type_display(), kwargs.get('get_type_display'))
|
|
if 'hash' in kwargs:
|
|
self.assertTrue(file.hash.startswith(kwargs.get('hash')), file.hash)
|
|
if 'name' in kwargs:
|
|
self.assertTrue(file.source.name.startswith(kwargs.get('name')), file.source.name)
|
|
if 'original_hash' in kwargs:
|
|
self.assertTrue(
|
|
file.original_hash.startswith(kwargs.get('original_hash')), file.original_hash
|
|
)
|
|
if 'original_name' in kwargs:
|
|
self.assertEqual(file.original_name, kwargs.get('original_name'))
|
|
if 'size_bytes' in kwargs:
|
|
self.assertEqual(file.size_bytes, kwargs.get('size_bytes'))
|
|
|
|
|
|
def create_user_token(*args, **kwargs) -> Tuple['UserToken', str]:
|
|
token_key = UserToken.generate_token_key()
|
|
kwargs['token_hash'] = UserToken.generate_hash(token_key)
|
|
kwargs['token_prefix'] = UserToken.generate_token_prefix(token_key)
|
|
token = UserToken.objects.create(*args, **kwargs)
|
|
return token, token_key
|