Merge lp:~widelands-dev/widelands-website/move_maps_minimap into lp:widelands-website

Proposed by kaputtnik
Status: Merged
Merged at revision: 545
Proposed branch: lp:~widelands-dev/widelands-website/move_maps_minimap
Merge into: lp:widelands-website
Diff against target: 247 lines (+124/-22)
7 files modified
wlmaps/admin.py (+13/-1)
wlmaps/forms.py (+15/-6)
wlmaps/migrations/0003_auto_20190712_0928.py (+65/-0)
wlmaps/models.py (+16/-1)
wlmaps/templates/wlmaps/index.html (+3/-7)
wlmaps/templates/wlmaps/inlines/version_info.html (+11/-0)
wlmaps/templates/wlmaps/map_detail.html (+1/-7)
To merge this branch: bzr merge lp:~widelands-dev/widelands-website/move_maps_minimap
Reviewer Review Type Date Requested Status
kaputtnik (community) Needs Resubmitting
GunChleoc Approve
Review via email: mp+370039@code.launchpad.net

Commit message

Move minimaps to wlmaps/minimaps
Implemented the new value needs_version_after
Delete map files (.wmf and .png) when deleting a map from the database

Description of the change

The maps minimaps are now moved to wlmaps/minimaps. This fixes also creating a faulty path in the database for the minimaps (beginning with a slash).

Deleting a map does now delete the related files.

The new value of 'needs_version_after' produced by wl_map_info is now considered. There is now an inline html file for this, so the logic is in one file.

The changes related to minimaps need manual intervention regarding the files and the database entries:

- All png files in MEDIA_ROOT/wlmaps/maps/ needs moving to MEDIA_ROOT/wlmaps/minimaps/
- Database entries for minimaps need to be changed from
  '/wlmaps/maps/NAME.png'
  to
  'wlmaps/minimaps/NAME.png'

To get this in:
- set maintenance
- backup the database
- backup the files from MEDIA_ROOT/wlmaps/
- run ./manage.py migrate
- move the png files
- correct the path(s) in the database. I want to change also some bad entries for the mapfiles. With activated virtualenvironment:

./manage.py shell
from wlmaps.models import Map
maps = Map.objects.all()
for m in maps:
    if m.minimap.name.startswith('/'):
        new_name = m.minimap.name.rpartition('/')[2]
        m.minimap = 'wlmaps/minimaps/{}'.format(new_name)
        m.save()

maps = Map.objects.all()
for m in maps:
    if m.file.name.startswith('/var/www'):
        new_name = m.file.name.rpartition('/')[2]
        m.file = 'wlmaps/maps/{}'.format(new_name)
        m.save()

This can maybe done also in one loop (changing minimap and file), but i fear saving an object twice in one loop can be problematic, although at home it works nicely.

To post a comment you must log in.
Revision history for this message
GunChleoc (gunchleoc) wrote :

LGTM :)

review: Approve
548. By kaputtnik

merged with trunk

Revision history for this message
kaputtnik (franku) wrote :

I have to test a bit more before merging this. On my second computer i get some errors after merging this branch.

review: Needs Fixing
549. By kaputtnik

use a custom delete function instead of signals

Revision history for this message
kaputtnik (franku) wrote :

A better solution: Using signals, especially when deleting files, can lead into some sideeffects. So i have implemented a custom delete() function which is much better, imho.

review: Needs Resubmitting
550. By kaputtnik

merged with trunk

Revision history for this message
GunChleoc (gunchleoc) wrote :

LGTM :)

Revision history for this message
kaputtnik (franku) wrote :

Thanks :-)

