+ + {% trans 'Import from Steam Wishlist / Library (owned games only)' %} + + + + {% csrf_token %} + + + {% trans 'Steam API Key' %} + + {% trans 'Get it here' %} + + + + + + {% trans 'Steam User ID' %} + + {% trans 'Find as "Steam ID: ..." in ' %} + {% trans 'Account Details' %} + + + + + + + {% trans 'Sources to import from' %} + + + {% trans 'Fetch wishlist' %} + + + + {% trans 'Fetch owned games' %} + + + + {% trans 'Fetch all free games' %} + + + + {% trans 'Fetch played free games' %} + + + + {% trans 'Fetch no free games' %} + + + + + + + {% trans 'Import games with these estimated status' %} + + + + {% trans 'Playing' %} + + + + {% trans 'Played' %} + + + + {% trans 'To play' %} + + + + {% trans 'Dropped' %} + + + + + + {% trans 'Ignored Games' %} + {% trans 'input comma-separated Steam AppIDs' %} + + + + + + {% trans 'Override' %} + + + {% trans 'Allow reverse override of status (e.g. playing -> want to, or played -> playing)' %} + + + + + + {% trans 'Mark Date' %} + + + + {% trans 'Current time (not recommended)' %} + + + + {% trans 'Using timestamp from Steam' %} + + + {% trans 'Input the most often timezone that you play games in this library, for us to convert the local time stored by Steam.' %} + {% trans 'reference' %} + + + + + + + + {% trans 'Visibility' %} + + + + {% trans 'Public' %} + + + + {% trans 'Followers Only' %} + + + + {% trans 'Mentioned Only' %} + + + + {% trans 'Import' %} + + +
{% trans 'Export Data' %} diff --git a/users/urls.py b/users/urls.py index e6ad7af2d..4baa4c1d0 100644 --- a/users/urls.py +++ b/users/urls.py @@ -15,6 +15,7 @@ path("data/import/douban", import_douban, name="import_douban"), path("data/import/letterboxd", import_letterboxd, name="import_letterboxd"), path("data/import/opml", import_opml, name="import_opml"), + path("data/import/steam", import_steam, name="import_steam"), path("data/export/reviews", export_reviews, name="export_reviews"), path("data/export/marks", export_marks, name="export_marks"), path("data/export/csv", export_csv, name="export_csv"), diff --git a/users/views/data.py b/users/views/data.py index 8e1f52cd9..e1714ae6f 100644 --- a/users/views/data.py +++ b/users/views/data.py @@ -10,6 +10,8 @@ from django.urls import reverse from django.utils import timezone, translation from django.utils.translation import gettext as _ +import pytz +import requests from common.utils import GenerateDateUUIDMediaFilePath from journal.exporters import CsvExporter, DoufenExporter, NdjsonExporter @@ -18,6 +20,7 @@ GoodreadsImporter, LetterboxdImporter, OPMLImporter, + SteamImporter ) from journal.models import ShelfType, reset_journal_visibility_for_user from social.models import reset_social_visibility_for_user @@ -331,3 +334,61 @@ def import_opml(request): else: messages.add_message(request, messages.ERROR, _("Invalid file.")) return redirect(reverse("users:data")) + +@login_required +def import_steam(request): + if request.method != "POST": + return redirect(reverse("users:data")) + + steam_apikey = request.POST.get("steam_apikey") + steam_id = request.POST.get("steam_id") + + try: + if not SteamImporter.validate_apikey(steam_apikey): + messages.add_message(request, messages.ERROR, _(f"Invalid API key: {steam_apikey}.")) + return redirect(reverse("users:data")) + if not SteamImporter.validate_userid(steam_apikey, steam_id): + messages.add_message(request, messages.ERROR, _("Invalid steam id.")) + return redirect(reverse("users:data")) + except requests.RequestException as e: + messages.add_message(request, messages.ERROR, _(f"Network error validating apikey / userid: {e}")) + return redirect(reverse("users:data")) + + fetch_wishlist = bool(request.POST.get("fetch_wishlist", True)) + fetch_owned = bool(request.POST.get("fetch_owned", True)) + + if not (fetch_wishlist or fetch_owned): + messages.add_message(request, messages.ERROR, _("Nothing to fetch.")) + return redirect(reverse("users:data")) + + ignored_appids = str(request.POST.get("ignored_appids")).strip(',') + shelf_filter = [] + if fetch_owned: + if request.POST.get("import_playing"): shelf_filter.append(ShelfType.PROGRESS) + if request.POST.get("import_played"): shelf_filter.append(ShelfType.COMPLETE) + if request.POST.get("import_wishlist"): shelf_filter.append(ShelfType.WISHLIST) + if request.POST.get("import_dropped"): shelf_filter.append(ShelfType.DROPPED) + + tz_str = request.POST.get("timezone") + try: + pytz.timezone(tz_str) + except pytz.UnknownTimeZoneError: + messages.add_message(request, messages.ERROR, _(f"Unknown timezone: {tz_str}")) + return redirect(reverse("users:data")) + + SteamImporter.create( + user=request.user, + shelf_type_reversion = bool(request.POST.get("shelf_type_reversion")), + fetch_wishlist = fetch_wishlist, + fetch_owned = fetch_owned, + last_play_to_ctime = bool(request.POST.get("mark_date") != "current_time"), + owned_filter = request.POST.get("owned_filter", "played_free"), + shelf_filter = shelf_filter, + ignored_appids = ignored_appids, + steam_tz = tz_str, + visibility = int(request.POST.get("visibility", request.user.preference.default_visibility)), + steam_apikey = steam_apikey, + steam_id = steam_id + ).enqueue() + messages.add_message(request, messages.INFO, _("Import in progress.")) + return redirect(reverse("users:data"))