Minimum viable product

This commit is contained in:
Damillora 2020-12-17 00:36:29 +07:00
parent b1a7d8d06c
commit 94fb585ac5
37 changed files with 602 additions and 15 deletions

View File

@ -124,3 +124,5 @@ USE_TZ = True
STATIC_URL = '/static/'
STATIC_ROOT = BASE_DIR / 'static'
MEDIA_ROOT = BASE_DIR / 'media'
MEDIA_URL = '/media/'

View File

@ -18,7 +18,7 @@ from django.urls import include, path
urlpatterns = [
path('', include('home.urls')),
path('categories/', include('categories.urls')),
path('taxonomy/', include('categories.urls')),
path('artists/', include('artists.urls')),
path('songs/', include('songs.urls')),
path('admin/', admin.site.urls),

View File

@ -0,0 +1,18 @@
# Generated by Django 3.1.4 on 2020-12-16 15:17
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('artists', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='artist',
name='slug',
field=models.SlugField(blank=True, max_length=255),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 3.1.4 on 2020-12-16 16:22
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('artists', '0002_artist_slug'),
]
operations = [
migrations.AlterField(
model_name='artist',
name='romanized_name',
field=models.CharField(max_length=255),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 3.1.4 on 2020-12-16 16:33
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('artists', '0003_auto_20201216_1622'),
]
operations = [
migrations.RenameField(
model_name='artist',
old_name='about_composer',
new_name='about_artist',
),
]

View File

@ -1,5 +1,6 @@
from django.db import models
from django.apps import apps
from django.utils.text import slugify
# Create your models here.
class ArtistManager(models.Manager):
@ -20,10 +21,11 @@ class ArtistManager(models.Manager):
class Artist(models.Model):
name = models.CharField(max_length=255,blank=True)
romanized_name = models.CharField(max_length=255,blank=True)
romanized_name = models.CharField(max_length=255)
slug = models.SlugField(max_length=255,blank=True)
aliases = models.ManyToManyField("self",blank=True)
category = models.ManyToManyField("categories.Category",blank=True)
about_composer = models.TextField(blank=True)
about_artist = models.TextField(blank=True)
about_music = models.TextField(blank=True)
objects = ArtistManager()
@ -33,3 +35,7 @@ class Artist(models.Model):
def __str__(self):
return self.romanized_name
def save(self, *args, **kwargs):
self.slug = slugify(self.romanized_name)
super().save(*args,**kwargs)

View File

@ -0,0 +1,12 @@
{% extends 'layouts/base.html' %}
{% block title %} Artists {% endblock %}
{% block content %}
<h1>Artists</h1>
<ul>
{% for artist in artists %}
<li><a href="/artists/{{ artist.slug }}">{{ artist.romanized_name }}</a></li>
{% endfor %}
</ul>
{% endblock %}

View File

@ -0,0 +1,60 @@
{% extends 'layouts/base.html' %}
{% block title %} Artist: {{ artist.romanized_name }} {% endblock %}
{% block content %}
<h1>Artist: {{ artist.romanized_name }}</h1>
<h2>Metadata</h2>
<table class="table">
<tbody>
{% if artist.name %}
<tr>
<th scope="row">
Name
</th>
<td>
{{ artist.name }}
</td>
</tr>
{% endif %}
{% if artist.romanized_name %}
<tr>
<th scope="row">
Romanized Name
</th>
<td>
{{ artist.romanized_name }}
</td>
</tr>
{% endif %}
{% for alias in artist.aliases.all %}
<tr>
<th scope="row">
Alias
</th>
<td>
<a href="/artists/{{ alias.id }}">{{ alias.romanized_name }}</a>
</td>
</tr>
{% endfor %}
{% for category in artist.category.all %}
<tr>
<th scope="row">
Category
</th>
<td>
<a href="/taxonomy/categories/{{ category.slug }}">{{ category.name }}</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<h2>About Artist</h2>
<p>{{ artist.about_artist }}</p>
<h2>About Music</h2>
<p>{{ artist.about_music }}</p>
<h2>Credits</h2>
{% include 'components/song-table.html' with songs=credit_songs %}
<h2>Sample works outside Idolmaster</h2>
{% include 'components/outside-song-table.html' with outside_songs=outside_songs %}
{% endblock %}

View File

@ -3,4 +3,6 @@ from django.urls import path
from . import views
urlpatterns = [
path('',views.artist_index),
path('<slug:slug>',views.artist_show)
]

View File

@ -1,3 +1,15 @@
from django.shortcuts import render
# Create your views here.
from .models import Artist
from songs.models import OutsideSong
def artist_index(request):
artists = Artist.objects.all()
return render(request,'artists/index.html',{'artists':artists})
def artist_show(request, slug):
artist = Artist.objects.filter(slug=slug)[0]
credit_songs = (artist.written_songs.all() | artist.composed_songs.all() | artist.arranged_songs.all()).distinct()
outside_songs = OutsideSong.objects.filter(composer=artist)
return render(request,'artists/show.html',{'artist': artist,'credit_songs':credit_songs,'outside_songs':outside_songs})

View File

@ -0,0 +1,19 @@
# Generated by Django 3.1.4 on 2020-12-16 15:17
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('categories', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='category',
name='slug',
field=models.SlugField(default='', max_length=255),
preserve_default=False,
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 3.1.4 on 2020-12-16 16:13
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('categories', '0002_category_slug'),
]
operations = [
migrations.AddField(
model_name='branch',
name='description',
field=models.TextField(blank=True),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 3.1.4 on 2020-12-16 16:22
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('categories', '0003_branch_description'),
]
operations = [
migrations.AlterField(
model_name='branch',
name='acronym',
field=models.CharField(max_length=20),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 3.1.4 on 2020-12-16 16:46
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('categories', '0004_auto_20201216_1622'),
]
operations = [
migrations.AddField(
model_name='branch',
name='color',
field=models.CharField(default='#ffffff', max_length=10),
),
]

View File

@ -0,0 +1,23 @@
# Generated by Django 3.1.4 on 2020-12-16 16:50
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('categories', '0005_branch_color'),
]
operations = [
migrations.RenameField(
model_name='branch',
old_name='color',
new_name='background_color',
),
migrations.AddField(
model_name='branch',
name='foreground_color',
field=models.CharField(default='#000000', max_length=10),
),
]

View File

@ -0,0 +1,26 @@
# Generated by Django 3.1.4 on 2020-12-16 17:07
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('categories', '0006_auto_20201216_1650'),
]
operations = [
migrations.RemoveField(
model_name='branch',
name='background_color',
),
migrations.RemoveField(
model_name='branch',
name='foreground_color',
),
migrations.AddField(
model_name='branch',
name='logo',
field=models.ImageField(blank=True, upload_to='logo'),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 3.1.4 on 2020-12-16 17:28
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('categories', '0007_auto_20201216_1707'),
]
operations = [
migrations.AlterField(
model_name='branch',
name='logo',
field=models.ImageField(blank=True, upload_to='media/logo'),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 3.1.4 on 2020-12-16 17:32
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('categories', '0008_auto_20201216_1728'),
]
operations = [
migrations.AlterField(
model_name='branch',
name='logo',
field=models.ImageField(blank=True, upload_to='logo'),
),
]

View File

@ -1,8 +1,11 @@
from django.db import models
from django.utils.text import slugify
class Branch(models.Model):
name = models.CharField(max_length=255,blank=True)
acronym = models.CharField(max_length=20,blank=True)
acronym = models.CharField(max_length=20)
description = models.TextField(blank=True)
logo = models.ImageField(upload_to="logo",blank=True)
def __str__(self):
return self.name+" ["+self.acronym+"]"
@ -26,6 +29,7 @@ class CategoryManager(models.Manager):
class Category(models.Model):
name = models.CharField(max_length=255)
slug = models.SlugField(max_length=255)
description = models.TextField(blank=True)
objects = CategoryManager()
@ -37,3 +41,7 @@ class Category(models.Model):
def __str__(self):
return self.name
def save(self, *args, **kwargs):
self.slug = slugify(self.name)
super().save(*args,**kwargs)

View File

@ -0,0 +1,26 @@
{% extends 'layouts/base.html' %}
{% block title %}Branches{% endblock %}
{% block content %}
<h1>Branches</h1>
<table class="table">
<thead>
<th>Acronym</th>
<th>Logo</th>
<th>Name</th>
</thead>
<tbody>
{% for branch in branches %}
<tr>
<td>{{ branch.acronym }}</td>
<td>
{% if branch.logo %}
<img src="{{ branch.logo.path }}" width=24>
{% endif %}
</td>
<td><a href="/taxonomy/branches/{{ branch.acronym }}">{{ branch.name }} [{{ branch.acronym }}]</a></td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}

View File

@ -0,0 +1,9 @@
{% extends 'layouts/base.html' %}
{% block content %}
<h1>[{{ branch.acronym }}] {{ branch.name }}</h1>
<h2>Description</h2>
<p>{{ branch.description }}</p>
<h2>Songs</h2>
{% include 'components/song-table.html' with songs=songs %}
{% endblock %}

View File

@ -0,0 +1,12 @@
{% extends 'layouts/base.html' %}
{% block title %} Categories {% endblock %}
{% block content %}
<h1>Categories</h1>
<ul>
{% for category in categories %}
<li><a href="/taxonomy/categories/{{ category.slug }}">{{ category.name }}</a></li>
{% endfor %}
</ul>
{% endblock %}

View File

@ -0,0 +1,15 @@
{% extends 'layouts/base.html' %}
{% block title %} Category: {{ category.name }} {% endblock %}
{% block content %}
<h1>Category: {{ category.name }}</h1>
<h2>Description</h2>
<p>{{ category.description }}</p>
<h2>Artists</h2>
<ul>
{% for artist in category.artist_set.all %}
<li><a href="/artists/{{ artist.slug }}">{{ artist.romanized_name }}</a></li>
{% endfor %}
</ul>
{% endblock %}

View File

@ -3,4 +3,8 @@ from django.urls import path
from . import views
urlpatterns = [
path('categories',views.category_index),
path('categories/<slug:slug>',views.category_show),
path('branches',views.branch_index),
path('branches/<str:acronym>',views.branch_show),
]

View File

@ -1,6 +1,23 @@
from django.shortcuts import render
from django.http import HttpResponse
from .models import Branch, Category
from songs.models import Song
from artists.models import Artist
# Create your views here.
def index(request):
return HttpResponse("Yuika!")
def category_index(request):
categories = Category.objects.all()
return render(request,"categories/index.html",{'categories':categories})
def category_show(request, slug):
category = Category.objects.filter(slug=slug)[0]
return render(request,"categories/show.html",{'category':category})
def branch_index(request):
branches = Branch.objects.all()
return render(request,"branches/index.html",{'branches':branches})
def branch_show(request, acronym):
branch = Branch.objects.filter(acronym=acronym)[0]
songs = Song.objects.filter(branch=branch)
return render(request,"branches/show.html",{'branch':branch,'songs':songs})

View File

@ -9,7 +9,7 @@
<ul>
<li>Complete lyricist credits</li>
<li>Add songs from IDOLM@STER Radio</li>
<li>Readd other songs that I might have missed</li>
<li>Re-add other songs that I might have missed</li>
<li>Complete showcases of composers</li>
</ul>
{% endblock %}

View File

@ -4,5 +4,4 @@ from . import views
urlpatterns = [
path('',views.index),
path('home',views.index),
]

2
media/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*
!.gitignore

View File

@ -0,0 +1,40 @@
# Generated by Django 3.1.4 on 2020-12-16 16:22
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('categories', '0004_auto_20201216_1622'),
('songs', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='outsidesong',
name='origin',
field=models.CharField(max_length=255),
),
migrations.AlterField(
model_name='outsidesong',
name='title',
field=models.CharField(max_length=255),
),
migrations.AlterField(
model_name='outsidesong',
name='url',
field=models.URLField(max_length=255),
),
migrations.AlterField(
model_name='song',
name='branch',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='categories.branch'),
),
migrations.AlterField(
model_name='song',
name='romanized_title',
field=models.CharField(max_length=255),
),
]

View File

@ -3,9 +3,9 @@ from django.db import models
# Create your models here.
class Song(models.Model):
branch = models.ForeignKey("categories.Branch", blank=True, on_delete=models.PROTECT)
branch = models.ForeignKey("categories.Branch", on_delete=models.PROTECT)
title = models.CharField(max_length=255,blank=True)
romanized_title = models.CharField(max_length=255,blank=True)
romanized_title = models.CharField(max_length=255)
lyricist = models.ManyToManyField("artists.Artist", blank=True, related_name="written_songs")
composer = models.ManyToManyField("artists.Artist", blank=True, related_name="composed_songs")
arranger = models.ManyToManyField("artists.Artist", blank=True, related_name="arranged_songs")
@ -18,10 +18,10 @@ class Song(models.Model):
return "["+self.branch.acronym+"] "+self.title
class OutsideSong(models.Model):
title = models.CharField(max_length=255,blank=True)
title = models.CharField(max_length=255)
artist = models.CharField(max_length=255,blank=True)
origin = models.CharField(max_length=255,blank=True)
url = models.URLField(max_length=255,blank=True)
origin = models.CharField(max_length=255)
url = models.URLField(max_length=255)
composer = models.ForeignKey("artists.Artist", blank=True, on_delete=models.CASCADE)
class Meta:

View File

@ -0,0 +1,10 @@
{% extends 'layouts/base.html' %}
{% block title %} Songs {% endblock %}
{% block content %}
<h1>Songs</h1>
<ul>
{% include 'components/song-table.html' with songs=songs %}
</ul>
{% endblock %}

View File

@ -0,0 +1,50 @@
{% extends 'layouts/base.html' %}
{% block title %} Song: {{ song.title }} {% endblock %}
{% block content %}
<h1>{{ song.title }}</h1>
<h2>Metadata</h2>
<table class="table">
<tbody>
{% if song.branch %}
<tr>
<th scope="row">Branch</th>
<td><a href="/taxonomy/branches/{{ song.branch.acronym }}">[{{ song.branch.acronym }}] {{ song.branch.name }}</a></td>
</tr>
{% endif %}
{% if song.title %}
<tr>
<th scope="row">Title</th>
<td>{{ song.title }}</td>
</tr>
{% endif %}
{% if song.romanized_title %}
<tr>
<th scope="row">Romanized Title</th>
<td>{{ song.romanized_title }}</td>
</tr>
{% endif %}
{% for lyricist in song.lyricist.all %}
<tr>
<th scope="row">Lyricist</th>
<td><a href="/artists/{{ lyricist.slug }}">{{ lyricist.romanized_name }}</a></td>
</tr>
{% endfor %}
{% for composer in song.composer.all %}
<tr>
<th scope="row">Composer</th>
<td><a href="/artists/{{ composer.slug }}">{{ composer.romanized_name }}</a></td>
</tr>
{% endfor %}
{% for arranger in song.arranger.all %}
<tr>
<th scope="row">Arranger</th>
<td><a href="/artists/{{ arranger.slug }}">{{ arranger.romanized_name }}</a></td>
</tr>
{% endfor %}
</tbody>
</table>
<h2>Impression</h2>
<p>{{ song.impression }}</p>
{% endblock %}

View File

@ -3,4 +3,7 @@ from django.urls import path
from . import views
urlpatterns = [
path('',views.song_index),
path('<int:id>',views.song_id),
path('<int:id>/<str:title>',views.song_show),
]

View File

@ -1,3 +1,15 @@
from django.shortcuts import render
from django.shortcuts import render, redirect
from .models import Song
# Create your views here.
def song_index(request):
songs = Song.objects.all()
return render(request,'songs/index.html',{'songs':songs})
def song_id(request, id):
song = Song.objects.filter(id=id)[0]
return redirect(song_show,id=song.id,title=song.title)
def song_show(request, id, title):
song = Song.objects.filter(id=id,title=title)[0]
return render(request,'songs/show.html',{'song':song})

View File

@ -0,0 +1,18 @@
<table class="table">
<thead>
<th class="col-4">Title</th>
<th>Artist</th>
<th>Origin</th>
<th class="col-2">Link</th>
</thead>
<tbody>
{% for song in outside_songs %}
<tr>
<td>{{ song.title }}</td>
<td>{{ song.artist }}</td>
<td>{{ song.origin }}</td>
<td><a href="{{ song.url }}">Open</a></td>
</tr>
{% endfor %}
</tbody>
</table>

View File

@ -0,0 +1,42 @@
<table class="table">
<thead>
<th class="col-1">Branch</th>
<th class="col-4">Song Title</th>
<th>Lyricist</th>
<th>Composer</th>
<th>Arranger</th>
</thead>
<tbody>
{% for song in songs %}
<tr>
<td>
{% if song.branch.logo %}
<a href="/taxonomy/branches/{{ song.branch.acronym }}">
<img src="{{ song.branch.logo.url }}" width=24>
</a>
{% else %}
<a href="/taxonomy/branches/{{ song.branch.acronym }}">{{ song.branch.acronym }}</a>
{% endif %}
</td>
<td>
<a href="/songs/{{ song.id }}/{{ song.title }}">{{ song.title }}</a>
</td>
<td>
{% for artist in song.lyricist.all %}
<a href="/artists/{{ artist.slug }}">{{ artist.romanized_name }}</a><br/>
{% endfor %}
</td>
<td>
{% for artist in song.composer.all %}
<a href="/artists/{{ artist.slug }}">{{ artist.romanized_name }}</a><br/>
{% endfor %}
</td>
<td>
{% for artist in song.arranger.all %}
<a href="/artists/{{ artist.slug }}">{{ artist.romanized_name }}</a><br/>
{% endfor %}
</td>
</tr>
{% endfor %}
</tbody>
</table>

View File

@ -4,7 +4,9 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Altessimo</title>
<title>
{% block title %} Altessimo {% endblock %}
</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
</head>
@ -22,6 +24,18 @@
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="/">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/songs">Songs</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/artists">Artists</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/taxonomy/categories">Categories</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/taxonomy/branches">Branches</a>
</li>
</ul>
</div>
</div>