diff --git a/beat/web/toolchains/admin.py b/beat/web/toolchains/admin.py index 16ce3f8a2e8579f6a249bcb60057fa1b4071ce98..e86fe4d407245a48a57850c69feb7b5ad3150c1d 100644 --- a/beat/web/toolchains/admin.py +++ b/beat/web/toolchains/admin.py @@ -29,60 +29,50 @@ from django import forms from django.contrib import admin from django.core.files.base import ContentFile - -from .models import Toolchain as ToolchainModel - -from ..ui.forms import CodeMirrorJSONFileField, CodeMirrorRSTFileField, \ - NameField - from ..common.texts import Messages +from ..ui.forms import CodeMirrorJSONFileField +from ..ui.forms import CodeMirrorRSTFileField +from ..ui.forms import NameField +from .models import Toolchain as ToolchainModel - -#---------------------------------------------------------- +# ---------------------------------------------------------- class ToolchainModelForm(forms.ModelForm): name = NameField( - widget=forms.TextInput(attrs=dict(size=80)), - help_text=Messages['name'], + widget=forms.TextInput(attrs=dict(size=80)), help_text=Messages["name"], ) declaration_file = CodeMirrorJSONFileField( - label='Declaration', - help_text=Messages['json'], + label="Declaration", help_text=Messages["json"], ) description_file = CodeMirrorRSTFileField( - label='Description', + label="Description", required=False, allow_empty_file=True, - help_text=Messages['description'], + help_text=Messages["description"], ) class Meta: model = ToolchainModel exclude = [] widgets = { - 'short_description': forms.TextInput( - attrs=dict(size=100), - ), - 'errors': forms.Textarea( - attrs=dict(readonly=1,cols=150,), - ), + "short_description": forms.TextInput(attrs=dict(size=100),), + "errors": forms.Textarea(attrs=dict(readonly=1, cols=150,),), } - def clean_declaration(self): """Cleans-up the file data, make sure it is really new""" - new_declaration = self.cleaned_data['declaration_file'].read() - old_declaration = '' + new_declaration = self.cleaned_data["declaration_file"].read() + old_declaration = "" if self.instance and self.instance.declaration_file.name is not None: old_declaration = self.instance.declaration_string if new_declaration == old_declaration: - self.changed_data.remove('declaration_file') + self.changed_data.remove("declaration_file") content_file = ContentFile(old_declaration) content_file.name = self.instance.declaration_file.name return content_file @@ -90,55 +80,61 @@ class ToolchainModelForm(forms.ModelForm): # we don't validate toolchains - they should be saved in any state # if that works out, then we return the passed file - self.cleaned_data['declaration_file'].seek(0) #reset ContentFile readout - return self.cleaned_data['declaration_file'] - + self.cleaned_data["declaration_file"].seek(0) # reset ContentFile readout + return self.cleaned_data["declaration_file"] def clean(self): """Cleans-up the input data, make sure it overall validates""" # make sure we don't pass back a str field as 'file' - if 'declaration_file' in self.data and \ - isinstance(self.data['declaration_file'], str): + if "declaration_file" in self.data and isinstance( + self.data["declaration_file"], str + ): mutable_data = self.data.copy() - mutable_data['declaration_file'] = ContentFile(self.data['declaration_file'], name='unsaved') + mutable_data["declaration_file"] = ContentFile( + self.data["declaration_file"], name="unsaved" + ) self.data = mutable_data -#---------------------------------------------------------- +# ---------------------------------------------------------- def rehash_toolchain(modeladmin, request, queryset): """Recalculates the hash of an toolchain""" - for q in queryset: q.save() + for q in queryset: + q.save() + -rehash_toolchain.short_description = 'Rehash selected toolchains' +rehash_toolchain.short_description = "Rehash selected toolchains" class Toolchain(admin.ModelAdmin): - list_display = ('id', - 'author', - 'name', - 'version', - 'short_description', - 'creation_date', - 'hash', - 'previous_version', - 'fork_of', - 'sharing', - ) - search_fields = ['author__username', - 'name', - 'short_description', - 'previous_version__author__username', - 'previous_version__name', - 'fork_of__name' - ] - list_display_links = ('id', 'name') - list_filter = ('sharing', ) - readonly_fields = ('hash', 'errors', 'short_description') + list_display = ( + "id", + "author", + "name", + "version", + "short_description", + "creation_date", + "hash", + "previous_version", + "fork_of", + "sharing", + ) + search_fields = [ + "author__username", + "name", + "short_description", + "previous_version__author__username", + "previous_version__name", + "fork_of__name", + ] + list_display_links = ("id", "name") + list_filter = ("sharing",) + readonly_fields = ("hash", "errors", "short_description") actions = [ rehash_toolchain, @@ -146,40 +142,32 @@ class Toolchain(admin.ModelAdmin): form = ToolchainModelForm - filter_horizontal = [ - 'shared_with', - 'shared_with_team' - ] + filter_horizontal = ["shared_with", "shared_with_team"] fieldsets = ( - (None, - dict( - fields=('name', 'author'), - ), - ), - ('Documentation', - dict( - classes=('collapse',), - fields=('short_description', 'description_file'), - ), - ), - ('Versioning', - dict( - classes=('collapse',), - fields=('version', 'previous_version', 'fork_of'), - ), - ), - ('Sharing', - dict( - classes=('collapse',), - fields=('sharing', 'shared_with', 'shared_with_team'), - ), - ), - ('Source code', - dict( - fields=('hash', 'declaration_file', 'errors'), - ), - ), + (None, dict(fields=("name", "author"),),), + ( + "Documentation", + dict( + classes=("collapse",), fields=("short_description", "description_file"), + ), + ), + ( + "Versioning", + dict( + classes=("collapse",), + fields=("version", "previous_version", "fork_of"), + ), + ), + ( + "Sharing", + dict( + classes=("collapse",), + fields=("sharing", "shared_with", "shared_with_team"), + ), + ), + ("Source code", dict(fields=("hash", "declaration_file", "errors"),),), ) + admin.site.register(ToolchainModel, Toolchain) diff --git a/beat/web/toolchains/api.py b/beat/web/toolchains/api.py index 1d861e1b985cb1f2649a73c4cf8c2ac1925dc2fe..08cf3ce036d0d8a1c09aedf5e0f46d76ac5be7c7 100644 --- a/beat/web/toolchains/api.py +++ b/beat/web/toolchains/api.py @@ -26,21 +26,16 @@ ############################################################################### -from ..common.api import ( - CheckContributionNameView, - ShareView, - ListCreateContributionView, - RetrieveUpdateDestroyContributionView, -) - +from ..common.api import CheckContributionNameView +from ..common.api import ListContributionView +from ..common.api import ListCreateContributionView +from ..common.api import RetrieveUpdateDestroyContributionView +from ..common.api import ShareView from .models import Toolchain -from .serializers import ToolchainSerializer from .serializers import FullToolchainSerializer from .serializers import ToolchainCreationSerializer from .serializers import ToolchainModSerializer - -from ..common.api import ListContributionView - +from .serializers import ToolchainSerializer # ---------------------------------------------------------- diff --git a/beat/web/toolchains/apps.py b/beat/web/toolchains/apps.py index 623cb76300880209de6296c5899f4198facd10b7..d12d820560d207e5e129d085170051fc720b41d6 100644 --- a/beat/web/toolchains/apps.py +++ b/beat/web/toolchains/apps.py @@ -25,18 +25,21 @@ # # ############################################################################### -from ..common.apps import CommonAppConfig from django.utils.translation import ugettext_lazy as _ +from ..common.apps import CommonAppConfig + class ToolchainsConfig(CommonAppConfig): - name = 'beat.web.toolchains' - verbose_name = _('Toolchains') + name = "beat.web.toolchains" + verbose_name = _("Toolchains") def ready(self): super(ToolchainsConfig, self).ready() - from .signals import auto_delete_file_on_delete, auto_delete_file_on_change from actstream import registry - registry.register(self.get_model('Toolchain')) + from .signals import auto_delete_file_on_change # noqa: F401 + from .signals import auto_delete_file_on_delete # noqa: F401 + + registry.register(self.get_model("Toolchain")) diff --git a/beat/web/toolchains/models.py b/beat/web/toolchains/models.py index 41ea825bf9195df4b59e91a200ad42dd097b7d30..133672e1f854cbc1b01af6e7a8f2edc83e3172c3 100644 --- a/beat/web/toolchains/models.py +++ b/beat/web/toolchains/models.py @@ -26,7 +26,6 @@ ############################################################################### import simplejson - from django.conf import settings from django.db import models from django.urls import reverse @@ -41,8 +40,7 @@ from ..common.models import get_contribution_declaration_filename from ..common.models import get_contribution_description_filename from ..common.storage import OverwriteStorage - -#---------------------------------------------------------- +# ---------------------------------------------------------- def validate_toolchain(declaration): @@ -51,39 +49,49 @@ def validate_toolchain(declaration): toolchain = beat.core.toolchain.Toolchain(settings.PREFIX, declaration) if not toolchain.valid: - errors = 'The toolchain declaration is **invalid**. Errors:\n * ' + \ - '\n * '.join(toolchain.errors) + errors = ( + "The toolchain declaration is **invalid**. Errors:\n * " + + "\n * ".join(toolchain.errors) + ) raise SyntaxError(errors) return toolchain -#---------------------------------------------------------- +# ---------------------------------------------------------- class ToolchainStorage(OverwriteStorage): - def __init__(self, *args, **kwargs): - super(ToolchainStorage, self).__init__(*args, location=settings.TOOLCHAINS_ROOT, **kwargs) + super(ToolchainStorage, self).__init__( + *args, location=settings.TOOLCHAINS_ROOT, **kwargs + ) -#---------------------------------------------------------- +# ---------------------------------------------------------- class ToolchainManager(StoredContributionManager): - - def create_toolchain(self, author, name, short_description='', description='', - declaration=None, version=1, previous_version=None, - fork_of=None): + def create_toolchain( + self, + author, + name, + short_description="", + description="", + declaration=None, + version=1, + previous_version=None, + fork_of=None, + ): # Create the database representation of the toolchain toolchain = self.model( - author = author, - name = self.model.sanitize_name(name), - version = version, - sharing = self.model.PRIVATE, - previous_version = previous_version, - fork_of = fork_of, + author=author, + name=self.model.sanitize_name(name), + version=version, + sharing=self.model.PRIVATE, + previous_version=previous_version, + fork_of=fork_of, ) # Check the provided declaration @@ -95,11 +103,11 @@ class ToolchainManager(StoredContributionManager): else: tc = beat.core.toolchain.Toolchain(settings.PREFIX, data=None) declaration = tc.data - elif not(isinstance(declaration, dict)): + elif not (isinstance(declaration, dict)): declaration = simplejson.loads(declaration) if len(short_description) > 0: - declaration['description'] = short_description + declaration["description"] = short_description toolchain.declaration = declaration @@ -116,18 +124,18 @@ class ToolchainManager(StoredContributionManager): toolchain.save() if toolchain.errors: - toolchain.delete() # undo saving to respect current API + toolchain.delete() # undo saving to respect current API return (None, toolchain.errors) return (toolchain, None) -#---------------------------------------------------------- +# ---------------------------------------------------------- class Toolchain(StoredContribution): - #_____ Constants _______ + # _____ Constants _______ DEFAULT_TOOLCHAIN_TEXT = """\ { "blocks": [], @@ -137,68 +145,68 @@ class Toolchain(StoredContribution): } """ - #_____ Fields __________ - - declaration_file = models.FileField(storage=ToolchainStorage(), - upload_to=get_contribution_declaration_filename, - blank=True, null=True, - max_length=200, - db_column='declaration' - ) - - description_file = models.FileField(storage=ToolchainStorage(), - upload_to=get_contribution_description_filename, - blank=True, null=True, - max_length=200, - db_column='description' - ) + # _____ Fields __________ + + declaration_file = models.FileField( + storage=ToolchainStorage(), + upload_to=get_contribution_declaration_filename, + blank=True, + null=True, + max_length=200, + db_column="declaration", + ) + + description_file = models.FileField( + storage=ToolchainStorage(), + upload_to=get_contribution_description_filename, + blank=True, + null=True, + max_length=200, + db_column="description", + ) # read-only parameters that are updated at every save(), if required - errors = models.TextField(blank=True, null=True, - help_text="Errors detected while validating the toolchain. Automatically set by the platform.") - + errors = models.TextField( + blank=True, + null=True, + help_text="Errors detected while validating the toolchain. Automatically set by the platform.", + ) objects = ToolchainManager() - - #_____ Utilities __________ + # _____ Utilities __________ def get_absolute_url(self): return reverse( - 'toolchains:view', - args=(self.author.username, self.name, self.version,), + "toolchains:view", args=(self.author.username, self.name, self.version,), ) - def get_api_update_url(self): - '''Returns the endpoint to update this object''' + """Returns the endpoint to update this object""" return reverse( - 'api_toolchains:object', - args=(self.author.username, self.name, self.version,), + "api_toolchains:object", + args=(self.author.username, self.name, self.version,), ) - def get_api_share_url(self): - '''Returns the endpoint to share this object''' + """Returns the endpoint to share this object""" return reverse( - 'api_toolchains:share', - args=(self.author.username, self.name, self.version,), + "api_toolchains:share", + args=(self.author.username, self.name, self.version,), ) - def get_new_experiment_url(self): - '''Returns the view to create a new experiment from self''' + """Returns the view to create a new experiment from self""" return reverse( - 'experiments:new-from-toolchain', - args=(self.author.username, self.name, self.version,), + "experiments:new-from-toolchain", + args=(self.author.username, self.name, self.version,), ) - - #_____ Overrides __________ + # _____ Overrides __________ def save(self, *args, **kwargs): @@ -206,20 +214,24 @@ class Toolchain(StoredContribution): declaration = self.declaration # Compute the hash of the content - content_hash = beat.core.hash.hashJSON(declaration, 'description') - content_modified = (content_hash != self.hash) + content_hash = beat.core.hash.hashJSON(declaration, "description") + content_modified = content_hash != self.hash if content_modified: # toolchains can be saved even if they are not valid... wrapper = None - errors = '' + errors = "" try: wrapper = validate_toolchain(declaration) except Exception as e: errors = str(e) self.hash = content_hash - self.short_description = wrapper.description if (wrapper is not None) and (wrapper.description is not None) else '' + self.short_description = ( + wrapper.description + if (wrapper is not None) and (wrapper.description is not None) + else "" + ) # Store the errors (if applicable) if errors is not None and not errors.strip(): @@ -227,7 +239,7 @@ class Toolchain(StoredContribution): else: self.errors = errors else: - self.short_description = declaration.get('description', '') + self.short_description = declaration.get("description", "") # Ensures that the sharing informations are consistent if self.sharing == Contribution.USABLE: @@ -236,11 +248,10 @@ class Toolchain(StoredContribution): # Invoke the base implementation super(Toolchain, self).save(*args, **kwargs) - - #_____ Methods __________ + # _____ Methods __________ def is_valid(self): - return (self.errors is None) + return self.errors is None def modifiable(self): return (self.experiments.count() == 0) and super(Toolchain, self).modifiable() diff --git a/beat/web/toolchains/serializers.py b/beat/web/toolchains/serializers.py index 247cf1399c24672be7e1e9508ece03a6c1d76531..676bc510215083fcc466b92b7ab1ae6bf7d4f598 100644 --- a/beat/web/toolchains/serializers.py +++ b/beat/web/toolchains/serializers.py @@ -27,19 +27,15 @@ from rest_framework import serializers -from ..common.serializers import ( - ContributionSerializer, - ContributionCreationSerializer, - ContributionModSerializer, -) +import beat.core.toolchain + from ..attestations.serializers import AttestationSerializer +from ..common.serializers import ContributionCreationSerializer +from ..common.serializers import ContributionModSerializer +from ..common.serializers import ContributionSerializer from ..experiments.serializers import ExperimentSerializer - from .models import Toolchain -import beat.core.toolchain - - # ---------------------------------------------------------- diff --git a/beat/web/toolchains/signals.py b/beat/web/toolchains/signals.py index c2dbe242293454a281100fe583d96d80cbbc6f1e..1deef398c12d60ab7e2d049fe31eec49f9041c22 100644 --- a/beat/web/toolchains/signals.py +++ b/beat/web/toolchains/signals.py @@ -30,8 +30,7 @@ from django.dispatch import receiver from .models import Toolchain - -#---------------------------------------------------------- +# ---------------------------------------------------------- # These two auto-delete files from filesystem when they are unneeded: @@ -46,7 +45,7 @@ def auto_delete_file_on_delete(sender, instance, **kwargs): instance.description_file.delete(save=False) -#---------------------------------------------------------- +# ---------------------------------------------------------- @receiver(models.signals.pre_save, sender=Toolchain) diff --git a/beat/web/toolchains/views.py b/beat/web/toolchains/views.py index 94e34d1b6c0f995ff894f125af35c76716b9ced6..5c8ee39b792cf560c03a0ef3eca456aa2b72d588 100644 --- a/beat/web/toolchains/views.py +++ b/beat/web/toolchains/views.py @@ -25,25 +25,22 @@ # # ############################################################################### +import simplejson as json +from django.conf import settings +from django.contrib.auth.decorators import login_required +from django.contrib.auth.models import User from django.http import Http404 from django.shortcuts import get_object_or_404 from django.shortcuts import render -from django.contrib.auth.decorators import login_required -from django.conf import settings -from django.contrib.auth.models import User -from django.db.models.functions import Coalesce +from beat.core import prototypes -from .models import Toolchain -from ..team.models import Team -from ..reports.models import Report from ..common.texts import Messages from ..common.utils import ensure_string +from ..reports.models import Report +from ..team.models import Team from ..ui.templatetags.markup import restructuredtext - -from beat.core import prototypes - -import simplejson as json +from .models import Toolchain @login_required @@ -53,22 +50,22 @@ def create(request, name=None): The user must be authenticated before it can add a new toolchain """ - parameters = {'toolchain_author': request.user.username, - 'toolchain_name': name, - 'toolchain_version': 1, - 'short_description': '', - 'description': '', - 'errors': '', - 'edition': False, - 'messages': Messages, - } + parameters = { + "toolchain_author": request.user.username, + "toolchain_name": name, + "toolchain_version": 1, + "short_description": "", + "description": "", + "errors": "", + "edition": False, + "messages": Messages, + } # Retrieves the existing toolchain (if necessary) if name is not None: previous_versions = Toolchain.objects.filter( - author=request.user, - name__iexact=name, - ).order_by('-version') + author=request.user, name__iexact=name, + ).order_by("-version") if len(previous_versions) == 0: raise Http404() @@ -76,19 +73,23 @@ def create(request, name=None): description = ensure_string(previous_version.description) - parameters['toolchain_version'] = previous_version.version + 1 - parameters['declaration'] = previous_version.declaration_string.replace('\n', '') - parameters['short_description'] = previous_version.short_description - parameters['description'] = description.replace('\n', '\\n') - parameters['html_description'] = restructuredtext(description).replace('\n', '') - parameters['errors'] = previous_version.errors.replace('\n', '\\n') if previous_version.errors is not None else '' + parameters["toolchain_version"] = previous_version.version + 1 + parameters["declaration"] = previous_version.declaration_string.replace( + "\n", "" + ) + parameters["short_description"] = previous_version.short_description + parameters["description"] = description.replace("\n", "\\n") + parameters["html_description"] = restructuredtext(description).replace("\n", "") + parameters["errors"] = ( + previous_version.errors.replace("\n", "\\n") + if previous_version.errors is not None + else "" + ) else: - declaration, errors = prototypes.load('toolchain') - parameters['declaration'] = json.dumps(declaration) + declaration, errors = prototypes.load("toolchain") + parameters["declaration"] = json.dumps(declaration) - return render(request, - 'toolchains/edition.html', - parameters) + return render(request, "toolchains/edition.html", parameters) @login_required @@ -99,30 +100,30 @@ def fork(request, author, name, version): """ # Retrieves the forked toolchain - fork_of = get_object_or_404(Toolchain.objects.for_user(request.user, True), - author__username__iexact=author, - name__iexact=name, - version=int(version) - ) + fork_of = get_object_or_404( + Toolchain.objects.for_user(request.user, True), + author__username__iexact=author, + name__iexact=name, + version=int(version), + ) description = ensure_string(fork_of.description) errors = ensure_string(fork_of.errors) - parameters = {'toolchain_author': request.user.username, - 'toolchain_name': name, - 'toolchain_version': 1, - 'fork_of': fork_of, - 'declaration': fork_of.declaration_string.replace('\n', ''), - 'short_description': fork_of.short_description, - 'description': description.replace('\n', '\\n'), - 'errors': errors.replace('\n', '\\n'), - 'edition': False, - 'messages': Messages, - } + parameters = { + "toolchain_author": request.user.username, + "toolchain_name": name, + "toolchain_version": 1, + "fork_of": fork_of, + "declaration": fork_of.declaration_string.replace("\n", ""), + "short_description": fork_of.short_description, + "description": description.replace("\n", "\\n"), + "errors": errors.replace("\n", "\\n"), + "edition": False, + "messages": Messages, + } - return render(request, - 'toolchains/edition.html', - parameters) + return render(request, "toolchains/edition.html", parameters) @login_required @@ -136,29 +137,33 @@ def edit(request, author, name, version): raise Http404() # Retrieves the toolchain - toolchain = get_object_or_404(Toolchain, - author__username__iexact=author, - name__iexact=name, - version=int(version) - ) + toolchain = get_object_or_404( + Toolchain, + author__username__iexact=author, + name__iexact=name, + version=int(version), + ) description = ensure_string(toolchain.description) errors = ensure_string(toolchain.errors) # Render the page - return render(request, - 'toolchains/edition.html', - {'toolchain_author': request.user.username, - 'toolchain_name': name, - 'toolchain_version': toolchain.version, - 'declaration': toolchain.declaration_string.replace('\n', ''), - 'short_description': toolchain.short_description, - 'description': description.replace('\n', '\\n'), - 'html_description': restructuredtext(description).replace('\n', ''), - 'errors': errors.replace('\n', '\\n'), - 'edition': True, - 'messages': Messages, - }) + return render( + request, + "toolchains/edition.html", + { + "toolchain_author": request.user.username, + "toolchain_name": name, + "toolchain_version": toolchain.version, + "declaration": toolchain.declaration_string.replace("\n", ""), + "short_description": toolchain.short_description, + "description": description.replace("\n", "\\n"), + "html_description": restructuredtext(description).replace("\n", ""), + "errors": errors.replace("\n", "\\n"), + "edition": True, + "messages": Messages, + }, + ) def view(request, author, name, version=None): @@ -175,8 +180,9 @@ def view(request, author, name, version=None): version=int(version), ) else: - toolchain = Toolchain.objects.filter(author__username__iexact=author, - name__iexact=name).order_by('-version') + toolchain = Toolchain.objects.filter( + author__username__iexact=author, name__iexact=name + ).order_by("-version") if not toolchain: raise Http404() else: @@ -187,25 +193,29 @@ def view(request, author, name, version=None): if not has_access: raise Http404() - owner = (request.user == toolchain.author) + owner = request.user == toolchain.author reports = None - if not request.user.is_anonymous: #fetch user reports, if any + if not request.user.is_anonymous: # fetch user reports, if any reports = Report.objects.filter(author=request.user) # Users the object can be shared with - users = User.objects.exclude(username__in=settings.ACCOUNTS_TO_EXCLUDE_FROM_TEAMS).order_by('username') + users = User.objects.exclude( + username__in=settings.ACCOUNTS_TO_EXCLUDE_FROM_TEAMS + ).order_by("username") # Render the page - return render(request, - 'toolchains/view.html', - { - 'toolchain': toolchain, - 'owner': owner, - 'reports': reports, - 'users': users, - 'teams': Team.objects.for_user(request.user, True) - }) + return render( + request, + "toolchains/view.html", + { + "toolchain": toolchain, + "owner": owner, + "reports": reports, + "users": users, + "teams": Team.objects.for_user(request.user, True), + }, + ) def diff(request, author1, name1, version1, author2, name2, version2): @@ -220,7 +230,8 @@ def diff(request, author1, name1, version1, author2, name2, version2): version=int(version1), ) has_access, _ = toolchain1.accessibility_for(request.user) - if not has_access: raise Http404() + if not has_access: + raise Http404() toolchain2 = get_object_or_404( Toolchain, @@ -229,49 +240,47 @@ def diff(request, author1, name1, version1, author2, name2, version2): version=int(version2), ) has_access, _ = toolchain2.accessibility_for(request.user) - if not has_access: raise Http404() + if not has_access: + raise Http404() - return render(request, - 'toolchains/diff.html', - { - 'toolchain1': toolchain1, - 'toolchain2': toolchain2, - }) + return render( + request, + "toolchains/diff.html", + {"toolchain1": toolchain1, "toolchain2": toolchain2}, + ) def ls(request, author_name): - '''List all accessible toolchains to the request user''' + """List all accessible toolchains to the request user""" - if not author_name: return public_ls(request) + if not author_name: + return public_ls(request) # check that the user exists on the system author = get_object_or_404(User, username=author_name) # orders toolchains so that the latest information is displayed first - objects = Toolchain.objects.from_author_and_public(request.user, - author_name).order_by('-creation_date') + objects = Toolchain.objects.from_author_and_public( + request.user, author_name + ).order_by("-creation_date") objects = Toolchain.filter_latest_versions(objects) - return render(request, - 'toolchains/list.html', - dict( - objects=objects, - author=author, - owner=(request.user==author), - )) + return render( + request, + "toolchains/list.html", + dict(objects=objects, author=author, owner=(request.user == author),), + ) def public_ls(request): - '''List all publicly accessible objects''' + """List all publicly accessible objects""" # orders so that more recent are first - objects = Toolchain.objects.public().order_by('-creation_date') + objects = Toolchain.objects.public().order_by("-creation_date") objects = Toolchain.filter_latest_versions(objects) - return render(request, - 'toolchains/list.html', - dict( - objects=objects, - author=request.user, #anonymous - owner=False, - )) + return render( + request, + "toolchains/list.html", + dict(objects=objects, author=request.user, owner=False,), # anonymous + )