Browse Source

New, better changelogs (#697)

New models for representing changelogs, designed so that I could write
an entry once and have it appear on multiple lists' changelogs.
master
parent
commit
011d35d1c3
Signed by: hristoast GPG Key ID: 5FC7664AD47AA1C5
  1. 2
      bin/seed_db.py
  2. 64
      momw/momw/data_seeds/changelogs.py
  3. 69
      momw/momw/migrations/0025_changelog_changelogentry.py
  4. 42
      momw/momw/models.py
  5. 15
      momw/momw/templates/changelogs.html
  6. 1
      momw/momw/templates/index.html
  7. 16
      momw/momw/templates/mod_list_changelog.html
  8. 4
      momw/momw/templates/mod_list_detail.html
  9. 5
      momw/momw/urls.py
  10. 21
      momw/momw/views/dynamicpages.py

2
bin/seed_db.py

@ -18,6 +18,7 @@ from momw.data_seeds.blog import (
blog_tag_factory,
blog_entry_factory,
)
from momw.data_seeds.changelogs import changelogs
from momw.data_seeds.media import media_factory
from momw.data_seeds.mod_categories import mod_cats
from momw.data_seeds.mod_datapaths import data_path_load_order
@ -112,6 +113,7 @@ def main():
run(mod_lists)
run(plugins_load_order)
run(data_path_load_order)
run(changelogs)
info("Finished {} db seed!".format(settings.PROJECT_NAME.upper()))

64
momw/momw/data_seeds/changelogs.py

@ -0,0 +1,64 @@
from momw.models import Changelog, ChangelogEntry, ModList
def generate_changelog(version: str, entries: tuple) -> None:
c = Changelog(version=version)
c.save()
for e in entries:
generate_changelog_entry(c.pk, e)
def generate_changelog_entry(cl_pk: int, data: dict) -> ChangelogEntry:
modlists = ModList.objects.filter(title__in=data["modlists"])
data.pop("modlists")
data["changelog_id"] = cl_pk
c = ChangelogEntry(**data)
c.save()
for ml in modlists:
c.modlists.add(ml)
c.save()
return c
def changelogs():
expanded_vanilla = "Expanded Vanilla"
graphics_overhaul = "Graphics Overhaul"
i_heart_vanilla = "I Heart Vanilla"
i_heart_vanilla_dc = "I Heart Vanilla: Director's Cut"
total_overhaul = "Total Overhaul"
generate_changelog(
"3.29",
(
{
"text": """New changelog feature to better show what has changed on each list over time.""",
"date": "2021-06-05",
"modlists": [
expanded_vanilla,
graphics_overhaul,
i_heart_vanilla,
i_heart_vanilla_dc,
total_overhaul,
],
"kind": ChangelogEntry.ADDED,
},
{
"text": """Removed two manual edit steps from <a href="/mods/dagoth-ur-voice-addon-v10/">Dagoth Ur Voice addon v10</a>, they aren't needed when objects are properly merged.""",
"date": "2021-06-04",
"modlists": [total_overhaul, expanded_vanilla, graphics_overhaul],
"kind": ChangelogEntry.UPDATED,
},
{
"text": """<a href="/mods/natural-character-growth-and-decay-mw/">Natural Character Growth and Decay</a> was updated to version 3.3, fixing some bugs with attribute calculations. Thanks to Atahualpa for the fix!""",
"date": "2021-05-30",
"modlists": [total_overhaul, expanded_vanilla],
"kind": ChangelogEntry.UPDATED,
},
{
"text": """<a href="/mods/vanilla-inspired-water-for-openmw/">Vanilla Inspired Water for OpenMW</a>.""",
"date": "2021-05-16",
"modlists": [i_heart_vanilla, i_heart_vanilla_dc],
"kind": ChangelogEntry.ADDED,
},
),
)

69
momw/momw/migrations/0025_changelog_changelogentry.py

@ -0,0 +1,69 @@
# Generated by Django 3.0.8 on 2021-06-06 00:26
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [("momw", "0024_auto_20210507_1354")]
operations = [
migrations.CreateModel(
name="Changelog",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("version", models.CharField(max_length=20)),
],
options={
"verbose_name": "Changelog",
"verbose_name_plural": "Changelog",
"db_table": "changelogs",
"ordering": ["-version"],
},
),
migrations.CreateModel(
name="ChangelogEntry",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"kind",
models.IntegerField(
choices=[(1, "Added"), (2, "Removed"), (3, "Updated")],
default=1,
),
),
("text", models.TextField()),
("date", models.DateField()),
(
"changelog",
models.ForeignKey(
on_delete=django.db.models.deletion.PROTECT, to="momw.Changelog"
),
),
("modlists", models.ManyToManyField(to="momw.ModList")),
],
options={
"verbose_name": "Changelog Entry",
"verbose_name_plural": "Changelog Entries",
"db_table": "changelog_entries",
"ordering": ["pk"],
},
),
]

