`X-Datalayer-Version` and `X-Datalayer-Reference` are now used instead
of the `Last-Modified` and `If-Unmodified-Since` headers.
`Last-Modified` is granular to the second, which led to problems with
the versionning. The new system uses timestamps instead.
This commit also changes the way versions were created. Previously,
the associated version was coming from two different places:
the last modified time from the filesystem and a `time.time()` call
done when saving the model, which could result in the two getting
out of sync.
This commit also introduce a new settings UMAP_SCHEMA, that could
be used to easily override schema default, like the default color, the
default path weigth and so on. I'm not documenting yet, because I'm
not yet totally sure we want this.
Previously, an error was thrown when the reference datalayer
had no `features`defined.
When looking for features, it now defaults to an empty list if the key
doesn't exist.
It is already handled by the front-end, and as it also handle the
"map created" message (including anonymous link form), I arbitrated
to keep all front-end side
This is the same as "map new", but it is not in edit mode. This
allow to click on the elements and see the popups instead of editing
it when using a `dataUrl` query string.
This way of using uMap is not documented, but it's used by some
partners (Deveco recently, data.gouv.fr historicaly).
In the same time, this PR adds two things:
- possibility to pass data direclty in querystring (instead of an URL):
in the case of Deveco, they have pages where only point is shown (for
each company)
- possibility to pass style options directly from query string: may
allow for example to control the `popupTemplate`, eg. to use a table
one that will display all properties of the clicked feature
Note: dataUrl and such also works in normal "map new" view. There are
two use cases around those parameters, from external sites:
- see this data on uMap (should point on map preview)
- create a map with those data (should point on map new)
I decided to remove the check `is_ajax` from `validate_url` to simplify
and edge case, and because I think it was more or less useless.
Basically, when getting remote data, we have two cases:
- direct call to the remote URL
- proxy through our `ajax_proxy` system (to work around CORS limitations)
In the first case, we cannot set the `X-Requested-With` header, otherwise
preflight step will fail, and in the second case, until now, we needed
to set this header for this `is_ajax` check to pass. So keeping this check
would mean adapting the behaviour of the Request/ServerRequest class in
a non elegant way. So let's make it simple…
For now we have only three modes:
- latest, which is the default and shows the last updated maps
- highlighted, which shows only the map that have been starred by a least
one staff member
- None, which does not show any map
The server tries to merge conflicting saves of
the same layer.
What it does:
- use the `If-Unmodified-Since` header to check
if changes happened to the stored data ;
- Compare the incoming version with its reference version
to get a diff.
- Reapply the diff on top of the latest version.
- If the merge is not possible, return a
"422 Conflict" HTTP response.
- If the merge worked, return the merged document,
to be updated by the client.
This was creating a huge INNER JOIN, and is replaced
by a UNION
cf https://explain.dalibo.com/plan/91af244fg9d1ec21
Also remove the conditional queryset, as now "my maps"
is serverd by the dashboard page, so we can only serve
public maps on this URL.
This bug has been introduced with this change:
8b4842ff21
That was not the correct fix, and this one should be the proper one.
We don't want to edit the permissions reference until we do save, otherwise user
cannot save as it is already no more the owner.
So:
- change permissions.options
- save
- commit those changes to map.options.permissions
- use only those values to check for isOwner and isAnonymousMap
uMap allows to use remote URL as data sources, but those URLs
are not always CORS open, so this is why there is this "ajax-proxy"
feature, where the URL is passed to the backend.
Additionally, there is a caching feature, which duration is configurable
through frontend settings. Valid values are: disabled, 5 min, 1 hour,
1 day.
Initially, I wanted this to be totally handled by Nginx, but I never
found a wayt to set the proxy_cache_valid value from a query string.
Since then, at least in OSM France servers, the ajax-proxy is still
handled by a Django view, which then opens the remote URL and transfert
the data. This is not optimal. And I suppose this is what is causing
hicups on the OSM France servers lately.
This PR provides a mix option, where python deals with validating the
URL and parsing the TTL parameter, and then it passes the hand to
nginx which will serve the remote content.
So, roughtly:
- the client calls /ajax-proxy/?url=xxx&ttl=300
- python will validate the URL (not internal calls…)
- if UMAP_SENDFILE_HEADER is set, then the python returns an empty
response with the path /proxy/http://url plus it will set the
cache ttl through the header X-Accel-Expires
- this /proxy/ location is then handled by nginx
Prior to 1.3.0, uMap was not setting the gzip mtime, so it was
whatever the time it get requested at first.
Since 1.3.0:
- when creating the geojson.gzip, we also force its mtime to be
the geojson one
- we replaced If-Match by If-Unmodified, which relies on Last-Modified
When uMap is served by a proxy like Nginx (and X-Accel-Redirect),
and if user accepts gzip, then the Last-Modified would be the gzip
one, not the flat geojson one.
So when comparing that value in a subsequent update, we need to
compare with the correct value.
fix#1212
Otherwise the frontend will treat map as anonymous even with
and owner and display a wrong message creation.
Also, this edit URL does not make sense (and will not work)
when there is an owner.