Add Steam library import via OpenID
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
- Steam OpenID flow: user authenticates with Steam, we get their Steam ID - Server-side API key fetches their owned games with playtime - Import page shows full library, marks already-imported games - Imported games land in backlog as GAMES items with hours_played set - STEAM_API_KEY env var plumbed into both prod and dev containers Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
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
|
||||
|
||||
|
||||
def signup(request):
|
||||
@@ -77,3 +80,73 @@ 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.objects.create(
|
||||
user=request.user,
|
||||
category=Item.GAMES,
|
||||
name=game['name'],
|
||||
hours_played=hours,
|
||||
progress_percent=progress,
|
||||
)
|
||||
imported += 1
|
||||
|
||||
del request.session['steam_games']
|
||||
return redirect(f"{reverse('backlogger:list')}?category=games&imported={imported}")
|
||||
|
||||
Reference in New Issue
Block a user