1
1
#!/usr/bin/env python -tt
5
from subprocess import check_call, CalledProcessError
4
7
from django import forms
6
class UploadMapForm(forms.Form):
7
mapfile = forms.FileField()
8
comment = forms.CharField(required=False)
8
from django.forms import ModelForm
9
from django.core.files.storage import default_storage
10
from django.conf import settings
12
from wlmaps.models import Map
15
class UploadMapForm(ModelForm):
17
We have to handle here three different kind of files:
18
1. The map which is uploaded
19
2. The files created by 'wl_map_info'
20
a. The json file containing infos of the map
21
b. The image of the minimap (png)
23
The filename of uploaded maps may contain bad characters which must be handled.
25
If a map get deleted in the database, the underlying files (.wmf, .png) still exists. Uploading
26
a map with the same name does not overwrite the existing file(s), instead they get a
27
name in form of 'filename_<random_chars>.wmf(.png)'. This is importand for linking the correct
29
The map file and the minimap (png) have different random characters in such a case, because the map
30
get saved twice: One time for the call to wl_map_info, and when the model is saved.
35
fields = ['file', 'uploader_comment']
38
cleaned_data = super(UploadMapForm, self).clean()
40
mem_file_obj = cleaned_data.get('file')
42
# no clean file => abort
46
# Try to make a safe filename
47
safe_name = default_storage.get_valid_name(mem_file_obj.name)
48
file_path = settings.MEDIA_ROOT + 'wlmaps/maps/' + safe_name
49
saved_file = default_storage.save(file_path, mem_file_obj)
50
except UnicodeEncodeError:
51
self._errors['file'] = self.error_class(
52
['The filename contains characters which cannot be handled. Please rename and upload again.'])
53
del cleaned_data['file']
57
# call map info tool to generate minimap and json info file
59
os.chdir(settings.WIDELANDS_SVN_DIR)
60
check_call(['wl_map_info', saved_file])
62
# TODO(shevonar): delete file because it will be saved again when
63
# the model is saved. File should not be saved twice
64
default_storage.delete(saved_file)
66
except CalledProcessError:
67
self._errors['file'] = self.error_class(
68
['The map file could not be processed.'])
69
del cleaned_data['file']
72
mapinfo = json.load(open(saved_file + '.json'))
74
if Map.objects.filter(name=mapinfo['name']):
75
self._errors['file'] = self.error_class(
76
['A map with the same name already exists.'])
77
del cleaned_data['file']
80
# Add information to the map
81
self.instance.name = mapinfo['name']
82
self.instance.author = mapinfo['author']
83
self.instance.w = mapinfo['width']
84
self.instance.h = mapinfo['height']
85
self.instance.nr_players = mapinfo['nr_players']
86
self.instance.descr = mapinfo['description']
87
self.instance.hint = mapinfo['hint']
88
self.instance.world_name = mapinfo['world_name']
90
# mapinfo["minimap"] is an absolute path.
91
# We partition it to get the correct file path
92
minimap_path = mapinfo['minimap'].partition(settings.MEDIA_ROOT)[2]
93
self.instance.minimap = '/' + minimap_path
95
# the json file is no longer needed
96
default_storage.delete(saved_file + '.json')
100
def save(self, *args, **kwargs):
101
map = super(UploadMapForm, self).save(*args, **kwargs)
107
class EditCommentForm(ModelForm):
111
fields = ['uploader_comment', ]