maposmatic/www/maposmatic/models.py

124 wiersze
4.5 KiB
Python

# coding: utf-8
# maposmatic, the web front-end of the MapOSMatic city map generation system
# Copyright (C) 2009 David Decotigny
# Copyright (C) 2009 Frédéric Lehobey
# Copyright (C) 2009 David Mentré
# Copyright (C) 2009 Maxime Petazzoni
# Copyright (C) 2009 Thomas Petazzoni
# Copyright (C) 2009 Gaël Utard
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.db import models
from datetime import datetime
import www.settings
import re
import logging
class MapRenderingJobManager(models.Manager):
def to_render(self):
return MapRenderingJob.objects.filter(status=0).order_by('submission_time')
def queue_size(self):
return MapRenderingJob.objects.filter(status=0).count()
SPACE_REDUCE = re.compile(r"\s+")
NONASCII_REMOVE = re.compile(r"[^A-Za-z0-9]+")
class MapRenderingJob(models.Model):
STATUS_LIST = (
(0, 'Submitted'),
(1, 'In progress'),
(2, 'Done'),
)
maptitle = models.CharField(max_length=256)
administrative_city = models.CharField(max_length=256, blank=True)
lat_upper_left = models.FloatField(blank=True, null=True)
lon_upper_left = models.FloatField(blank=True, null=True)
lat_bottom_right = models.FloatField(blank=True, null=True)
lon_bottom_right = models.FloatField(blank=True, null=True)
status = models.IntegerField(choices=STATUS_LIST)
submission_time = models.DateTimeField(auto_now_add=True)
startofrendering_time = models.DateTimeField(null=True)
endofrendering_time = models.DateTimeField(null=True)
resultmsg = models.CharField(max_length=256, null=True)
submitterip = models.IPAddressField()
index_queue_at_submission = models.IntegerField()
objects = MapRenderingJobManager()
def maptitle_computized(self):
t = self.maptitle.strip()
t = SPACE_REDUCE.sub("-", t)
t = NONASCII_REMOVE.sub("", t)
return t
def files_prefix(self):
return "%06d_%s_%s" % (self.id,
self.startofrendering_time.strftime("%Y-%m-%d_%H-%M"),
self.maptitle_computized())
def start_rendering(self):
self.status = 1
self.startofrendering_time = datetime.now()
self.save()
def end_rendering(self, resultmsg):
self.status = 2
self.endofrendering_time = datetime.now()
self.resultmsg = resultmsg
self.save()
def is_waiting(self):
return self.status == 0
def is_rendering(self):
return self.status == 1
def is_done(self):
return self.status == 2
def is_done_ok(self):
return self.is_done() and self.resultmsg == "ok"
def is_done_failed(self):
return self.is_done() and self.resultmsg != "ok"
def output_files(self):
allfiles = []
for format in www.settings.RENDERING_RESULT_FORMATS:
if format != 'csv':
allfiles.append((www.settings.RENDERING_RESULT_URL + "/" + self.files_prefix() + "." + format,
self.maptitle + " %s Map" % format.upper()))
allfiles.append((www.settings.RENDERING_RESULT_URL + "/" + self.files_prefix() + "_index." + format,
self.maptitle + " %s Index" % format.upper()))
return allfiles
def current_position_in_queue(self):
return MapRenderingJob.objects.filter(status=0).filter(index_queue_at_submission__lte=self.index_queue_at_submission).count()
# Estimate the date at which the rendering will be started
def rendering_estimated_start_time(self):
waiting_time = datetime.now() - self.submission_time
progression = self.index_queue_at_submission - self.current_position_in_queue()
if progression == 0:
return datetime.now()
mean_job_rendering_time = waiting_time // progression
estimated_time_left = mean_job_rendering_time * self.current_position_in_queue()
return datetime.now() + estimated_time_left