Files
k-boris-website/backlogger/views.py
Boris 2e0ca22dd9
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Fix unending: shelf status, not category
Unending belongs in STATUS_CHOICES alongside completed/abandoned.
Adds an Unending shelf tab and an ∞ button on active game cards.
Reverts the incorrect category addition from the previous commit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 23:32:09 +03:00

174 lines
5.6 KiB
Python

from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.shortcuts import render, get_object_or_404, redirect
from django.urls import reverse
from .models import Item
from .forms import ItemForm, SignupForm
from . import steam as steam_api
from . import hltb as hltb_api
def signup(request):
if request.method == 'POST':
form = SignupForm(request.POST)
if form.is_valid():
user = form.save(commit=False)
user.is_active = False
user.save()
return render(request, 'backlogger/signup_pending.html')
else:
form = SignupForm()
return render(request, 'backlogger/signup.html', {'form': form})
SORT_MAP = {
'fav': ['-favorite', 'name'],
'az': ['name'],
'za': ['-name'],
'newest': ['-created_at'],
'oldest': ['created_at'],
'progress': ['-progress_percent'],
}
@login_required
def item_list(request):
category = request.GET.get('category', '')
sort = request.GET.get('sort', 'fav')
shelf = request.GET.get('shelf', Item.ACTIVE)
if shelf not in (Item.ACTIVE, Item.COMPLETED, Item.ABANDONED, Item.UNENDING):
shelf = Item.ACTIVE
items = Item.objects.filter(user=request.user, status=shelf)
if category:
items = items.filter(category=category)
items = items.order_by(*SORT_MAP.get(sort, SORT_MAP['fav']))
return render(request, 'backlogger/list.html', {
'items': items,
'category': category,
'sort': sort,
'shelf': shelf,
'categories': Item.CATEGORY_CHOICES,
})
@login_required
def item_add(request):
if request.method == 'POST':
form = ItemForm(request.POST)
if form.is_valid():
item = form.save(commit=False)
item.user = request.user
item.save()
hltb_api.apply_to_item(item)
return redirect('backlogger:list')
else:
form = ItemForm()
return render(request, 'backlogger/item_form.html', {'form': form, 'action': 'Add'})
@login_required
def item_edit(request, pk):
item = get_object_or_404(Item, pk=pk, user=request.user)
if request.method == 'POST':
form = ItemForm(request.POST, instance=item)
if form.is_valid():
updated = form.save()
if 'name' in form.changed_data or 'category' in form.changed_data:
hltb_api.apply_to_item(updated)
return redirect('backlogger:list')
else:
form = ItemForm(instance=item)
return render(request, 'backlogger/item_form.html', {'form': form, 'action': 'Edit', 'item': item})
@login_required
def item_set_status(request, pk):
if request.method == 'POST':
item = get_object_or_404(Item, pk=pk, user=request.user)
new_status = request.POST.get('status')
if new_status in (Item.ACTIVE, Item.COMPLETED, Item.ABANDONED, Item.UNENDING):
item.status = new_status
item.save(update_fields=['status', 'updated_at'])
next_url = request.POST.get('next') or reverse('backlogger:list')
return redirect(next_url)
@login_required
def item_delete(request, pk):
if request.method == 'POST':
get_object_or_404(Item, pk=pk, user=request.user).delete()
return redirect('backlogger:list')
@login_required
def steam_login(request):
callback = request.build_absolute_uri(reverse('backlogger:steam_callback'))
realm = f"{request.scheme}://{request.get_host()}"
return redirect(steam_api.build_auth_url(callback, realm))
@login_required
def steam_callback(request):
steam_id = steam_api.verify_and_get_steam_id(request.GET.dict())
if not steam_id:
return render(request, 'backlogger/steam_import.html', {'error': 'Steam verification failed. Please try again.'})
api_key = getattr(settings, 'STEAM_API_KEY', '')
if not api_key:
return render(request, 'backlogger/steam_import.html', {'error': 'Steam API key is not configured on the server.'})
try:
games = steam_api.get_owned_games(api_key, steam_id)
except Exception:
return render(request, 'backlogger/steam_import.html', {'error': 'Could not fetch your Steam library. Your profile may be set to private.'})
existing = set(
Item.objects.filter(user=request.user, category=Item.GAMES)
.values_list('name', flat=True)
)
game_list = []
for g in games:
name = g.get('name', '')
hours = round(g.get('playtime_forever', 0) / 60, 1)
game_list.append({
'appid': g.get('appid'),
'name': name,
'hours': hours,
'already_imported': name in existing,
})
request.session['steam_games'] = game_list
return render(request, 'backlogger/steam_import.html', {'games': game_list})
@login_required
def steam_import(request):
if request.method != 'POST':
return redirect('backlogger:list')
games_by_appid = {str(g['appid']): g for g in request.session.get('steam_games', [])}
selected = request.POST.getlist('appids')
imported = 0
for appid in selected:
game = games_by_appid.get(appid)
if not game or game['already_imported']:
continue
hours = game['hours']
progress = min(100.0, hours) if hours > 0 else 0.0
item = Item.objects.create(
user=request.user,
category=Item.GAMES,
name=game['name'],
hours_played=hours,
progress_percent=progress,
)
hltb_api.apply_to_item(item)
imported += 1
del request.session['steam_games']
return redirect(f"{reverse('backlogger:list')}?category=games&imported={imported}")