Files
thrillwiki_django_no_react/history_tracking/views.py

239 lines
7.9 KiB
Python

from django.views.generic import TemplateView, View
from django.http import HttpResponse, JsonResponse
from django.shortcuts import get_object_or_404
from django.template.loader import render_to_string
from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.exceptions import ValidationError
from django.db import transaction
from django.utils import timezone
from .models import VersionBranch, VersionTag, ChangeSet
from .managers import BranchManager, ChangeTracker, MergeStrategy
class VersionControlPanel(LoginRequiredMixin, TemplateView):
"""Main version control interface"""
template_name = 'history_tracking/version_control_panel.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
branch_manager = BranchManager()
context.update({
'branches': branch_manager.list_branches(),
'current_branch': self.request.GET.get('branch'),
})
return context
class BranchListView(LoginRequiredMixin, View):
"""HTMX view for branch list"""
def get(self, request):
branch_manager = BranchManager()
branches = branch_manager.list_branches()
content = render_to_string(
'history_tracking/components/branch_list.html',
{'branches': branches},
request=request
)
return HttpResponse(content)
class HistoryView(LoginRequiredMixin, View):
"""HTMX view for change history"""
def get(self, request):
branch_name = request.GET.get('branch')
if not branch_name:
return HttpResponse("No branch selected")
branch = get_object_or_404(VersionBranch, name=branch_name)
tracker = ChangeTracker()
changes = tracker.get_changes(branch)
content = render_to_string(
'history_tracking/components/history_view.html',
{'changes': changes},
request=request
)
return HttpResponse(content)
class MergeView(LoginRequiredMixin, View):
"""HTMX view for merge operations"""
def get(self, request):
source = request.GET.get('source')
target = request.GET.get('target')
if not (source and target):
return HttpResponse("Source and target branches required")
content = render_to_string(
'history_tracking/components/merge_panel.html',
{
'source': source,
'target': target
},
request=request
)
return HttpResponse(content)
@transaction.atomic
def post(self, request):
source_name = request.POST.get('source')
target_name = request.POST.get('target')
if not (source_name and target_name):
return JsonResponse({
'error': 'Source and target branches required'
}, status=400)
try:
source = get_object_or_404(VersionBranch, name=source_name)
target = get_object_or_404(VersionBranch, name=target_name)
branch_manager = BranchManager()
success, conflicts = branch_manager.merge_branches(
source=source,
target=target,
user=request.user
)
if success:
content = render_to_string(
'history_tracking/components/merge_success.html',
{'source': source, 'target': target},
request=request
)
return HttpResponse(content)
else:
content = render_to_string(
'history_tracking/components/merge_conflicts.html',
{
'source': source,
'target': target,
'conflicts': conflicts
},
request=request
)
return HttpResponse(content)
except ValidationError as e:
return JsonResponse({'error': str(e)}, status=400)
except Exception as e:
return JsonResponse(
{'error': 'Merge failed. Please try again.'},
status=500
)
class BranchCreateView(LoginRequiredMixin, View):
"""HTMX view for branch creation"""
def get(self, request):
content = render_to_string(
'history_tracking/components/branch_create.html',
request=request
)
return HttpResponse(content)
@transaction.atomic
def post(self, request):
name = request.POST.get('name')
parent_name = request.POST.get('parent')
if not name:
return JsonResponse({'error': 'Branch name required'}, status=400)
try:
branch_manager = BranchManager()
parent = None
if parent_name:
parent = get_object_or_404(VersionBranch, name=parent_name)
branch = branch_manager.create_branch(
name=name,
parent=parent,
user=request.user
)
content = render_to_string(
'history_tracking/components/branch_item.html',
{'branch': branch},
request=request
)
return HttpResponse(content)
except ValidationError as e:
return JsonResponse({'error': str(e)}, status=400)
except Exception as e:
return JsonResponse(
{'error': 'Branch creation failed. Please try again.'},
status=500
)
class TagCreateView(LoginRequiredMixin, View):
"""HTMX view for version tagging"""
def get(self, request):
branch_name = request.GET.get('branch')
if not branch_name:
return HttpResponse("Branch required")
content = render_to_string(
'history_tracking/components/tag_create.html',
{'branch_name': branch_name},
request=request
)
return HttpResponse(content)
@transaction.atomic
def post(self, request):
name = request.POST.get('name')
branch_name = request.POST.get('branch')
if not (name and branch_name):
return JsonResponse(
{'error': 'Tag name and branch required'},
status=400
)
try:
branch = get_object_or_404(VersionBranch, name=branch_name)
# Get latest historical record for the branch
latest_change = ChangeSet.objects.filter(
branch=branch,
status='applied'
).latest('created_at')
if not latest_change:
return JsonResponse(
{'error': 'No changes to tag'},
status=400
)
tag = VersionTag.objects.create(
name=name,
branch=branch,
historical_record=latest_change.historical_records.latest('history_date'),
created_by=request.user,
metadata={
'tagged_at': timezone.now().isoformat(),
'changeset': latest_change.pk
}
)
content = render_to_string(
'history_tracking/components/tag_item.html',
{'tag': tag},
request=request
)
return HttpResponse(content)
except ValidationError as e:
return JsonResponse({'error': str(e)}, status=400)
except Exception as e:
return JsonResponse(
{'error': 'Tag creation failed. Please try again.'},
status=500
)