Fixing long play scrobbles
This commit is contained in:
@ -0,0 +1,23 @@
|
|||||||
|
# Generated by Django 4.1.5 on 2023-03-06 05:29
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("books", "0001_initial"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="book",
|
||||||
|
name="author_name",
|
||||||
|
field=models.CharField(blank=True, max_length=255, null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="book",
|
||||||
|
name="author_openlibrary_id",
|
||||||
|
field=models.CharField(blank=True, max_length=255, null=True),
|
||||||
|
),
|
||||||
|
]
|
||||||
20
vrobbler/apps/books/migrations/0003_book_cover.py
Normal file
20
vrobbler/apps/books/migrations/0003_book_cover.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# Generated by Django 4.1.5 on 2023-03-06 05:31
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("books", "0002_book_author_name_book_author_openlibrary_id"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="book",
|
||||||
|
name="cover",
|
||||||
|
field=models.ImageField(
|
||||||
|
blank=True, null=True, upload_to="books/covers/"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
||||||
19
vrobbler/apps/books/urls.py
Normal file
19
vrobbler/apps/books/urls.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
from django.urls import path
|
||||||
|
from books import views
|
||||||
|
|
||||||
|
app_name = "books"
|
||||||
|
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path("book/", views.BookListView.as_view(), name="book_list"),
|
||||||
|
path(
|
||||||
|
"book/<slug:slug>/",
|
||||||
|
views.BookDetailView.as_view(),
|
||||||
|
name="book_detail",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"author/<slug:slug>/",
|
||||||
|
views.AuthorDetailView.as_view(),
|
||||||
|
name="author_detail",
|
||||||
|
),
|
||||||
|
]
|
||||||
17
vrobbler/apps/books/views.py
Normal file
17
vrobbler/apps/books/views.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
from django.views import generic
|
||||||
|
from books.models import Book, Author
|
||||||
|
|
||||||
|
|
||||||
|
class BookListView(generic.ListView):
|
||||||
|
model = Book
|
||||||
|
paginate_by = 20
|
||||||
|
|
||||||
|
|
||||||
|
class BookDetailView(generic.DetailView):
|
||||||
|
model = Book
|
||||||
|
slug_field = "uuid"
|
||||||
|
|
||||||
|
|
||||||
|
class AuthorDetailView(generic.DetailView):
|
||||||
|
model = Author
|
||||||
|
slug_field = "uuid"
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
# Generated by Django 4.1.5 on 2023-03-06 02:52
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("scrobbles", "0026_scrobble_video_game"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name="scrobble",
|
||||||
|
name="videogame_minutes_played",
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="scrobble",
|
||||||
|
name="playback_position",
|
||||||
|
field=models.CharField(blank=True, max_length=10, null=True),
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
# Generated by Django 4.1.5 on 2023-03-06 05:04
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
(
|
||||||
|
"scrobbles",
|
||||||
|
"0027_remove_scrobble_videogame_minutes_played_and_more",
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="scrobble",
|
||||||
|
name="video_game_minutes_played",
|
||||||
|
field=models.IntegerField(blank=True, null=True),
|
||||||
|
),
|
||||||
|
]
|
||||||
BIN
vrobbler/apps/scrobbles/static/images/hltb.webp
Normal file
BIN
vrobbler/apps/scrobbles/static/images/hltb.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 78 B |
BIN
vrobbler/apps/scrobbles/static/images/igdb-logo.png
Normal file
BIN
vrobbler/apps/scrobbles/static/images/igdb-logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
@ -0,0 +1,23 @@
|
|||||||
|
# Generated by Django 4.1.5 on 2023-03-06 02:52
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("videogames", "0005_rename_platform_videogame_platforms"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="videogame",
|
||||||
|
name="summary",
|
||||||
|
field=models.TextField(blank=True, null=True),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="videogame",
|
||||||
|
name="platforms",
|
||||||
|
field=models.ManyToManyField(to="videogames.videogameplatform"),
|
||||||
|
),
|
||||||
|
]
|
||||||
0
vrobbler/apps/videogames/templatetags/__init__.py
Normal file
0
vrobbler/apps/videogames/templatetags/__init__.py
Normal file
16
vrobbler/apps/videogames/templatetags/naturalduration.py
Normal file
16
vrobbler/apps/videogames/templatetags/naturalduration.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
from django import template
|
||||||
|
|
||||||
|
register = template.Library()
|
||||||
|
|
||||||
|
|
||||||
|
@register.filter
|
||||||
|
def natural_duration(value):
|
||||||
|
value = int(value)
|
||||||
|
hours = int(value / 60)
|
||||||
|
minutes = value - (hours * 60)
|
||||||
|
value_str = ""
|
||||||
|
if minutes:
|
||||||
|
value_str = f"{minutes} minutes"
|
||||||
|
if hours:
|
||||||
|
value_str = f"{hours} hours, " + value_str
|
||||||
|
return value_str
|
||||||
57
vrobbler/templates/books/book_detail.html
Normal file
57
vrobbler/templates/books/book_detail.html
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
{% extends "base_list.html" %}
|
||||||
|
{% load mathfilters %}
|
||||||
|
{% load static %}
|
||||||
|
{% load naturalduration %}
|
||||||
|
|
||||||
|
{% block title %}{{object.title}}{% endblock %}
|
||||||
|
|
||||||
|
{% block lists %}
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
{% if object.cover%}
|
||||||
|
<p style="float:left; width:402px; padding:0; border: 1px solid #ccc">
|
||||||
|
<img src="{{object.cover.url}}" width=400 />
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
<div style="float:left; width:600px; margin-left:10px; ">
|
||||||
|
{% if object.summary %}
|
||||||
|
<p>{{object.summary|safe|linebreaks|truncatewords:160}}</p>
|
||||||
|
<hr />
|
||||||
|
{% endif %}
|
||||||
|
<p style="float:right;">
|
||||||
|
<a href="{{object.openlibrary_link}}"><img src="{% static " images/openlibrary-logo.png" %}" width=35></a>
|
||||||
|
<a href="{{object.amazon_link}}"><img src="{% static " images/amazon-logo.png" %}" width=35></a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<p>{{object.scrobble_set.count}} scrobbles</p>
|
||||||
|
<p><a href="">Start playing</a></p>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md">
|
||||||
|
<h3>Last scrobbles</h3>
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-striped table-sm">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">Date</th>
|
||||||
|
<th scope="col">Duration</th>
|
||||||
|
<th scope="col">Authors</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for scrobble in object.scrobble_set.all|dictsortreversed:"timestamp" %}
|
||||||
|
<tr>
|
||||||
|
<td>{{scrobble.timestamp}}</td>
|
||||||
|
<td>{% if scrobble.in_progress %}Now playing{% else %}{{scrobble.playback_position|natural_duration}}{% 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>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
57
vrobbler/templates/videogames/videogame_detail.html
Normal file
57
vrobbler/templates/videogames/videogame_detail.html
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
{% extends "base_list.html" %}
|
||||||
|
{% load mathfilters %}
|
||||||
|
{% load static %}
|
||||||
|
{% load naturalduration %}
|
||||||
|
|
||||||
|
{% block title %}{{object.title}}{% endblock %}
|
||||||
|
|
||||||
|
{% block lists %}
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
{% if object.hltb_cover%}
|
||||||
|
<p style="float:left; width:402px; padding:0; border: 1px solid #ccc">
|
||||||
|
<img src="{{object.hltb_cover.url}}" width=400 />
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
<div style="float:left; width:600px; margin-left:10px; ">
|
||||||
|
{% if object.summary %}
|
||||||
|
<p>{{object.summary|safe|linebreaks|truncatewords:160}}</p>
|
||||||
|
<hr/>
|
||||||
|
{% endif %}
|
||||||
|
<p style="float:right;">
|
||||||
|
<a href="{{object.igdb_link}}"><img src="{% static "images/igdb-logo.png" %}" width=35></a>
|
||||||
|
<a href="{{object.hltb_link}}"><img style="background: black;" src="{% static "images/hltb.webp" %}" width=35></a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<p>{{object.scrobble_set.count}} scrobbles</p>
|
||||||
|
<p><a href="">Start playing</a></p>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md">
|
||||||
|
<h3>Last scrobbles</h3>
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-striped table-sm">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">Date</th>
|
||||||
|
<th scope="col">Duration</th>
|
||||||
|
<th scope="col">Platforms</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for scrobble in object.scrobble_set.all|dictsortreversed:"timestamp" %}
|
||||||
|
<tr>
|
||||||
|
<td>{{scrobble.timestamp}}</td>
|
||||||
|
<td>{% if scrobble.in_progress %}Now playing{% else %}{{scrobble.playback_position|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>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
Reference in New Issue
Block a user