42
momw/momw/models.py

@ -513,3 +513,45 @@ class TaggedMod(GenericTaggedItemBase):
class Meta:
db_table = "tagged_mods"
class Changelog(models.Model):
version = models.CharField(max_length=20)
class Meta:
db_table = "changelogs"
ordering = ["-version"]
verbose_name = _("Changelog")
verbose_name_plural = _("Changelog")
def __str__(self):
return "{} Changelog: {}".format(self.mod_list.title, self.version)
class ChangelogEntry(models.Model):
ADDED = 1
REMOVED = 2
UPDATED = 3
KIND_CHOICES = ((ADDED, "Added"), (REMOVED, "Removed"), (UPDATED, "Updated"))
kind = models.IntegerField(choices=KIND_CHOICES, default=ADDED)
modlists = models.ManyToManyField(ModList)
text = models.TextField()
changelog = models.ForeignKey(Changelog, on_delete=models.PROTECT)
date = models.DateField()
class Meta:
db_table = "changelog_entries"
ordering = ["pk"]
verbose_name = _("Changelog Entry")
verbose_name_plural = _("Changelog Entries")
def __str__(self):
return "{} {}: {}".format(
self.KIND_CHOICES[self.kind - 1][1].upper(), self.date, self.text
)
@property
def fulltext(self):
return '<span class="bold">{} {}</span>: {}'.format(
self.KIND_CHOICES[self.kind - 1][1].upper(), self.date, self.text
)

15
momw/momw/templates/changelogs.html

@ -0,0 +1,15 @@
{% extends 'base.html' %}
{% block title %}Mod List Changelogs{% endblock %}
{% block content %}
<h2>Mod List Changelogs</h2>
<ul>
<li><a href="{% url 'mod-list-changelog' slug='expanded-vanilla' %}">Expanded Vanilla</a></li>
<li><a href="{% url 'mod-list-changelog' slug='graphics-overhaul' %}">Graphics Overhaul</a></li>
<li><a href="{% url 'mod-list-changelog' slug='i-heart-vanilla' %}">I Heart Vanilla</a></li>
<li><a href="{% url 'mod-list-changelog' slug='i-heart-vanilla-directors-cut' %}">I Heart Vanilla: Director's Cut</a></li>
<li><a href="{% url 'mod-list-changelog' slug='total-overhaul' %}">Total Overhaul</a></li>
</ul>
{% endblock %}

1
momw/momw/templates/index.html

