Apply black to models.py
This commit is contained in:
parent
b6628a3015
commit
0b76ebb259
1 changed files with 76 additions and 64 deletions
140
umap/models.py
140
umap/models.py
|
@ -17,7 +17,7 @@ class NamedModel(models.Model):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
abstract = True
|
abstract = True
|
||||||
ordering = ('name', )
|
ordering = ("name",)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
@ -34,8 +34,7 @@ def get_default_licence():
|
||||||
"""
|
"""
|
||||||
return Licence.objects.get_or_create(
|
return Licence.objects.get_or_create(
|
||||||
# can't use ugettext_lazy for database storage, see #13965
|
# can't use ugettext_lazy for database storage, see #13965
|
||||||
name=getattr(settings, "UMAP_DEFAULT_LICENCE_NAME",
|
name=getattr(settings, "UMAP_DEFAULT_LICENCE_NAME", "No licence set")
|
||||||
'No licence set')
|
|
||||||
)[0]
|
)[0]
|
||||||
|
|
||||||
|
|
||||||
|
@ -43,46 +42,42 @@ class Licence(NamedModel):
|
||||||
"""
|
"""
|
||||||
The licence one map is published on.
|
The licence one map is published on.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
details = models.URLField(
|
details = models.URLField(
|
||||||
verbose_name=_('details'),
|
verbose_name=_("details"),
|
||||||
help_text=_('Link to a page where the licence is detailed.')
|
help_text=_("Link to a page where the licence is detailed."),
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def json(self):
|
def json(self):
|
||||||
return {
|
return {"name": self.name, "url": self.details}
|
||||||
'name': self.name,
|
|
||||||
'url': self.details
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class TileLayer(NamedModel):
|
class TileLayer(NamedModel):
|
||||||
url_template = models.CharField(
|
url_template = models.CharField(
|
||||||
max_length=200,
|
max_length=200, help_text=_("URL template using OSM tile format")
|
||||||
help_text=_("URL template using OSM tile format")
|
|
||||||
)
|
)
|
||||||
minZoom = models.IntegerField(default=0)
|
minZoom = models.IntegerField(default=0)
|
||||||
maxZoom = models.IntegerField(default=18)
|
maxZoom = models.IntegerField(default=18)
|
||||||
attribution = models.CharField(max_length=300)
|
attribution = models.CharField(max_length=300)
|
||||||
rank = models.SmallIntegerField(
|
rank = models.SmallIntegerField(
|
||||||
blank=True,
|
blank=True, null=True, help_text=_("Order of the tilelayers in the edit box")
|
||||||
null=True,
|
|
||||||
help_text=_('Order of the tilelayers in the edit box')
|
|
||||||
)
|
)
|
||||||
# See https://wiki.openstreetmap.org/wiki/TMS#The_Y_coordinate
|
# See https://wiki.openstreetmap.org/wiki/TMS#The_Y_coordinate
|
||||||
tms = models.BooleanField(default=False)
|
tms = models.BooleanField(default=False)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def json(self):
|
def json(self):
|
||||||
return dict((field.name, getattr(self, field.name))
|
return dict(
|
||||||
for field in self._meta.fields)
|
(field.name, getattr(self, field.name)) for field in self._meta.fields
|
||||||
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_default(cls):
|
def get_default(cls):
|
||||||
"""
|
"""
|
||||||
Returns the default tile layer (used for a map when no layer is set).
|
Returns the default tile layer (used for a map when no layer is set).
|
||||||
"""
|
"""
|
||||||
return cls.objects.order_by('rank')[0] # FIXME, make it administrable
|
return cls.objects.order_by("rank")[0] # FIXME, make it administrable
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_list(cls):
|
def get_list(cls):
|
||||||
|
@ -91,18 +86,19 @@ class TileLayer(NamedModel):
|
||||||
for t in cls.objects.all():
|
for t in cls.objects.all():
|
||||||
fields = t.json
|
fields = t.json
|
||||||
if default and default.pk == t.pk:
|
if default and default.pk == t.pk:
|
||||||
fields['selected'] = True
|
fields["selected"] = True
|
||||||
l.append(fields)
|
l.append(fields)
|
||||||
return l
|
return l
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ('rank', 'name', )
|
ordering = ("rank", "name")
|
||||||
|
|
||||||
|
|
||||||
class Map(NamedModel):
|
class Map(NamedModel):
|
||||||
"""
|
"""
|
||||||
A single thematical map.
|
A single thematical map.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
ANONYMOUS = 1
|
ANONYMOUS = 1
|
||||||
EDITORS = 2
|
EDITORS = 2
|
||||||
OWNER = 3
|
OWNER = 3
|
||||||
|
@ -111,45 +107,62 @@ class Map(NamedModel):
|
||||||
PRIVATE = 3
|
PRIVATE = 3
|
||||||
BLOCKED = 9
|
BLOCKED = 9
|
||||||
EDIT_STATUS = (
|
EDIT_STATUS = (
|
||||||
(ANONYMOUS, _('Everyone can edit')),
|
(ANONYMOUS, _("Everyone can edit")),
|
||||||
(EDITORS, _('Only editors can edit')),
|
(EDITORS, _("Only editors can edit")),
|
||||||
(OWNER, _('Only owner can edit')),
|
(OWNER, _("Only owner can edit")),
|
||||||
)
|
)
|
||||||
SHARE_STATUS = (
|
SHARE_STATUS = (
|
||||||
(PUBLIC, _('everyone (public)')),
|
(PUBLIC, _("everyone (public)")),
|
||||||
(OPEN, _('anyone with link')),
|
(OPEN, _("anyone with link")),
|
||||||
(PRIVATE, _('editors only')),
|
(PRIVATE, _("editors only")),
|
||||||
(BLOCKED, _('blocked')),
|
(BLOCKED, _("blocked")),
|
||||||
)
|
)
|
||||||
slug = models.SlugField(db_index=True)
|
slug = models.SlugField(db_index=True)
|
||||||
description = models.TextField(blank=True, null=True, verbose_name=_("description"))
|
description = models.TextField(blank=True, null=True, verbose_name=_("description"))
|
||||||
center = models.PointField(geography=True, verbose_name=_("center"))
|
center = models.PointField(geography=True, verbose_name=_("center"))
|
||||||
zoom = models.IntegerField(default=7, verbose_name=_("zoom"))
|
zoom = models.IntegerField(default=7, verbose_name=_("zoom"))
|
||||||
locate = models.BooleanField(default=False, verbose_name=_("locate"), help_text=_("Locate user on load?"))
|
locate = models.BooleanField(
|
||||||
|
default=False, verbose_name=_("locate"), help_text=_("Locate user on load?")
|
||||||
|
)
|
||||||
licence = models.ForeignKey(
|
licence = models.ForeignKey(
|
||||||
Licence,
|
Licence,
|
||||||
help_text=_("Choose the map licence."),
|
help_text=_("Choose the map licence."),
|
||||||
verbose_name=_('licence'),
|
verbose_name=_("licence"),
|
||||||
on_delete=models.SET_DEFAULT,
|
on_delete=models.SET_DEFAULT,
|
||||||
default=get_default_licence
|
default=get_default_licence,
|
||||||
)
|
)
|
||||||
modified_at = models.DateTimeField(auto_now=True)
|
modified_at = models.DateTimeField(auto_now=True)
|
||||||
owner = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True, related_name="owned_maps", verbose_name=_("owner"), on_delete=models.PROTECT)
|
owner = models.ForeignKey(
|
||||||
editors = models.ManyToManyField(settings.AUTH_USER_MODEL, blank=True, verbose_name=_("editors"))
|
settings.AUTH_USER_MODEL,
|
||||||
edit_status = models.SmallIntegerField(choices=EDIT_STATUS, default=OWNER, verbose_name=_("edit status"))
|
blank=True,
|
||||||
share_status = models.SmallIntegerField(choices=SHARE_STATUS, default=PUBLIC, verbose_name=_("share status"))
|
null=True,
|
||||||
settings = models.JSONField(blank=True, null=True, verbose_name=_("settings"), default=dict)
|
related_name="owned_maps",
|
||||||
|
verbose_name=_("owner"),
|
||||||
|
on_delete=models.PROTECT,
|
||||||
|
)
|
||||||
|
editors = models.ManyToManyField(
|
||||||
|
settings.AUTH_USER_MODEL, blank=True, verbose_name=_("editors")
|
||||||
|
)
|
||||||
|
edit_status = models.SmallIntegerField(
|
||||||
|
choices=EDIT_STATUS, default=OWNER, verbose_name=_("edit status")
|
||||||
|
)
|
||||||
|
share_status = models.SmallIntegerField(
|
||||||
|
choices=SHARE_STATUS, default=PUBLIC, verbose_name=_("share status")
|
||||||
|
)
|
||||||
|
settings = models.JSONField(
|
||||||
|
blank=True, null=True, verbose_name=_("settings"), default=dict
|
||||||
|
)
|
||||||
|
|
||||||
objects = models.Manager()
|
objects = models.Manager()
|
||||||
public = PublicManager()
|
public = PublicManager()
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse("map", kwargs={'slug': self.slug or "map", 'pk': self.pk})
|
return reverse("map", kwargs={"slug": self.slug or "map", "pk": self.pk})
|
||||||
|
|
||||||
def get_anonymous_edit_url(self):
|
def get_anonymous_edit_url(self):
|
||||||
signer = Signer()
|
signer = Signer()
|
||||||
signature = signer.sign(self.pk)
|
signature = signer.sign(self.pk)
|
||||||
return reverse('map_anonymous_edit_url', kwargs={'signature': signature})
|
return reverse("map_anonymous_edit_url", kwargs={"signature": signature})
|
||||||
|
|
||||||
def is_anonymous_owner(self, request):
|
def is_anonymous_owner(self, request):
|
||||||
if self.owner:
|
if self.owner:
|
||||||
|
@ -169,8 +182,9 @@ class Map(NamedModel):
|
||||||
"""
|
"""
|
||||||
can = False
|
can = False
|
||||||
if request and not self.owner:
|
if request and not self.owner:
|
||||||
if (getattr(settings, "UMAP_ALLOW_ANONYMOUS", False)
|
if getattr(
|
||||||
and self.is_anonymous_owner(request)):
|
settings, "UMAP_ALLOW_ANONYMOUS", False
|
||||||
|
) and self.is_anonymous_owner(request):
|
||||||
can = True
|
can = True
|
||||||
if self.edit_status == self.ANONYMOUS:
|
if self.edit_status == self.ANONYMOUS:
|
||||||
can = True
|
can = True
|
||||||
|
@ -192,13 +206,15 @@ class Map(NamedModel):
|
||||||
elif request.user == self.owner:
|
elif request.user == self.owner:
|
||||||
can = True
|
can = True
|
||||||
else:
|
else:
|
||||||
can = not (self.share_status == self.PRIVATE
|
can = not (
|
||||||
and request.user not in self.editors.all())
|
self.share_status == self.PRIVATE
|
||||||
|
and request.user not in self.editors.all()
|
||||||
|
)
|
||||||
return can
|
return can
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def signed_cookie_elements(self):
|
def signed_cookie_elements(self):
|
||||||
return ('anonymous_owner|%s' % self.pk, self.pk)
|
return ("anonymous_owner|%s" % self.pk, self.pk)
|
||||||
|
|
||||||
def get_tilelayer(self):
|
def get_tilelayer(self):
|
||||||
return self.tilelayer or TileLayer.get_default()
|
return self.tilelayer or TileLayer.get_default()
|
||||||
|
@ -206,7 +222,7 @@ class Map(NamedModel):
|
||||||
def clone(self, **kwargs):
|
def clone(self, **kwargs):
|
||||||
new = self.__class__.objects.get(pk=self.pk)
|
new = self.__class__.objects.get(pk=self.pk)
|
||||||
new.pk = None
|
new.pk = None
|
||||||
new.name = u"%s %s" % (_("Clone of"), self.name)
|
new.name = "%s %s" % (_("Clone of"), self.name)
|
||||||
if "owner" in kwargs:
|
if "owner" in kwargs:
|
||||||
# can be None in case of anonymous cloning
|
# can be None in case of anonymous cloning
|
||||||
new.owner = kwargs["owner"]
|
new.owner = kwargs["owner"]
|
||||||
|
@ -222,6 +238,7 @@ class Pictogram(NamedModel):
|
||||||
"""
|
"""
|
||||||
An image added to an icon of the map.
|
An image added to an icon of the map.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
attribution = models.CharField(max_length=300)
|
attribution = models.CharField(max_length=300)
|
||||||
pictogram = models.ImageField(upload_to="pictogram")
|
pictogram = models.ImageField(upload_to="pictogram")
|
||||||
|
|
||||||
|
@ -231,7 +248,7 @@ class Pictogram(NamedModel):
|
||||||
"id": self.pk,
|
"id": self.pk,
|
||||||
"attribution": self.attribution,
|
"attribution": self.attribution,
|
||||||
"name": self.name,
|
"name": self.name,
|
||||||
"src": self.pictogram.url
|
"src": self.pictogram.url,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -248,22 +265,19 @@ class DataLayer(NamedModel):
|
||||||
"""
|
"""
|
||||||
Layer to store Features in.
|
Layer to store Features in.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
map = models.ForeignKey(Map, on_delete=models.CASCADE)
|
map = models.ForeignKey(Map, on_delete=models.CASCADE)
|
||||||
description = models.TextField(
|
description = models.TextField(blank=True, null=True, verbose_name=_("description"))
|
||||||
blank=True,
|
|
||||||
null=True,
|
|
||||||
verbose_name=_("description")
|
|
||||||
)
|
|
||||||
geojson = models.FileField(upload_to=upload_to, blank=True, null=True)
|
geojson = models.FileField(upload_to=upload_to, blank=True, null=True)
|
||||||
display_on_load = models.BooleanField(
|
display_on_load = models.BooleanField(
|
||||||
default=False,
|
default=False,
|
||||||
verbose_name=_("display on load"),
|
verbose_name=_("display on load"),
|
||||||
help_text=_("Display this layer on load.")
|
help_text=_("Display this layer on load."),
|
||||||
)
|
)
|
||||||
rank = models.SmallIntegerField(default=0)
|
rank = models.SmallIntegerField(default=0)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ('rank',)
|
ordering = ("rank",)
|
||||||
|
|
||||||
def save(self, force_insert=False, force_update=False, **kwargs):
|
def save(self, force_insert=False, force_update=False, **kwargs):
|
||||||
is_new = not bool(self.pk)
|
is_new = not bool(self.pk)
|
||||||
|
@ -281,7 +295,7 @@ class DataLayer(NamedModel):
|
||||||
|
|
||||||
def upload_to(self):
|
def upload_to(self):
|
||||||
root = self.storage_root()
|
root = self.storage_root()
|
||||||
name = '%s_%s.geojson' % (self.pk, int(time.time() * 1000))
|
name = "%s_%s.geojson" % (self.pk, int(time.time() * 1000))
|
||||||
return os.path.join(root, name)
|
return os.path.join(root, name)
|
||||||
|
|
||||||
def storage_root(self):
|
def storage_root(self):
|
||||||
|
@ -293,11 +307,7 @@ class DataLayer(NamedModel):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def metadata(self):
|
def metadata(self):
|
||||||
return {
|
return {"name": self.name, "id": self.pk, "displayOnLoad": self.display_on_load}
|
||||||
"name": self.name,
|
|
||||||
"id": self.pk,
|
|
||||||
"displayOnLoad": self.display_on_load
|
|
||||||
}
|
|
||||||
|
|
||||||
def clone(self, map_inst=None):
|
def clone(self, map_inst=None):
|
||||||
new = self.__class__.objects.get(pk=self.pk)
|
new = self.__class__.objects.get(pk=self.pk)
|
||||||
|
@ -309,14 +319,14 @@ class DataLayer(NamedModel):
|
||||||
return new
|
return new
|
||||||
|
|
||||||
def is_valid_version(self, name):
|
def is_valid_version(self, name):
|
||||||
return name.startswith('%s_' % self.pk) and name.endswith('.geojson')
|
return name.startswith("%s_" % self.pk) and name.endswith(".geojson")
|
||||||
|
|
||||||
def version_metadata(self, name):
|
def version_metadata(self, name):
|
||||||
els = name.split('.')[0].split('_')
|
els = name.split(".")[0].split("_")
|
||||||
return {
|
return {
|
||||||
"name": name,
|
"name": name,
|
||||||
"at": els[1],
|
"at": els[1],
|
||||||
"size": self.geojson.storage.size(self.get_version_path(name))
|
"size": self.geojson.storage.size(self.get_version_path(name)),
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_versions(self):
|
def get_versions(self):
|
||||||
|
@ -333,17 +343,17 @@ class DataLayer(NamedModel):
|
||||||
|
|
||||||
def get_version(self, name):
|
def get_version(self, name):
|
||||||
path = self.get_version_path(name)
|
path = self.get_version_path(name)
|
||||||
with self.geojson.storage.open(path, 'r') as f:
|
with self.geojson.storage.open(path, "r") as f:
|
||||||
return f.read()
|
return f.read()
|
||||||
|
|
||||||
def get_version_path(self, name):
|
def get_version_path(self, name):
|
||||||
return '{root}/{name}'.format(root=self.storage_root(), name=name)
|
return "{root}/{name}".format(root=self.storage_root(), name=name)
|
||||||
|
|
||||||
def purge_old_versions(self):
|
def purge_old_versions(self):
|
||||||
root = self.storage_root()
|
root = self.storage_root()
|
||||||
names = self.get_versions()[settings.UMAP_KEEP_VERSIONS:]
|
names = self.get_versions()[settings.UMAP_KEEP_VERSIONS :]
|
||||||
for name in names:
|
for name in names:
|
||||||
for ext in ['', '.gz']:
|
for ext in ["", ".gz"]:
|
||||||
path = os.path.join(root, name + ext)
|
path = os.path.join(root, name + ext)
|
||||||
try:
|
try:
|
||||||
self.geojson.storage.delete(path)
|
self.geojson.storage.delete(path)
|
||||||
|
@ -354,4 +364,6 @@ class DataLayer(NamedModel):
|
||||||
class Star(models.Model):
|
class Star(models.Model):
|
||||||
at = models.DateTimeField(auto_now=True)
|
at = models.DateTimeField(auto_now=True)
|
||||||
map = models.ForeignKey(Map, on_delete=models.CASCADE)
|
map = models.ForeignKey(Map, on_delete=models.CASCADE)
|
||||||
by = models.ForeignKey(settings.AUTH_USER_MODEL, related_name="stars", on_delete=models.CASCADE)
|
by = models.ForeignKey(
|
||||||
|
settings.AUTH_USER_MODEL, related_name="stars", on_delete=models.CASCADE
|
||||||
|
)
|
||||||
|
|
Loading…
Reference in a new issue