from django.db import models
from django.db.models import Q
class File(models.Model):
path = models.CharField(
max_length=1024,
unique=True,
help_text="POSIX path relative to repo root"
)
name = models.CharField(max_length=500)
content = models.TextField(blank=True)
is_directory = models.BooleanField(default=False)
def __str__(self):
return self.path
@property
def parent_path(self):
if "/" not in self.path:
return None
return self.path.rsplit("/", 1)[0]
def get_absolute_path(self):
return f'/src/{self.path}'
def get_parent_absolute_url(self):
"""Get URL for parent directory"""
if self.parent_path is not None:
return f'/src/{self.parent_path}'
else:
return '/src'
def get_directory_contents(self):
"""Get all files in this directory"""
if not self.is_directory:
return File.objects.none()
return File.get_files_in_directory(self.path)
@classmethod
def get_files_in_directory(cls, dir_path):
"""Get all files in a given directory path"""
if dir_path is None or dir_path == "":
return cls.objects.filter(~Q(path__contains="/")).order_by('-is_directory', 'name')
all_possible = cls.objects.filter(
path__startswith=f"{dir_path}/"
).order_by('-is_directory', 'name')
result = []
for file in all_possible:
remaining = file.path[len(dir_path) + 1:]
if "/" not in remaining:
result.append(file)
return result
@property
def breadcrumb_parts(self):
"""Return list of dicts for breadcrumb navigation"""
parts = []
parts.append({
'name': 'src',
'url': '/src/'
})
if not self.path:
return parts
path_parts = self.path.split('/')
current_path = ''
for i, part in enumerate(path_parts):
current_path = f"{current_path}/{part}" if current_path else part
if i < len(path_parts) - 1:
parts.append({
'name': part,
'url': f'/src/{current_path}'
})
else:
if self.is_directory:
parts.append({
'name': part + '/',
'url': f'/src/{current_path}'
})
else:
parts.append({
'name': part,
'url': None
})
return parts
@property
def highlight_language(self):
"""Return Highlight.js language class based on file extension"""
extension_map = {
'.py': 'python',
'.js': 'javascript',
'.html': 'html',
'.css': 'css',
'.yaml': 'yaml',
'.md': 'markdown',
'.json': 'json',
'.sh': 'bash',
'.xml': 'xml',
'.txt': 'plaintext',
}
if '.' in self.name:
ext = '.' + self.name.split('.')[-1].lower()
return extension_map.get(ext, 'plaintext')
return 'plaintext'