@ -20,6 +20,7 @@
<a class="button button-primary" href="{% url 'mod-list-detail' slug='i-heart-vanilla' %}">I Heart Vanilla</a>
{# <a class="button button-primary" href="{% url 'mod-list-detail' slug='tes3mp-server' %}">TES3MP Server</a> #}
<a class="button button-primary" href="{% url 'mod-lists' %}">Browse All Lists</a>
<a class="button button-primary" href="{% url 'changelogs' %}">List Changelogs</a>
</div>
<div class="line" style="margin-top: 14px;"></div>

16
momw/momw/templates/mod_list_changelog.html

@ -0,0 +1,16 @@
{% extends 'base.html' %}
{% block title %}{{ mod_list_title }} Changelog{% endblock %}
{% block content %}
<h1><span class="bold">{{ mod_list_title }}</span> Changelog</h1>
<p><a href="{% url 'changelogs' %}">View all list changelogs</a></p>
{% for cl in c %}
<h2>
Release: <span class="bold">{{ cl.version }}</span>
</h2>
<ul>
{% for entry in cl.entries %}
<li>{{ entry.fulltext|safe }}</li>
{% endfor %}
</ul>
{% endfor %}
{% endblock %}

4
momw/momw/templates/mod_list_detail.html

@ -14,8 +14,8 @@
</p>
<p class="center">
{% if modlist_is_parent %}
<a class="button button-primary" href="https://git.modding-openmw.com/Modding-OpenMW.com/momw/commits/branch/{% if momw_ver %}beta{% else %}master{% endif %}/momw/momw/data_seeds/data/{% if mod_list.slug == 'androidswitch' %}android{% elif mod_list.slug == 'i-heart-vanilla-directors-cut' %}i-heart-vanilla-dc{% else %}{{ mod_list.slug }}{% endif %}.{% if mod_list.slug == 'total-overhaul' %}toml{% else %}yml{% endif %}" title="This button takes you to the change log for this mod list. Note that the log is in the form of a raw git log.">
{% if modlist_is_parent or not mod_list.parent_list %}
<a class="button button-primary" href="{% url 'mod-list-changelog' slug=mod_list.slug %}" title="This button takes you to the change log for this mod list..">
View list changelog
</a>

5
momw/momw/urls.py

@ -17,6 +17,7 @@ from .views.dynamicpages import (
latest_mods,
mod_alts,
mod_detail,
mod_list_changelog,
mod_list_detail,
mod_list_final,
mod_list_step_detail,
@ -42,6 +43,9 @@ urlpatterns = [
path("cfg-generator/", cfg_generator, name="cfg_generator"),
path("cfg/generator/", cfg_generator, name="cfg_generator2"),
path("cfg/", cfg_generator, name="cfg_generator3"),
path(
"changelogs/", static_view, {"template": "changelogs.html"}, name="changelogs"
),
path(
"compatibility/",
static_view,
@ -111,6 +115,7 @@ urlpatterns = [
),
# END legacy list URLs
path("lists/<slug:slug>/", mod_list_detail, name="mod-list-detail"),
path("lists/<slug:slug>/changelog", mod_list_changelog, name="mod-list-changelog"),
path("lists/<slug:slug>/final", mod_list_final, name="mod-list-final"),
path(
"lists/<slug:slug>/<int:step>/",

21
momw/momw/views/dynamicpages.py

@ -4,7 +4,7 @@ from django.shortcuts import get_object_or_404, redirect, render
from django.views.decorators.cache import cache_page
from ..cfg import get_visitor_os
from ..helpers import paginator_for_queryset
from ..models import Category, ListedMod, Mod, ModList, Tag
from ..models import Category, Changelog, ChangelogEntry, ListedMod, Mod, ModList, Tag
CLEAN_EXCEPTIONS = ("Better Robes.ESP", "Quill of Feyfolken 2.0-OpenMW-Patch.omwaddon")
@ -155,6 +155,25 @@ def mod_list_detail(request, slug):
)
@cache_page(settings.CACHE_MIDDLEWARE_SECONDS)
def mod_list_changelog(request, slug):
c = []
ml = get_object_or_404(ModList, slug=slug)
for changelog in Changelog.objects.all():
c.append(
{
"version": changelog.version,
"entries": ChangelogEntry.objects.select_related("changelog").filter(
modlists__in=[ml], changelog__version=changelog.version
),
}
)
return render(
request, "mod_list_changelog.html", {"c": c, "mod_list_title": ml.title}
)
@cache_page(settings.CACHE_MIDDLEWARE_SECONDS)
def mod_list_final(request, slug):
modlist = get_object_or_404(ModList, slug=slug)

Loading…
Cancel
Save