Merged and deployed.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'wlmaps/admin.py'
2--- wlmaps/admin.py 2019-04-11 15:06:09 +0000
3+++ wlmaps/admin.py 2019-07-15 06:06:57 +0000
4@@ -5,8 +5,20 @@
5 from .models import Map
6 from django.contrib import admin
7
8+def delete_selected(modeladmin, request, queryset):
9+ """Overwritten Django's default action to delete a map.
10+
11+ This action uses the delete() method of the map model. This ensures
12+ also deleting the corresponding files (.wmf and .png) of a map.
13+
14+ """
15+ for obj in queryset:
16+ obj.delete()
17+delete_selected.short_description = 'Delete selected maps'
18+
19
20 class MapAdmin(admin.ModelAdmin):
21+ actions = [delete_selected,]
22 list_display = ['name', 'author', 'pub_date']
23 prepopulated_fields = {'slug': ('name',)}
24 search_fields = ['name', 'author']
25@@ -14,7 +26,7 @@
26 readonly_fields = ('uploader', 'nr_players', 'w', 'h', 'minimap', 'file', 'world_name')
27 fieldsets = (
28 (None, {
29- 'fields': (('name', 'author'), 'uploader', 'uploader_comment')
30+ 'fields': (('name', 'author'), 'uploader', 'uploader_comment', 'wl_version_after')
31 }),
32 ('Map properties', {
33 'classes': ('collapse',),
34
35=== modified file 'wlmaps/forms.py'
36--- wlmaps/forms.py 2019-03-31 11:08:21 +0000
37+++ wlmaps/forms.py 2019-07-15 06:06:57 +0000
38@@ -11,6 +11,8 @@
39
40 from wlmaps.models import Map
41 import os
42+import shutil
43+
44
45 class UploadMapForm(ModelForm):
46 """
47@@ -59,8 +61,8 @@
48 os.chdir(settings.WIDELANDS_SVN_DIR)
49 check_call(['wl_map_info', saved_file])
50
51- # TODO(shevonar): delete file because it will be saved again when
52- # the model is saved. File should not be saved twice
53+ # Deleting the file because it will be saved again when
54+ # the model is saved.
55 default_storage.delete(saved_file)
56 os.chdir(old_cwd)
57 except CalledProcessError:
58@@ -86,11 +88,18 @@
59 self.instance.descr = mapinfo['description']
60 self.instance.hint = mapinfo['hint']
61 self.instance.world_name = mapinfo['world_name']
62+ self.instance.wl_version_after = mapinfo['needs_widelands_version_after']
63
64- # mapinfo["minimap"] is an absolute path.
65- # We partition it to get the correct file path
66- minimap_path = mapinfo['minimap'].partition(settings.MEDIA_ROOT)[2]
67- self.instance.minimap = '/' + minimap_path
68+ # mapinfo["minimap"] is the absolute path containing the path where it
69+ # is saved, extract the name
70+ minimap_name = mapinfo['minimap'].rpartition('/')[2]
71+ minimap_upload_to = self.instance._meta.get_field('minimap').upload_to
72+ # Set the destination relative to MEDIA_ROOT
73+ minimap_path = os.path.join(minimap_upload_to, minimap_name)
74+ self.instance.minimap = minimap_path
75+ # Move the minimap file (.png) from wlmaps/maps to wlmaps/minimaps
76+ shutil.move(mapinfo['minimap'], os.path.join(
77+ settings.MEDIA_ROOT, minimap_path))
78
79 # the json file is no longer needed
80 default_storage.delete(saved_file + '.json')
81
82=== added file 'wlmaps/migrations/0003_auto_20190712_0928.py'
83--- wlmaps/migrations/0003_auto_20190712_0928.py 1970-01-01 00:00:00 +0000
84+++ wlmaps/migrations/0003_auto_20190712_0928.py 2019-07-15 06:06:57 +0000
85@@ -0,0 +1,65 @@
86+# -*- coding: utf-8 -*-
87+# Generated by Django 1.11.22 on 2019-07-12 09:28
88+from __future__ import unicode_literals
89+
90+from django.db import migrations, models
91+
92+
93+class Migration(migrations.Migration):
94+
95+ dependencies = [
96+ ('wlmaps', '0002_auto_20181119_1855'),
97+ ]
98+
99+ operations = [
100+ migrations.AddField(
101+ model_name='map',
102+ name='wl_version_after',
103+ field=models.PositiveIntegerField(blank=True, null=True, verbose_name='WL version after'),
104+ ),
105+ migrations.AlterField(
106+ model_name='map',
107+ name='descr',
108+ field=models.TextField(verbose_name='Description'),
109+ ),
110+ migrations.AlterField(
111+ model_name='map',
112+ name='file',
113+ field=models.FileField(upload_to='wlmaps/maps', verbose_name='Mapfile'),
114+ ),
115+ migrations.AlterField(
116+ model_name='map',
117+ name='h',
118+ field=models.PositiveIntegerField(verbose_name='Height'),
119+ ),
120+ migrations.AlterField(
121+ model_name='map',
122+ name='hint',
123+ field=models.TextField(blank=True, verbose_name='Hint'),
124+ ),
125+ migrations.AlterField(
126+ model_name='map',
127+ name='minimap',
128+ field=models.ImageField(upload_to='wlmaps/minimaps', verbose_name='Minimap'),
129+ ),
130+ migrations.AlterField(
131+ model_name='map',
132+ name='nr_downloads',
133+ field=models.PositiveIntegerField(default=0, verbose_name='Download count'),
134+ ),
135+ migrations.AlterField(
136+ model_name='map',
137+ name='nr_players',
138+ field=models.PositiveIntegerField(verbose_name='Max Players'),
139+ ),
140+ migrations.AlterField(
141+ model_name='map',
142+ name='uploader_comment',
143+ field=models.TextField(blank=True, verbose_name='Uploader comment'),
144+ ),
145+ migrations.AlterField(
146+ model_name='map',
147+ name='w',
148+ field=models.PositiveIntegerField(verbose_name='Width'),
149+ ),
150+ ]
151
152=== modified file 'wlmaps/models.py'
153--- wlmaps/models.py 2019-04-11 15:20:33 +0000
154+++ wlmaps/models.py 2019-07-15 06:06:57 +0000
155@@ -5,7 +5,11 @@
156 from django.contrib.auth.models import User
157 from django.template.defaultfilters import slugify
158 from django.urls import reverse
159+from django.db.models.signals import pre_delete
160+from django.conf import settings
161+
162 import datetime
163+import os
164 try:
165 from notification import models as notification
166 except ImportError:
167@@ -35,7 +39,10 @@
168 uploader = models.ForeignKey(User)
169 nr_downloads = models.PositiveIntegerField(
170 verbose_name='Download count', default=0)
171-
172+ wl_version_after = models.PositiveIntegerField(
173+ verbose_name='WL version after',
174+ null=True,
175+ blank=True)
176
177 class Meta:
178 ordering = ('-pub_date',)
179@@ -72,3 +79,11 @@
180 )
181
182 return map
183+
184+ def delete(self, *args, **kwargs):
185+ """Delete also corresponding map files."""
186+
187+ # For some reason this throws no error if a file didn't exist
188+ self.minimap.delete()
189+ self.file.delete()
190+ super(Map, self).delete(*args, **kwargs)
191
192=== modified file 'wlmaps/templates/wlmaps/index.html'
193--- wlmaps/templates/wlmaps/index.html 2018-11-22 11:08:51 +0000
194+++ wlmaps/templates/wlmaps/index.html 2019-07-15 06:06:57 +0000
195@@ -69,13 +69,9 @@
196 </tr>
197 {% if not map.world_name %}
198 <tr>
199- <td colspan="5"><strong>This map requires a version of Widelands newer than build
200- {% if map.nr_players > 8 %}
201- 19!
202- {% else %}
203- 18!
204- {% endif %}
205- </strong></td>
206+ <td colspan="5">
207+ {% include 'wlmaps/inlines/version_info.html' %}
208+ </td>
209 </tr>
210 {% endif %}
211 <tr>
212
213=== added directory 'wlmaps/templates/wlmaps/inlines'
214=== added file 'wlmaps/templates/wlmaps/inlines/version_info.html'
215--- wlmaps/templates/wlmaps/inlines/version_info.html 1970-01-01 00:00:00 +0000
216+++ wlmaps/templates/wlmaps/inlines/version_info.html 2019-07-15 06:06:57 +0000
217@@ -0,0 +1,11 @@
218+<strong>This map requires a version of Widelands newer than build
219+ {% if map.wl_version_after %}
220+ {{ map.wl_version_after }}!
221+ {% else %}
222+ {% if map.nr_players > 8 %}
223+ 19!
224+ {% else %}
225+ 18!
226+ {% endif %}
227+ {% endif %}
228+</strong>
229
230=== modified file 'wlmaps/templates/wlmaps/map_detail.html'
231--- wlmaps/templates/wlmaps/map_detail.html 2018-11-22 11:08:51 +0000
232+++ wlmaps/templates/wlmaps/map_detail.html 2019-07-15 06:06:57 +0000
233@@ -90,13 +90,7 @@
234
235 {% if not map.world_name %}
236 <div>
237- <strong>This map requires a version of Widelands newer than build
238- {% if map.nr_players > 8 %}
239- 19!
240- {% else %}
241- 18!
242- {% endif %}
243- </strong>
244+ {% include 'wlmaps/inlines/version_info.html'%}
245 </div>
246 {% endif %}
247 </div>

Subscribers

People subscribed via source and target branches