This commit has no recorded session.
diff
commit c0be131e3d0d2f7f5b5b99b460077821a187b2b1Author: Colin Powell <colin@unbl.ink>Date: Mon Jun 15 14:55:58 2026 -0400 [longplay] Add ability to undo finishes@@ -594,6 +594,7 @@ named constants for maintainability. - ~vrobbler/apps/webpages/models.py~ (line 290) -- ="url"= - ~vrobbler/apps/scrobbles/importers/tsv.py~ (line 55) -- ="S"= completion status +** TODO [#C] Show time per scrobble in long play lists and total time playing :templates:longplay:scrobbles: ** DONE [#B] Allow marking media as long play complete from detail page :templates:scrobbles:longplay: :PROPERTIES: :ID: 2c314768-be97-9b10-d13c-9cfd0f38a64e@@ -909,6 +909,28 @@ def scrobble_longplay_finish(request, uuid): if not user.is_authenticated: return HttpResponseRedirect(success_url) + # Try scrobble UUID first+ scrobble = Scrobble.objects.filter(uuid=uuid, user=user).first()+ if scrobble:+ if scrobble.long_play_complete == True:+ scrobble.long_play_complete = None+ scrobble.save(update_fields=["long_play_complete"])+ messages.add_message(+ request,+ messages.INFO,+ f"Long play of {scrobble.media_obj} marked as not complete.",+ )+ else:+ scrobble.long_play_complete = True+ scrobble.save(update_fields=["long_play_complete"])+ messages.add_message(+ request,+ messages.SUCCESS,+ f"Long play of {scrobble.media_obj} finished.",+ )+ return HttpResponseRedirect(success_url)++ # Fall back to media UUID (existing behavior) media_obj = None for app, model in LONG_PLAY_MEDIA.items(): media_model = apps.get_model(app_label=app, model_name=model)@@ -917,22 +939,27 @@ def scrobble_longplay_finish(request, uuid): break if not media_obj:- return+ messages.add_message(+ request, messages.ERROR, f"Media with uuid {uuid} not found."+ )+ return HttpResponseRedirect(success_url) last_scrobble = media_obj.last_long_play_scrobble_for_user(user)- if last_scrobble and last_scrobble.long_play_complete == False:- last_scrobble.long_play_complete = True+ if last_scrobble and last_scrobble.long_play_complete == True:+ last_scrobble.long_play_complete = None last_scrobble.save(update_fields=["long_play_complete"]) messages.add_message( request,- messages.SUCCESS,- f"Long play of {media_obj} finished.",+ messages.INFO,+ f"Long play of {media_obj} marked as not complete.", )- elif last_scrobble and last_scrobble.long_play_complete == True:+ elif last_scrobble:+ last_scrobble.long_play_complete = True+ last_scrobble.save(update_fields=["long_play_complete"]) messages.add_message( request,- messages.INFO,- f"Long play of {media_obj} was already completed.",+ messages.SUCCESS,+ f"Long play of {media_obj} finished.", ) else: messages.add_message(@@ -36,7 +36,6 @@ <p>{{scrobbles.count}} scrobbles</p> <p><a href="{{object.resume_start_url}}">Resume reading</a></p>- <p><a class="btn btn-sm btn-warning" href="{{object.get_longplay_finish_url}}">Finish long play</a></p> </div> {% if charts %} <div class="row">@@ -62,7 +61,7 @@ {% for scrobble in scrobbles.all|dictsortreversed:"timestamp" %} <tr> <td><a href="{{scrobble.get_absolute_url}}">{{scrobble.local_timestamp}}</a></td>- <td>{% if scrobble.long_play_complete == True %}Yes{% else %}No{% endif %}</td>+ <td>{% if scrobble.long_play_complete == True %}Yes <small><a href="{% url 'scrobbles:longplay-finish' uuid=scrobble.uuid %}">(not complete?)</a></small>{% else %}<a href="{% url 'scrobbles:longplay-finish' uuid=scrobble.uuid %}">No</a>{% endif %}</td> <td>{% if scrobble.in_progress %}Now reading{% else %}{{scrobble.session_pages_read}}{% endif %}</td> <td>{% for author in scrobble.book.authors.all %}<a href="{{author.get_absolute_url}}">{{author}}</a>{% if not forloop.last %}, {% endif %}{% endfor %}</td> </tr>@@ -27,7 +27,6 @@ </div> <div class="row"> <p>{{scrobbles.count}} scrobbles</p>- <p><a class="btn btn-sm btn-warning" href="{{object.get_longplay_finish_url}}">Finish long play</a></p> </div> <div class="row"> <div class="col-md">@@ -45,7 +44,7 @@ {% for scrobble in scrobbles.all|dictsortreversed:"timestamp" %} <tr> <td><a href="{{scrobble.get_absolute_url}}">{{scrobble.local_timestamp}}</a></td>- <td>{% if scrobble.long_play_complete == True %}Yes{% else %}No{% endif %}</td>+ <td>{% if scrobble.long_play_complete == True %}Yes <small><a href="{% url 'scrobbles:longplay-finish' uuid=scrobble.uuid %}">(not complete?)</a></small>{% else %}<a href="{% url 'scrobbles:longplay-finish' uuid=scrobble.uuid %}">No</a>{% endif %}</td> <td>{% if scrobble.in_progress %}Now reading{% else %}{{scrobble.session_pages_read}}{% endif %}</td> </tr> {% endfor %}@@ -53,7 +53,6 @@ <p>{{scrobbles.count}} scrobbles</p> <p> <a href="{{object.start_url}}">Play again</a>- <a class="btn btn-sm btn-warning" href="{{object.get_longplay_finish_url}}">Finish long play</a> </p> </div> <div class="row">@@ -68,6 +67,7 @@ <th scope="col">Title</th> <th scope="col">Notes</th> <th scope="col">Source</th>+ <th scope="col">Completed</th> </tr> </thead> <tbody>@@ -77,6 +77,7 @@ <td><a href="{{scrobble.get_media_source_url}}">{{scrobble.logdata.title}}</a></td> <td>{{scrobble.logdata.notes_as_str}}</td> <td>{{scrobble.source}}</td>+ <td>{% if scrobble.long_play_complete == True %}Yes <small><a href="{% url 'scrobbles:longplay-finish' uuid=scrobble.uuid %}">(not complete?)</a></small>{% else %}<a href="{% url 'scrobbles:longplay-finish' uuid=scrobble.uuid %}">No</a>{% endif %}</td> </tr> {% endfor %} </tbody>@@ -62,7 +62,6 @@ <p>{{scrobbles.count}} scrobbles</p> <p> <a href="">Play again</a>- <a class="btn btn-sm btn-warning" href="{{object.get_longplay_finish_url}}">Finish long play</a> </p> </div> <div class="row">@@ -84,7 +83,7 @@ <tr> <td><a href="{{scrobble.get_absolute_url}}">{{scrobble.local_timestamp}}</a></td>- <td>{% if scrobble.long_play_complete == True %}Yes{% else %}Not yet{% endif %}</td>+ <td>{% if scrobble.long_play_complete == True %}Yes <small><a href="{% url 'scrobbles:longplay-finish' uuid=scrobble.uuid %}">(not complete?)</a></small>{% else %}<a href="{% url 'scrobbles:longplay-finish' uuid=scrobble.uuid %}">Not yet</a>{% endif %}</td> <td>{% if scrobble.in_progress %}Now playing{% else %}{{scrobble.playback_position_seconds|natural_duration}}{% endif %}</td> <td>{% for platform in scrobble.video_game.platforms.all %}<a href="{{platform.get_absolute_url}}">{{platform}}</a>{% if not forloop.last %}, {% endif %}{% endfor %}</td> <td>{% if scrobble.videogame_save_data %}<a href="{{scrobble.videogame_save_data.url}}">Save data</a>{% else %}Not yet{% endif %}</td>