Skip to content

Commit

Permalink
Add ProjectCodebaseView to browse project codebase tree #744
Browse files Browse the repository at this point in the history
Signed-off-by: Thomas Druez <[email protected]>
  • Loading branch information
tdruez committed May 30, 2023
1 parent 1860ca0 commit 8f20dda
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 9 deletions.
21 changes: 13 additions & 8 deletions scanpipe/templates/scanpipe/includes/project_codebase.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
<nav class="panel is-info">
<nav id="codebase-navigation" class="panel is-info">
<p class="panel-heading py-2 is-size-6">
Codebase
</p>
{% for path in paths %}
<a class="panel-block">
<span class="panel-icon">
<i class="{% if path.is_dir %}fas fa-folder{% else %}far fa-file{% endif %}"></i>
</span>
{{ path.name }}
</a>
{% for node in codebase_tree %}
{% if node.is_dir %}
<a class="panel-block" href="#" hx-target="#codebase-navigation" hx-swap="outerHTML" hx-get="{{ project.get_absolute_url }}codebase/?current_dir={{ node.location }}">
<span class="panel-icon"><i class="fas fa-folder"></i></span>
{{ node.name }}
</a>
{% else %}
<a class="panel-block" href="{% url "resource_detail" project.uuid node.location %}" target="_blank">
<span class="panel-icon"><i class="far fa-file"></i></span>
{{ node.name }}
</a>
{% endif %}
{% endfor %}
</nav>
4 changes: 3 additions & 1 deletion scanpipe/templates/scanpipe/project_detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,9 @@
<div class="columns">
{% if codebase_root %}
<div class="column">
{% include "scanpipe/includes/project_codebase.html" with paths=codebase_root %}
<div hx-get="{% url 'project_codebase' project.uuid %}" hx-trigger="load">
<i class="fas fa-spinner fa-pulse" aria-hidden="true"></i>
</div>
</div>
{% endif %}
{% if resource_status_summary %}
Expand Down
5 changes: 5 additions & 0 deletions scanpipe/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,11 @@
views.ProjectResetView.as_view(),
name="project_reset",
),
path(
"project/<uuid:uuid>/codebase/",
views.ProjectCodebaseView.as_view(),
name="project_codebase",
),
path(
"run/<uuid:uuid>/",
views.run_detail_view,
Expand Down
54 changes: 54 additions & 0 deletions scanpipe/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,13 @@
from collections import Counter
from collections import namedtuple
from contextlib import suppress
from pathlib import Path

from django.apps import apps
from django.conf import settings
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.files.storage.filesystem import FileSystemStorage
from django.http import FileResponse
from django.http import Http404
from django.http import HttpResponse
Expand Down Expand Up @@ -686,6 +688,58 @@ def get_context_data(self, **kwargs):
return context


class ProjectCodebaseView(
ConditionalLoginRequired,
ProjectViewMixin,
generic.DetailView,
):
template_name = "scanpipe/includes/project_codebase.html"

@staticmethod
def get_tree(project, current_dir):
codebase_root = project.codebase_path.resolve()
if not codebase_root.exists():
raise Http404

try:
codebase_root.relative_to(scanpipe_app.workspace_path)
except ValueError:
raise Http404

fs_storage = FileSystemStorage(location=codebase_root)
directories, files = fs_storage.listdir(current_dir)

def get_node(name, is_dir, location):
return {
"name": name,
"is_dir": is_dir,
"location": location,
}

tree = []
root_directory = "."
include_parent = current_dir and current_dir != root_directory
if include_parent:
tree.append(
get_node(name="..", is_dir=True, location=str(Path(current_dir).parent))
)

for resources, is_dir in [(directories, True), (files, False)]:
tree.extend(
get_node(name=name, is_dir=is_dir, location=f"{current_dir}/{name}")
for name in resources
)

return tree

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
current_dir = self.request.GET.get("current_dir") or "."
context["current_dir"] = current_dir
context["codebase_tree"] = self.get_tree(self.object, current_dir)
return context


class ProjectArchiveView(
ConditionalLoginRequired, ProjectViewMixin, SingleObjectMixin, FormView
):
Expand Down

0 comments on commit 8f20dda

Please sign in to comment.