204 changes: 204 additions & 0 deletions docs/reference/worldmap.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
.. _worldmap:

========
WorldMap
========

By using the WorldMap optional application, GeoNode is extended with the following additional features:

* a customized GeoExplorer viewer
* the table of contents is hierarchical with layer categories. When a layer is added a new category containing the layer is added to the table of contents. If the category is already in the table of contents, then the layer is added to it. By default the category is the same as the layer's topic category, but that can be renamed by right clicking on it
* the "Add Layers" dialog comes with a "Search" tab which uses Hypermap Registry (Hypermap) as a catalogue of remote and local layers. Hypermap is a requirement when using the WorldMap contrib application
* a gazetteer application: it is possible to add a given layer to a gazetteer. The gazetteer can be checked using the map client. When a layer is part of the gazetter it is possible to include it in a general gazetteer or in a specific project one. It is possible to search place names in the gazetteer by date range, in which case it is necessary to specify the layer attributes for the start and end depict dates

Installation
============

Requirements
------------

We are assuming a Ubuntu 16.04.1 LTS development environment, but these instructions can be adapted to any recent Linux distributions::

# Install Ubuntu dependencies
sudo apt-get update
sudo apt-get install python-virtualenv python-dev libxml2 libxml2-dev libxslt1-dev zlib1g-dev libjpeg-dev libpq-dev libgdal-dev git default-jdk postgresql postgis

# Install Java 8 (needed by latest GeoServer 2.13)
sudo apt-add-repository ppa:webupd8team/java
sudo apt-get update
sudo apt-get install oracle-java8-installer

Virtual environment creation and installation of Python packages
----------------------------------------------------------------

Create and activate the virtual environment::

cd ~
virtualenv --no-site-packages env
. env/bin/activate

Now install GeoNode from source code::

git clone -b https://github.com/geonode/geonode.git
cd geonode
pip install -r requirements.txt
pip install pygdal==1.11.3.3
pip install -e .
paver setup
paver sync

Set the following environment variables as needed (change SITE_NAME and SERVER_IP s needed. Also HYPERMAP_REGISTRY_URL and SOLR_URL may be different). Even better, create a file and source it::

export USE_WORLDMAP=True
export SITE_NAME=worldmap
export SERVER_IP=128.31.22.73
export PG_USERNAME=worldmap
export PG_PASSWORD=worldmap
export PG_WORLDMAP_DJANGO_DB=worldmap
export PG_WORLDMAP_UPLOADS_DB=wmdata
export OWNER=$PG_USERNAME
export ALLOWED_HOSTS="localhost, $SERVER_IP, "
export GEOSERVER_LOCATION=http://localhost:8080/geoserver/
export GEOSERVER_PUBLIC_LOCATION=http://$SERVER_IP/geoserver/
export SOLR_URL =http://localhost:8983/solr/hypermap/select/
export HYPERMAP_REGISTRY_URL =http://localhost:8001
export MAPPROXY_URL=http://localhost:8001


You can install GeoNode WorldMap in two different ways:

1) By installing GeoNode itself
2) By using the recommended way of a geonode-project

GeoNode/WorldMap without a geonode-project
------------------------------------------

Copy the included local_settings.py file and customize it to your needs::

cp local_settings.py.worldmap.sample local_settings.py

GeoNode/WorldMap with a geonode-project
---------------------------------------

You will use a geonode-project in order to separate the customization of your instance from GeoNode.

Create your geonode project by using the WorldMap geonode-project as a template (https://github.com/cga-harvard/geonode-project). Rename it to something meaningful (for example your web site name)::

cd ~
django-admin startproject $SITE_NAME --template=https://github.com/cga-harvard/geonode-project/archive/master.zip -epy,rst
cd $SITE_NAME

Create a local_settings.py by copying the included template::

cp $SITE_NAME/local_settings.py.sample $SITE_NAME/local_settings.py
make build
paver setup

Start the Server
----------------

Start GeoNode with Worldmap using pavement::

python manage.py runserver 0.0.0.0:8000
paver start_geoserver

To upload layers you can login with the default GeoNode administrative account:

user: admin
password: admin

Configuring instance for production
-----------------------------------

Please follow best practices suggested by GeoNode documentation:

http://docs.geonode.org/en/master/tutorials/advanced/geonode_production/

Remember to add the ip of your server in ALLOWED_HOSTS in the local_settings.py file::

ALLOWED_HOSTS = ['localhost', '128.31.22.73', ]

Hypermap Registry
=================

GeoNode with the WorldMap contribute module requires a Hypermap Registry (Hypermap) running instance.

You can install Hypermap by following these instructions (use the "Manual Installation" section): https://github.com/cga-harvard/HHypermap/blob/master/_docs/developers.md

Note that you can bypass Java 8 installation as it was installed previously. As a search engine you should install Solr, as we haven't tested Elasticsearch with WorldMap so far. Create a specific virtual environment for Hypermap in order not to interfere with the GeoNode/WorldMap virtual environment.

After installing Hypermap, start it on a different port than 8000, for example::

python manage.py runserver 0.0.0.0:8001

In another shell start the Celery process as well::

cd HHypermap
celery -A hypermap worker --beat --scheduler django -l info

Test the stack
==============

Now that GeoNode/WorldMap and Hypermap are both running, test the stack by uploading a layer.

Login in GeoNode (admin/admin) and upload a shapefile from this page: http://localhost:8000/layers/upload

Make sure the shapefile is correctly displayed in GeoNode by going to the layer page.

Now login in Hypermap (admin/admin) and go to the admin services page: http://localhost:8001/admin/aggregator/service/ Add a service like this:

* Title: My GeoNode WorldMap SDI
* Url: http://localhost:8000/
* Type: GeoNode WorldMap

Go to the Hypermap service page and check it the service and the layer is there:
http://localhost:8001/registry/

In order to have layers in the search engine (Solr) there are two options:

1) from task runner press the "Index cached layers" button
2) schedule a task in celery

We recommend the second option, which can be configured in the next section.

Schedule Celery tasks
=====================

Go to the Periodic Task administrative interface: http://localhost:8001/admin/django_celery_beat/periodictask/

Create the following two tasks:

Index Cached Layer Task
-----------------------

This task will sync the layers from the cache to the search engine. Layers are sent in the cache every time they are saved:

* Name: Index Cached Layer
* Task (registered): hypermap.aggregator.tasks.index_cached_layers
* Interval: every 1 minute (or as needed)

Check Worldmap Service
----------------------

This task will do a check of all of WorldMap service:

* Name: Check WorldMap Service
* Task (registered): hypermap.aggregator.tasks.check_service
* Interval: every 1 minute (or as needed)
* Arguments: [1] # 1 is the id of the service. Change it as is needed

Now upload a new layer in GeoNode/WorldMap and check if it appears in Hypermap and in Solr (you may need to wait for the tasks to be executed)

Update Last GeoNode WorldMap Layers
-----------------------------------

If your GeoNode/WorldMap instance has many layers, it is preferable to runt the check_service not so often, as it can be time consuming, and rather use the update_last_wm_layers.

As a first thing, change the interval for the check_service task you created for GeoNode/WorldMap to a value such as "one day" or "one week".

Then create the following periodic task:

* Name: Sync last layers in WorldMap Service
* Task (registered): hypermap.aggregator.update_last_wm_layers
* Interval: every 1 minute
* Arguments: [1] # 1 is the id of the service. Change it as is needed
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ If you are working remotely, you should first connect to the machine that has yo

.. code-block:: console
:linenos:

$ apt-get install python-django
$ django-admin startproject my_geonode --template=https://github.com/GeoNode/geonode-project/archive/master.zip -epy,rst
$ cd my_geonode
$ sudo pip install -e .
$ sudo pip install -e . --upgrade --no-cache
$ python manage.py migrate

.. note:: You should NOT use the name *geonode* for your project as it will conflict with your default geonode package name.
Expand All @@ -25,11 +25,11 @@ Make sure that the directories are reachable and have the correct rights for the

.. code-block:: console
:linenos:

$ sudo chown -Rf geonode: *
$ sudo chmod -Rf 775 my_geonode

If you have a brand new installation of GeoNode, rename the **/home/geonode/geonode/local_settings.py.sample** to **local_settings.py** and edit it's content by setting the SITEURL and SITENAME. This file will be your main settings file for your project. It inherits all the settings from the original one plus you can override the ones that you need.
If you have a brand new installation of GeoNode, rename the **/home/geonode/geonode/local_settings.py.sample** to **local_settings.py** and edit it's content by setting the SITEURL and SITENAME. This file will be your main settings file for your project. It inherits all the settings from the original one plus you can override the ones that you need.

.. note:: You can also decide to copy the **/home/geonode/geonode/local_settings.py.sample** to **/path/to/my_geonode/my_geonode/local_settings.py** in order to keep all the custom settings confined into the new project.

Expand Down Expand Up @@ -82,7 +82,7 @@ Edit the file /etc/apache2/sites-available/geonode.conf and modify the **Documen
Allow from all
IndexOptions FancyIndexing
</Directory>

...

Then regenerate the static **JavaScript** and **CSS** files from **/path/to/my_geonode/** and restart apache
Expand Down Expand Up @@ -144,7 +144,7 @@ It is recommended that you immediately put your new project under source code re
:linenos:

$ sudo git remote add origin <https url of your custom repo>


#. Add your project files to the repository:

Expand All @@ -161,7 +161,7 @@ It is recommended that you immediately put your new project under source code re
# Those two command must be issued ONLY once
$ sudo git config --global user.email "my@email"
$ sudo git config --global user.name "myuser"

$ sudo git commit -am "Initial commit"

#. Push to the remote repository:
Expand Down Expand Up @@ -237,7 +237,7 @@ python module may not be available) is:

.. code-block: python
:linenos:

try:
from local_settings import *
except:
Expand Down
22 changes: 11 additions & 11 deletions docs/tutorials/admin/install/custom_install.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ This includes:
* Python development libraries
* PostgreSQL database
* The GDAL, GEOS, and OGR geospatial software libraries

For detailed information on dependencies please refer to the section :ref:`dependencies`.

For convenience, appropriate commands to retrieve these dependencies on Ubuntu
Expand Down Expand Up @@ -100,7 +100,7 @@ installation-configuration of GeoNode:
#. `Configure using the ubuntu config file`_.
This is the recommended way, using the provided .sh scripts
#. `Configure manually`_, doing each step by hand as opposed to using the .sh scripts

In the end you will have the same running instance of Geonode.

Configure Manually
Expand All @@ -120,7 +120,7 @@ Download the code using git.
$ cd geonode

# Installs django etc.
$ sudo pip install -e .
$ sudo pip install -e . --upgrade --no-cache

# Downloads geoserver.war
$ sudo paver setup
Expand Down Expand Up @@ -192,7 +192,7 @@ To create the databases (the geonode one and the spatial for shapefile imports):
$ psql -d geonode_data -c 'GRANT ALL ON spatial_ref_sys TO PUBLIC;'
$ exit

This creates databases called *geonode* and *geonode_data*
This creates databases called *geonode* and *geonode_data*
(which automatically has the postgis extension as well!)
with owner *geonode*.

Expand Down Expand Up @@ -491,7 +491,7 @@ pre-installed.
However, some manual configuration may still be needed in case of not standard
installation.

**Configure GeoServer**
**Configure GeoServer**

Configure GeoServer with the location of the GeoNode site, used for
authentication (so that GeoServer can recognize logins from the main site).
Expand All @@ -508,12 +508,12 @@ so:
<context-param>
<param-name>GEONODE_BASE_URL</param-name>
<param-value>http://localhost/</param-value>
</context-param>
</context-param>

The ``<param-value>`` tag should enclose the URL to the Django application
homepage.

And secondly, update the value of the ``baseUrl`` tag in
And secondly, update the value of the ``baseUrl`` tag in
``data/security/auth/geonodeAuthProvider/config.xml``:

.. code-block:: xml
Expand Down Expand Up @@ -544,16 +544,16 @@ Download the code using git.
$ git clone https://github.com/GeoNode/geonode.git
$ cd geonode

* Installer configuration file *(located in ``package/support/config-ubuntu.sh``)*
* Installer configuration file *(located in ``package/support/config-ubuntu.sh``)*
This is the first thing to edit.
* The installer script *(located in ``package/install.sh``)*
Second thing to edit.

#. First open the ``package/support/config-ubuntu.sh`` installer configuration file.
Now provide the details of your installation,
such as where your web server looks for documents.

#. Second, open ``install.sh`` and configure to your needs.
#. Second, open ``install.sh`` and configure to your needs.

.. note:: you might have to change the postgresql and postgis versions in
this file, according to the versions you use!
Expand All @@ -573,6 +573,6 @@ Once edited (if necessary) run the ``./install.sh`` file with the following comm

# create the IP address to your address
$ sudo geonode-updateip youraddress


GeoNode can now be accessed at http://localhost
28 changes: 14 additions & 14 deletions docs/tutorials/admin/socialaccounts/index.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Base concepts and objects
* `django-invitations <https://github.com/bee-keeper/django-invitations>`_ has also been integrated as a dependency of geonode and is used for managing invitations to new users. This functionality was previously provided by geonode-user-accounts;

* `django-allauth <http://django-allauth.readthedocs.io/en/latest/>`_ has been extended in order to provide the following additional features:

- Automatically registering an e-mail with a user when the e-mail is used to connect to a social account;
- Automatically extract information from the user's social account and use that to enhance the user's profile fields on geonode. This was implemented in a pluggable way, allowing custom installs to configure it for other providers;
- Allow approval of new registrations by staff members before allowing new users to login. This functionality was previously provided by geonode-user-accounts.
Expand All @@ -33,7 +33,7 @@ Base concepts and objects
.. image:: img/001_screenshot.png

* When properly configured, the login and register pages now display the possibility to login with social accounts

.. image:: img/002_screenshot.png


Expand All @@ -44,8 +44,8 @@ Installation

.. code:: python

pip install -r requirements.txt
pip install -e .
pip install -r requirements.txt --upgrade
pip install -e . --upgrade --no-cache
pip uninstall geonode-user-accounts -y
pip uninstall django-user-accounts -y

Expand Down Expand Up @@ -157,9 +157,9 @@ Usage
This will require a persoanl or business account, which can access to the ``developers`` sections of LinkedIn and Facebook and create and configure new ``Applications``.

That account won't be visibile to the GeoNode users. This is needed only to generate OAuth2 ``Client ID`` and ``Client Secret`` Authorization Keys.

In the following sections we will see in details how to configure them for both LinkedIn and Facebook.

LinkedIn Application
++++++++++++++++++++
(ref.: http://django-allauth.readthedocs.io/en/latest/providers.html)
Expand Down Expand Up @@ -188,10 +188,10 @@ LinkedIn Application
5. Add OAuth 2.0 Authorized Redirect URLs:

.. code:: python

http://geonode.geo-solutions.it/account/linkedin_oauth2/login/callback/
http://geonode.geo-solutions.it/account/linkedin/login/callback/

.. image:: img/008_socialaouth.png

6. Save
Expand Down Expand Up @@ -243,10 +243,10 @@ Facebook Application
5. Cut and Paste the ``App ID`` and ``Secret Key`` on the related fields

.. code:: python

ClientID <--> App Id
Client Secret <--> Secret Key

.. image:: img/018_socialaouth.png

6. Save
Expand Down Expand Up @@ -298,7 +298,7 @@ Facebook Application
18. Add the valid ``redirect URIs``:

.. code:: python

http://geonode.geo-solutions.it/account/facebook/login/callback/
http://geondoe.geo-solutions.it/account/login/

Expand All @@ -312,9 +312,9 @@ Login by using Existing Accounts on GeoNode
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you want to enable an already existing user account to login through social apps, you need to associate it to social accounts.

Usually this could be done only by the current user, since this operation requires authentication on its social accounts.

In order to do that you need to go to the User Profile Settings

.. image:: img/032_socialaouth.png
Expand All @@ -325,7 +325,7 @@ Login by using Existing Accounts on GeoNode
.. image:: img/033_socialaouth.png

And actually connect them

.. image:: img/034_socialaouth.png

.. image:: img/035_socialaouth.png
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ packages
.. code-block:: bash

$ sudo apt-get update

$ sudo apt-get install python-virtualenv python-dev libxml2 libxml2-dev libxslt1-dev zlib1g-dev libjpeg-dev libpq-dev git default-jdk
$ sudo apt-get install build-essential openssh-server gettext nano vim unzip zip patch git-core postfix

Expand All @@ -50,7 +50,7 @@ packages
$ sudo apt-get install gcc apache2 libapache2-mod-wsgi libgeos-dev libjpeg-dev libpng-dev libpq-dev libproj-dev libxml2-dev libxslt-dev
$ sudo apt-add-repository ppa:ubuntugis/ubuntugis-testing && sudo apt-get update && sudo apt-get upgrade
$ sudo apt-get install gdal-bin libgdal20 libgdal-dev
$ sudo apt-get install python-gdal python-pycurl python-imaging python-pastescript python-psycopg2 python-urlgrabber
$ sudo apt-get install python-gdal python-pycurl python-imaging python-pastescript python-psycopg2 python-urlgrabber
$ sudo apt-get install postgresql postgis postgresql-9.5-postgis-scripts postgresql-contrib
$ sudo apt-get install tomcat8

Expand Down Expand Up @@ -101,7 +101,7 @@ First of all we need to prepare a new Python Virtual Environment:
Let's activate the new `geonode` Python Virtual Environment:

.. code-block:: bash

$ workon geonode

Move into the `geonode` home folder
Expand All @@ -113,12 +113,12 @@ Move into the `geonode` home folder
We are going to install GeoNode as a dependency of a **Customized DJango Project**

.. note::
A custom project is a DJango application with *ad hoc* configuration and folders, which allows you to
A custom project is a DJango application with *ad hoc* configuration and folders, which allows you to
extend the original **GeoNode** code without actually dealing or modifying the main source code.

This will allow you to easily customize your GeoNode instance, modify the theme, add new functionalities and so on,
and also being able to keep updated with the GeoNode latest source code.

For more deails please check https://github.com/GeoNode/geonode-project/tree/master

.. code-block:: bash
Expand All @@ -132,7 +132,7 @@ Let's install the GeoNode dependencies and packages into the Python Virtual Envi

$ cd my_geonode

# Find the closest pygdal version.
# Find the closest pygdal version.
# Example: 2.2.1 ... 2.2.1.3, ...
$ gdal-config --version && pip install pygdal==

Expand All @@ -142,8 +142,8 @@ Let's install the GeoNode dependencies and packages into the Python Virtual Envi
-e git://github.com/GeoNode/geonode.git@2.8.0#egg=geonode
pygdal==2.2.1.3

$ pip install -r requirements.txt
$ pip install -e .
$ pip install -r requirements.txt --upgrade
$ pip install -e . --upgrade --no-cache


In the next section we are going to setup PostgreSQL Databases for GeoNode and finalize the setup
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ Upgrade Development Environment
.. code-block:: bash

pip install pip --upgrade
pip install -r requirements.txt
pip install -e .
pip install -r requirements.txt --upgrade
pip install -e . --upgrade --no-cache

# WARNING: your GDAL version might be different. Use the right one accordingly to gdal-config --version
pip install pygdal==2.2.1.3
Expand Down
8 changes: 4 additions & 4 deletions docs/tutorials/install_and_admin/quick_install.txt
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ This option installs geonode in a virtual environment. This option is very usefu
cd geonode

# Install pip dependencies
pip install -r requirements.txt --no-deps
pip install -e .
pip install -r requirements.txt --upgrade
pip install -e . --upgrade --no-cache

sudo add-apt-repository ppa:ubuntugis/ppa && sudo apt-get update
sudo apt-get install gdal-bin
Expand Down Expand Up @@ -204,7 +204,7 @@ Install Python native dependencies, this command will look for and install binar

Install GeoNode in the local virtualenv::

pip install -e .
pip install -e . --upgrade --no-cache

You have two options to set up the GEOS and GDAL libraries. Either create an environment variable
or add the variables to your local_settings.py file as below.
Expand Down Expand Up @@ -269,7 +269,7 @@ On a production environment, remember to refresh also the "static_root" folder::

Install pip dependencies::

pip install -e .
pip install -e . --upgrade --no-cache

Paver handles dependencies for Geonode, first setup (this will download and update your python dependencies - ensure you're in a virtualenv)::

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Move the sources into project folder::
Navigate to sources folder and install required packages::

cd /opt/apps/geonode/geonode
sudo pip install -e .
sudo pip install -e . --upgrade --no-cache

.. _geonode_install_settings:

Expand Down
3 changes: 2 additions & 1 deletion geonode/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@

import os

__version__ = (2, 9, 0, 'unstable', 0)
__version__ = (2, 7, 7, 'unstable', 0)


default_app_config = "geonode.apps.AppConfig"

Expand Down
2 changes: 1 addition & 1 deletion geonode/api/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,7 @@ def populate_object(self, style):
""":type: geonode.qgis_server.QGISServerLayer"""
style.layer = qgis_layer.layer
style.type = 'qml'
except:
except BaseException:
pass
return style

Expand Down
19 changes: 13 additions & 6 deletions geonode/api/resourcebase_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,8 +259,7 @@ def filter_bbox(self, queryset, bbox):
northeast_lng,northeast_lat'
returns the modified query
"""
bbox = bbox.split(
',') # TODO: Why is this different when done through haystack?
bbox = bbox.split(',') # TODO: Why is this different when done through haystack?
bbox = map(str, bbox) # 2.6 compat - float to decimal conversion
intersects = ~(Q(bbox_x0__gt=bbox[2]) | Q(bbox_x1__lt=bbox[0]) |
Q(bbox_y0__gt=bbox[3]) | Q(bbox_y1__lt=bbox[1]))
Expand Down Expand Up @@ -746,7 +745,12 @@ def format_objects(self, objects):
if hasattr(obj, 'storeType'):
formatted_obj['store_type'] = obj.storeType
if obj.storeType == 'remoteStore' and hasattr(obj, 'remote_service'):
formatted_obj['online'] = (obj.remote_service.probe == 200)
if obj.remote_service:
formatted_obj['online'] = (obj.remote_service.probe == 200)
else:
formatted_obj['online'] = False

formatted_obj['gtype'] = self.dehydrate_gtype(bundle)

# put the object on the response stack
formatted_objects.append(formatted_obj)
Expand All @@ -770,6 +774,9 @@ def dehydrate_links(self, bundle):

return dehydrated

def dehydrate_gtype(self, bundle):
return bundle.obj.gtype

def populate_object(self, obj):
"""Populate results with necessary fields
Expand All @@ -782,13 +789,13 @@ def populate_object(self, obj):
# Default style
try:
obj.qgis_default_style = obj.qgis_layer.default_style
except:
except BaseException:
obj.qgis_default_style = None

# Styles
try:
obj.qgis_styles = obj.qgis_layer.styles
except:
except BaseException:
obj.qgis_styles = []
return obj

Expand Down Expand Up @@ -835,7 +842,7 @@ def patch_detail(self, request, **kwargs):

layer_id = kwargs['id']
layer = Layer.objects.get(id=layer_id)
except:
except BaseException:
return http.HttpBadRequest(reason=reason)

from geonode.qgis_server.views import default_qml_style
Expand Down
98 changes: 89 additions & 9 deletions geonode/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@

from guardian.models import Group

from allauth.account.utils import user_field, user_email, user_username

from ..utils import json_response


def verify_access_token(key):
try:
Expand All @@ -54,6 +58,65 @@ def get_client_ip(request):
return ip


def extract_headers(request):
"""
Extracts headers from the Django request object
:param request: The current django.http.HttpRequest object
:return: a dictionary with OAuthLib needed headers
"""
headers = request.META.copy()
if "wsgi.input" in headers:
del headers["wsgi.input"]
if "wsgi.errors" in headers:
del headers["wsgi.errors"]
if "HTTP_AUTHORIZATION" in headers:
headers["Authorization"] = headers["HTTP_AUTHORIZATION"]

return headers


@csrf_exempt
def user_info(request):
headers = extract_headers(request)
user = request.user

if not user:
out = {'success': False,
'status': 'error',
'errors': {'user': ['User is not authenticated']}
}
return json_response(out, status=401)

if 'Authorization' not in headers and 'Bearer' not in headers["Authorization"]:
out = {'success': False,
'status': 'error',
'errors': {'auth': ['No token provided.']}
}
return json_response(out, status=403)

groups = [group.name for group in user.groups.all()]
if user.is_superuser:
groups.append("admin")

user_info = json.dumps({
"sub": str(user.id),
"name": " ".join([user_field(user, 'first_name'), user_field(user, 'last_name')]),
"given_name": user_field(user, 'first_name'),
"family_name": user_field(user, 'last_name'),
"email": user_email(user),
"preferred_username": user_username(user),
"groups": groups
})

response = HttpResponse(
user_info,
content_type="application/json"
)
response['Cache-Control'] = 'no-store'
response['Pragma'] = 'no-cache'
return response


@csrf_exempt
def verify_token(request):
"""
Expand All @@ -74,10 +137,12 @@ def verify_token(request):
)
"""

if (request.POST and request.POST['token']):
if (request.POST and 'token' in request.POST):
token = None
try:
token = verify_access_token(request.POST['token'])
except Exception, e:
access_token = request.POST.get('token')
token = verify_access_token(access_token)
except Exception as e:
return HttpResponse(
json.dumps({
'error': str(e)
Expand All @@ -86,18 +151,33 @@ def verify_token(request):
content_type="application/json"
)

return HttpResponse(
json.dumps({
if token:
token_info = json.dumps({
'client_id': token.application.client_id,
'issued_to': token.user.username,
'user_id': token.user.id,
'username': token.user.username,
'issued_to': token.user.username,
'access_token': access_token,
'email': token.user.email,
'verified_email': 'true',
'access_type': 'online',
'expires_in': (token.expires - timezone.now()).total_seconds() * 1000
}),
content_type="application/json"
)
})

response = HttpResponse(
token_info,
content_type="application/json"
)
response["Authorization"] = ("Bearer %s" % access_token)
return response
else:
return HttpResponse(
json.dumps({
'error': 'No access_token from server.'
}),
status=403,
content_type="application/json"
)

return HttpResponse(
json.dumps({
Expand Down
2 changes: 1 addition & 1 deletion geonode/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
def run_setup_hooks(*args, **kwargs):
from django.conf import settings
from .celery_app import app as celery_app
if 'celery_app' not in settings.INSTALLED_APPS:
if celery_app not in settings.INSTALLED_APPS:
settings.INSTALLED_APPS += (celery_app, )


Expand Down
2 changes: 1 addition & 1 deletion geonode/base/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
class BaseAppConfig(NotificationsAppConfigBase):
name = 'geonode.base'
NOTIFICATIONS = (("request_download_resourcebase", _("Request to download a resource"),
_("A request for downloading a resource was sent")),
_("A request for downloading a resource was sent")),
)


Expand Down
2 changes: 1 addition & 1 deletion geonode/base/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def __init__(self, label=None, required=True, help_text=None, widget=None):
tkl = tk.keyword.filter(lang='en')
choices_list.append((tkl[0].id, tkl[0].label))
fields_list.append(forms.MultipleChoiceField(choices=tuple(choices_list)))
except:
except BaseException:
tb = traceback.format_exc()
logger.error(tb)

Expand Down
15 changes: 12 additions & 3 deletions geonode/base/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
from bootstrap3_datetime.widgets import DateTimePicker
from modeltranslation.forms import TranslationModelForm

from geonode.base.models import TopicCategory, Region, License
from geonode.base.models import HierarchicalKeyword, TopicCategory, Region, License
from geonode.people.models import Profile
from geonode.base.enumerations import ALL_LANGUAGES
from django.contrib.auth.models import Group
Expand Down Expand Up @@ -424,9 +424,18 @@ def unicode_escape(unistr):
if not isinstance(_k, basestring):
for _kk in [x.strip() for x in _k]:
_kk = HTMLParser.HTMLParser().unescape(unicode_escape(_kk))
_unsescaped_kwds.append(_kk)
# _hk = HierarchicalKeyword.objects.extra(where=["%s LIKE name||'%%'"], params=[_kk])
_hk = HierarchicalKeyword.objects.filter(name__contains='%s' % _kk.strip())
if _hk and len(_hk) > 0:
_unsescaped_kwds.append(_hk[0])
else:
_unsescaped_kwds.append(_kk)
else:
_unsescaped_kwds.append(_k)
_hk = HierarchicalKeyword.objects.filter(name__iexact=_k)
if _hk and len(_hk) > 0:
_unsescaped_kwds.append(_hk[0])
else:
_unsescaped_kwds.append(_k)
return _unsescaped_kwds

class Meta:
Expand Down
9 changes: 8 additions & 1 deletion geonode/base/management/commands/backup.py
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,14 @@ def handle(self, **options):
print "Saved Static Files from '"+static_files_folder+"'."

# Store Template Folders
template_folders = settings.TEMPLATE_DIRS
template_folders = []
try:
template_folders = settings.TEMPLATE_DIRS
except:
try:
template_folders = settings.TEMPLATES[0]['DIRS']
except:
pass
template_files_folders = os.path.join(target_folder, helpers.TEMPLATE_DIRS)
if not os.path.exists(template_files_folders):
os.makedirs(template_files_folders)
Expand Down
4 changes: 2 additions & 2 deletions geonode/base/management/commands/fixsitename.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ class Command(BaseCommand):
def handle(self, *args, **options):
from django.conf import settings
name = getattr(settings, 'SITENAME', 'GeoNode')
url = getattr(settings, 'SITEURL')

site_url = getattr(settings, 'SITEURL')
url = site_url.rstrip('/') if site_url.startswith('http') else site_url
parsed = urlsplit(url)

site = Site.objects.get_current()
Expand Down
4 changes: 2 additions & 2 deletions geonode/base/management/commands/migrate_layers.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,11 @@ def handle(self, **options):

print "Deserializing "+fixture_file
mangler = helpers.load_class(mangler)

site_url = settings.SITEURL.rstrip('/') if settings.SITEURL.startswith('http') else settings.SITEURL
obj = helpers.load_fixture(app_name, fixture_file, mangler=mangler,
basepk=higher_pk, owner=owner,
datastore=settings.OGC_SERVER['default']['DATASTORE'],
siteurl=settings.SITEURL)
siteurl=site_url)

from django.core import serializers

Expand Down
9 changes: 8 additions & 1 deletion geonode/base/management/commands/restore.py
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,14 @@ def handle(self, **options):
static_folder = os.path.join(target_folder, helpers.STATIC_ROOT)
static_folders = settings.STATICFILES_DIRS
static_files_folders = os.path.join(target_folder, helpers.STATICFILES_DIRS)
template_folders = settings.TEMPLATE_DIRS
template_folders = []
try:
template_folders = settings.TEMPLATE_DIRS
except:
try:
template_folders = settings.TEMPLATES[0]['DIRS']
except:
pass
template_files_folders = os.path.join(target_folder, helpers.TEMPLATE_DIRS)
locale_folders = settings.LOCALE_PATHS
locale_files_folders = os.path.join(target_folder, helpers.LOCALE_PATHS)
Expand Down
40 changes: 40 additions & 0 deletions geonode/base/management/commands/set_all_layers_metadata.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# -*- coding: utf-8 -*-
#########################################################################
#
# Copyright (C) 2017 OSGeo
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#########################################################################

from django.core.management.base import BaseCommand
from geonode.layers.models import Layer
from geonode.catalogue.models import catalogue_post_save


class Command(BaseCommand):
"""Resets Permissions to Public for All Layers
"""

def handle(self, *args, **options):
all_layers = Layer.objects.all()

for index, layer in enumerate(all_layers):
print "[%s / %s] Updating Layer [%s] ..." % ((index + 1), len(all_layers), layer.name)
try:
catalogue_post_save(instance=layer, sender=layer.__class__)
except:
# import traceback
# traceback.print_exc()
print "[ERROR] Layer [%s] couldn't be updated" % (layer.name)
4 changes: 2 additions & 2 deletions geonode/base/management/commands/settings.ini
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ dumprasterdata = yes
# dumps = people,accounts,avatars,backups,licenses,topiccategories,regions,spatialrepresentationtypes,restrictioncodetypes,resourcebases,contactroles,links,useropermissions,groupopermissions,uploadsessions,styles,layers,attributes,layerfiles,maps,maplayers,mapsnapshots,documents,tags

# 2.6+
apps = contenttypes,auth,people,groups,account,actstream,admin,agon_ratings,announcements,avatar,base,dialogos,documents,guardian,invitations,layers,maps,oauth2_provider,pinax_notifications,services,sessions,sites,taggit,tastypie,upload,user_messages
dumps = contenttypes,auth,people,groups,account,actstream,admin,agon_ratings,announcements,avatar,base,dialogos,documents,guardian,invitations,layers,maps,oauth2_provider,pinax_notifications,services,sessions,sites,taggit,tastypie,upload,user_messages
apps = contenttypes,auth,people,groups,account,guardian,admin,actstream,agon_ratings,announcements,avatar,base,dialogos,documents,geoserver,invitations,layers,maps,oauth2_provider,pinax_notifications,services,sites,socialaccount,taggit,tastypie,upload,user_messages
dumps = contenttypes,auth,people,groups,account,guardian,admin,actstream,agon_ratings,announcements,avatar,base,dialogos,documents,geoserver,invitations,layers,maps,oauth2_provider,pinax_notifications,services,sites,socialaccount,taggit,tastypie,upload,user_messages

# Migrate from GN 2.0 to GN 2.4
# migrations = base.resourcebase,layers.layer,layers.attribute,maps.map,maps.maplayer
Expand Down
90 changes: 71 additions & 19 deletions geonode/base/management/commands/updategeoip.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,25 @@
import os
import logging
import gzip
import urllib2 as urllib
import traceback

from six import StringIO
import tarfile

from django.conf import settings
from django.core.management.base import BaseCommand
from django.utils.translation import ugettext_noop as _

logger = logging.getLogger(__name__)

URL = 'http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz'
try:
from django.contrib.gis.geoip2 import GeoIP2 as GeoIP
URL = 'http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.tar.gz'
OLD_FORMAT = False
except ImportError:
try:
from django.contrib.gis.geoip import GeoIP
URL = 'http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz'
OLD_FORMAT = True
except:
URL = None


class Command(BaseCommand):
Expand All @@ -50,33 +57,78 @@ def add_arguments(self, parser):
help=_("Overwrite file if exists"))

def handle(self, *args, **options):
if not settings.MONITORING_ENABLED or not URL:
return

fname = options['file']
fbase = '.'.join(os.path.basename(options['url']).split('.')[:-1])
if not options['overwrite'] and os.path.exists(fname):
logger.warning("File exists, won't overwrite %s", fname)
return

from tqdm import tqdm
import requests
import math
# Streaming, so we can iterate over the response.
r = requests.get(options['url'], stream=True, timeout=10)
# Total size in bytes.
total_size = int(r.headers.get('content-length', 0))
logger.info("Requesting %s", options['url'])
block_size = 1024
wrote = 0
with open('output.bin', 'wb') as f:
for data in tqdm(r.iter_content(block_size), total=math.ceil(total_size//block_size) , unit='KB', unit_scale=False):
wrote = wrote + len(data)
f.write(data)
logger.info(" total_size [%d] / wrote [%d] " % (total_size, wrote))
if total_size != 0 and wrote != total_size:
logger.info("ERROR, something went wrong")
else:
if OLD_FORMAT:
self.handle_old_format(open('output.bin', 'r'), fname)
else:
self.handle_new_format(open('output.bin', 'r'), fname)
try:
# Cleaning up
os.remove('output.bin')
except OSError:
pass

r = urllib.urlopen(options['url'], timeout=10.0)

def handle_new_format(self, f, fname):
try:
data = StringIO(r.read())
with gzip.GzipFile(fileobj=data) as zfile:
with tarfile.open(fileobj=f) as zfile:
members = zfile.getmembers()
for m in members:
if m.name.endswith('GeoLite2-City.mmdb'):
with open(fname, 'wb') as tofile:
try:
fromfile = zfile.extractfile(m)
logger.info("Writing to %s", fname)
tofile.write(fromfile.read())
except Exception, err:
logger.error("Cannot extract %s and write to %s: %s", m, fname, err, exc_info=err)
try:
os.remove(fname)
except OSError:
logger.debug("Could not delete file %s", fname)
return
except Exception, err:
logger.error("Cannot process %s: %s", f, err, exc_info=err)


def handle_old_format(self, f, fname):
try:
with gzip.GzipFile(fileobj=f) as zfile:
logger.info("Writing to %s", fname)
try:
os.remove(fname)
except OSError:
logger.debug('Could not delete file %s' % fname)
with open(fname, 'wb') as tofile:
try:
tofile.write(zfile.read())
except:
tb = traceback.format_exc()
logger.error(tb)

except Exception, err:
logger.error("Cannot extract %s and write to %s: %s", f, fname, err, exc_info=err)
try:
os.remove(fname)
except OSError:
logger.debug('Could not delete file %s' % fname)
except:
tb = traceback.format_exc()
logger.error(tb)
except Exception, err:
logger.error("Cannot process %s: %s", f, err, exc_info=err)
71 changes: 60 additions & 11 deletions geonode/base/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,7 @@ class ResourceBase(PolymorphicModel, PermissionLevelMixin, ItemBase):
manager=_HierarchicalTagManager)
tkeywords = models.ManyToManyField(
ThesaurusKeyword,
verbose_name=_('keywords'),
help_text=tkeywords_help_text,
blank=True)
regions = models.ManyToManyField(
Expand Down Expand Up @@ -736,7 +737,7 @@ class ResourceBase(PolymorphicModel, PermissionLevelMixin, ItemBase):

# metadata XML specific fields
metadata_uploaded = models.BooleanField(default=False)
metadata_uploaded_preserve = models.BooleanField(default=False)
metadata_uploaded_preserve = models.BooleanField(_('Metadata uploaded preserve'), default=False)
metadata_xml = models.TextField(
null=True,
default='<gmd:MD_Metadata xmlns:gmd="http://www.isotc211.org/2005/gmd"/>',
Expand All @@ -757,7 +758,7 @@ class ResourceBase(PolymorphicModel, PermissionLevelMixin, ItemBase):
help_text=_('Is this resource validated from a publisher or editor?'))

# fields necessary for the apis
thumbnail_url = models.TextField(null=True, blank=True)
thumbnail_url = models.TextField(_("Thumbnail url"), null=True, blank=True)
detail_url = models.CharField(max_length=255, null=True, blank=True)
rating = models.IntegerField(default=0, null=True, blank=True)

Expand All @@ -767,6 +768,34 @@ def __unicode__(self):
def get_upload_session(self):
raise NotImplementedError()

@property
def creator(self):
return self.owner.get_full_name() or self.owner.username

@property
def organizationname(self):
return self.owner.organization

@property
def restriction_code(self):
return self.restriction_code_type.gn_description

@property
def publisher(self):
return self.poc.get_full_name() or self.poc.username

@property
def contributor(self):
return self.metadata_author.get_full_name() or self.metadata_author.username

@property
def topiccategory(self):
return self.category.identifier

@property
def csw_crs(self):
return self.srid

@property
def group_name(self):
if self.group:
Expand All @@ -783,6 +812,24 @@ def bbox(self):
self.bbox_y1,
self.srid]

@property
def ll_bbox(self):
"""BBOX is in the format: [x0,x1,y0,y1]."""
from geonode.utils import bbox_to_projection
llbbox = self.bbox[0:4]
if self.srid and 'EPSG:' in self.srid:
try:
llbbox = bbox_to_projection([float(coord) for coord in llbbox] + [self.srid, ],
target_srid=4326)
except BaseException:
pass
return [
llbbox[0], # x0
llbbox[1], # x1
llbbox[2], # y0
llbbox[3], # y1
self.srid]

@property
def bbox_string(self):
"""BBOX is in the format: [x0,y0,x1,y1]."""
Expand All @@ -792,11 +839,12 @@ def bbox_string(self):
@property
def geographic_bounding_box(self):
"""BBOX is in the format: [x0,x1,y0,y1]."""
llbbox = self.ll_bbox[0:4]
return bbox_to_wkt(
self.bbox_x0,
self.bbox_x1,
self.bbox_y0,
self.bbox_y1,
llbbox[0], # x0
llbbox[1], # x1
llbbox[2], # y0
llbbox[3], # y1
srid=self.srid)

@property
Expand Down Expand Up @@ -1073,7 +1121,8 @@ def save_thumbnail(self, filename, image):
filename).replace(
'\\',
'/')
url = urljoin(settings.SITEURL, url_path)
site_url = settings.SITEURL.rstrip('/') if settings.SITEURL.startswith('http') else settings.SITEURL
url = urljoin(site_url, url_path)

# should only have one 'Thumbnail' link
obj, created = Link.objects.get_or_create(resource=self,
Expand Down Expand Up @@ -1388,7 +1437,7 @@ def do_login(sender, user, request, **kwargs):
token = u.hex

# Do GeoServer Login
url = "%s%s?access_token=%s" % (settings.OGC_SERVER['default']['PUBLIC_LOCATION'],
url = "%s%s&access_token=%s" % (settings.OGC_SERVER['default']['LOCATION'],
'ows?service=wms&version=1.3.0&request=GetCapabilities',
token)

Expand Down Expand Up @@ -1431,20 +1480,20 @@ def do_logout(sender, user, request, **kwargs):
pass

# Do GeoServer Logout
if 'access_token' in request.session:
if request and 'access_token' in request.session:
access_token = request.session['access_token']
else:
access_token = None

if access_token:
url = "%s%s?access_token=%s" % (settings.OGC_SERVER['default']['PUBLIC_LOCATION'],
url = "%s%s?access_token=%s" % (settings.OGC_SERVER['default']['LOCATION'],
settings.OGC_SERVER['default']['LOGOUT_ENDPOINT'],
access_token)
header_params = {
"Authorization": ("Bearer %s" % access_token)
}
else:
url = "%s%s" % (settings.OGC_SERVER['default']['PUBLIC_LOCATION'],
url = "%s%s" % (settings.OGC_SERVER['default']['LOCATION'],
settings.OGC_SERVER['default']['LOGOUT_ENDPOINT'])

param = {}
Expand Down
53 changes: 29 additions & 24 deletions geonode/base/populate_test_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def reconnect_signals():
# django's dumpdata

imgfile = StringIO.StringIO('GIF87a\x01\x00\x01\x00\x80\x01\x00\x00\x00\x00ccc,\x00'
'\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02D\x01\x00;')
'\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02D\x01\x00;')
f = SimpleUploadedFile('test_img_file.gif', imgfile.read(), 'image/gif')


Expand Down Expand Up @@ -139,15 +139,20 @@ def callable():

next_date = get_test_date()


layer_data = [('CA', 'abstract1', 'CA', 'geonode:CA', world_extent, next_date(), ('populartag', 'here'), elevation),
('layer2', 'abstract2', 'layer2', 'geonode:layer2', world_extent, next_date(), ('populartag',), elevation),
('uniquetitle', 'something here', 'mylayer', 'geonode:mylayer', world_extent, next_date(), ('populartag',), elevation), # flake8: noqa
('common blar', 'lorem ipsum', 'foo', 'geonode:foo', world_extent, next_date(), ('populartag', 'layertagunique'), location), # flake8: noqa
('common double it', 'whatever', 'whatever', 'geonode:whatever', [0, 1, 0, 1], next_date(), ('populartag',), location), # flake8: noqa
('common double time', 'else', 'fooey', 'geonode:fooey', [0, 5, 0, 5], next_date(), ('populartag',), location), # flake8: noqa
('common bar', 'uniqueabstract', 'quux', 'geonode:quux', [0, 10, 0, 10], next_date(), ('populartag',), biota), # flake8: noqa
('common morx', 'lorem ipsum', 'fleem', 'geonode:fleem', [0, 50, 0, 50], next_date(), ('populartag',), biota), # flake8: noqa
('layer2', 'abstract2', 'layer2', 'geonode:layer2', world_extent, next_date(), ('populartag',), elevation),
('uniquetitle', 'something here', 'mylayer', 'geonode:mylayer',
world_extent, next_date(), ('populartag',), elevation), # flake8: noqa
('common blar', 'lorem ipsum', 'foo', 'geonode:foo', world_extent,
next_date(), ('populartag', 'layertagunique'), location), # flake8: noqa
('common double it', 'whatever', 'whatever', 'geonode:whatever', [
0, 1, 0, 1], next_date(), ('populartag',), location), # flake8: noqa
('common double time', 'else', 'fooey', 'geonode:fooey', [
0, 5, 0, 5], next_date(), ('populartag',), location), # flake8: noqa
('common bar', 'uniqueabstract', 'quux', 'geonode:quux', [
0, 10, 0, 10], next_date(), ('populartag',), biota), # flake8: noqa
('common morx', 'lorem ipsum', 'fleem', 'geonode:fleem', [
0, 50, 0, 50], next_date(), ('populartag',), biota), # flake8: noqa
]

document_data = [('lorem ipsum', 'common lorem ipsum', ('populartag',), world_extent, biota),
Expand Down Expand Up @@ -264,29 +269,29 @@ def remove_models(obj_ids, type=None):
remove_models(None, type='document')

if type == 'map':
m_ids = obj_ids or [m.id for m in Map.objects.all()]
for id in m_ids:
try:
try:
m_ids = obj_ids or [m.id for m in Map.objects.all()]
for id in m_ids:
m = Map.objects.get(pk=id)
m.delete()
except:
pass
except BaseException:
pass
elif type == 'layer':
l_ids = obj_ids or [l.id for l in Layer.objects.all()]
for id in l_ids:
try:
try:
l_ids = obj_ids or [l.id for l in Layer.objects.all()]
for id in l_ids:
l = Layer.objects.get(pk=id)
l.delete()
except:
pass
except BaseException:
pass
elif type == 'document':
d_ids = obj_ids or [d.id for d in Document.objects.all()]
for id in d_ids:
try:
try:
d_ids = obj_ids or [d.id for d in Document.objects.all()]
for id in d_ids:
d = Document.objects.get(pk=id)
d.delete()
except:
pass
except BaseException:
pass


def dump_models(path=None):
Expand Down
6 changes: 3 additions & 3 deletions geonode/base/templatetags/base_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def facets(context):
kws = HierarchicalKeyword.objects.filter(name__iexact=keyword)
for kw in kws:
treeqs = treeqs | HierarchicalKeyword.get_tree(kw)
except:
except BaseException:
# Ignore keywords not actually used?
pass

Expand Down Expand Up @@ -163,7 +163,7 @@ def facets(context):
kws = HierarchicalKeyword.objects.filter(name__iexact=keyword)
for kw in kws:
treeqs = treeqs | HierarchicalKeyword.get_tree(kw)
except:
except BaseException:
# Ignore keywords not actually used?
pass

Expand Down Expand Up @@ -248,7 +248,7 @@ def facets(context):
kws = HierarchicalKeyword.objects.filter(name__iexact=keyword)
for kw in kws:
treeqs = treeqs | HierarchicalKeyword.get_tree(kw)
except:
except BaseException:
# Ignore keywords not actually used?
pass

Expand Down
4 changes: 2 additions & 2 deletions geonode/catalogue/backends/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,10 @@ def csw_gen_xml(self, layer, template):
id_pname = 'dc:identifier'
if self.type == 'deegree':
id_pname = 'apiso:Identifier'

site_url = settings.SITEURL.rstrip('/') if settings.SITEURL.startswith('http') else settings.SITEURL
tpl = get_template(template)
ctx = {'layer': layer,
'SITEURL': settings.SITEURL[:-1],
'SITEURL': site_url,
'id_pname': id_pname,
'LICENSES_METADATA': getattr(settings,
'LICENSES',
Expand Down
4 changes: 2 additions & 2 deletions geonode/catalogue/backends/pycsw_local.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@
# 'loglevel': 'DEBUG',
# 'logfile': '/tmp/pycsw.log',
# 'federatedcatalogues': 'http://geo.data.gov/geoportal/csw/discovery',
# 'pretty_print': 'true',
# 'domainquerytype': 'range',
'pretty_print': 'true',
'domainquerytype': 'range',
'domaincounts': 'true',
'profiles': 'apiso,ebrim',
},
Expand Down
11 changes: 6 additions & 5 deletions geonode/catalogue/backends/pycsw_local_mappings.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,17 @@
'pycsw:Modified': 'date',
'pycsw:Type': 'csw_type',
'pycsw:BoundingBox': 'csw_wkt_geometry',
'pycsw:CRS': 'crs',
'pycsw:CRS': 'csw_crs',
'pycsw:AlternateTitle': 'alternate',
'pycsw:RevisionDate': 'date',
'pycsw:CreationDate': 'date',
'pycsw:PublicationDate': 'date',
'pycsw:OrganizationName': 'uuid',
'pycsw:Organization': 'organizationname',
'pycsw:OrganizationName': 'organizationname',
'pycsw:SecurityConstraints': 'securityconstraints',
'pycsw:ParentIdentifier': 'parentidentifier',
'pycsw:TopicCategory': 'topiccategory',
'pycsw:ResourceLanguage': 'resourcelanguage',
'pycsw:ResourceLanguage': 'language',
'pycsw:GeographicDescriptionCode': 'geodescode',
'pycsw:Denominator': 'denominator',
'pycsw:DistanceValue': 'distancevalue',
Expand All @@ -64,8 +65,8 @@
'pycsw:OperatesOnIdentifier': 'operatesonidentifier',
'pycsw:OperatesOnName': 'operatesoname',
'pycsw:Degree': 'degree',
'pycsw:AccessConstraints': 'accessconstraints',
'pycsw:OtherConstraints': 'otherconstraints',
'pycsw:AccessConstraints': 'restriction_code',
'pycsw:OtherConstraints': 'constraints_other',
'pycsw:Classification': 'classification',
'pycsw:ConditionApplyingToAccessAndUse': 'conditionapplyingtoaccessanduse',
'pycsw:Lineage': 'lineage',
Expand Down
6 changes: 2 additions & 4 deletions geonode/catalogue/backends/pycsw_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,15 +164,13 @@ def query(self, constraint, sortby=None, typenames=None,
# search engine
if 'where' in constraint: # GetRecords with constraint
query = self._get_repo_filter(
Layer.objects).filter(
is_published=True).extra(
Layer.objects).filter(alternate__isnull=False).extra(
where=[
constraint['where']],
params=constraint['values'])
else: # GetRecords sans constraint
query = self._get_repo_filter(
Layer.objects).filter(
is_published=True)
Layer.objects).filter(alternate__isnull=False)

total = query.count()

Expand Down
8 changes: 4 additions & 4 deletions geonode/catalogue/templates/catalogue/full_metadata.xml
Original file line number Diff line number Diff line change
Expand Up @@ -407,16 +407,16 @@
<gmd:geographicElement>
<gmd:EX_GeographicBoundingBox>
<gmd:westBoundLongitude>
<gco:Decimal>{{layer.bbox_x0}}</gco:Decimal>
<gco:Decimal>{{layer.ll_bbox.0}}</gco:Decimal>
</gmd:westBoundLongitude>
<gmd:eastBoundLongitude>
<gco:Decimal>{{layer.bbox_x1}}</gco:Decimal>
<gco:Decimal>{{layer.ll_bbox.1}}</gco:Decimal>
</gmd:eastBoundLongitude>
<gmd:southBoundLatitude>
<gco:Decimal>{{layer.bbox_y0}}</gco:Decimal>
<gco:Decimal>{{layer.ll_bbox.2}}</gco:Decimal>
</gmd:southBoundLatitude>
<gmd:northBoundLatitude>
<gco:Decimal>{{layer.bbox_y1}}</gco:Decimal>
<gco:Decimal>{{layer.ll_bbox.3}}</gco:Decimal>
</gmd:northBoundLatitude>
</gmd:EX_GeographicBoundingBox>
</gmd:geographicElement>
Expand Down
8 changes: 4 additions & 4 deletions geonode/catalogue/templates/geonode_metadata_full.html
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,10 @@ <h2 class="page-title">{{ resource.title }}</h2>
<dt>Extent</dt>
<dd>
<ul class="nop">
<li>long min: {{resource.bbox_x0}}</li>
<li>long max: {{resource.bbox_x1}}</li>
<li>lat min: {{resource.bbox_y0}}</li>
<li>lat max: {{resource.bbox_y1}}</li>
<li>x0: {{resource.bbox_x0}}</li>
<li>x1: {{resource.bbox_x1}}</li>
<li>y0: {{resource.bbox_y0}}</li>
<li>y1: {{resource.bbox_y1}}</li>
</ul>
</dd>

Expand Down
11 changes: 7 additions & 4 deletions geonode/catalogue/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def csw_global_dispatch(request):
mdict = dict(settings.PYCSW['CONFIGURATION'], **CONFIGURATION)

access_token = None
if 'access_token' in request.session:
if request and 'access_token' in request.session:
access_token = request.session['access_token']

absolute_uri = ('%s' % request.build_absolute_uri())
Expand Down Expand Up @@ -93,6 +93,9 @@ def csw_global_dispatch(request):
for e in authorized_ids)) + ")"
authorized_layers_filter = "id IN " + authorized_layers
mdict['repository']['filter'] += " AND " + authorized_layers_filter
if request.user and request.user.is_authenticated():
mdict['repository']['filter'] = "({}) OR ({})".format(mdict['repository']['filter'],
authorized_layers_filter)
else:
authorized_layers_filter = "id = -9999"
mdict['repository']['filter'] += " AND " + authorized_layers_filter
Expand All @@ -108,7 +111,7 @@ def csw_global_dispatch(request):

if not is_admin and settings.GROUP_PRIVATE_RESOURCES:
groups_ids = []
if request.user:
if request.user and request.user.is_authenticated():
for group in request.user.groups.all():
groups_ids.append(group.id)
group_list_all = []
Expand All @@ -124,7 +127,7 @@ def csw_global_dispatch(request):
groups_ids.append(group.id)

public_groups = GroupProfile.objects.exclude(
access="private").exclude(access="public-invite").values('group')
access="private").values('group')
for group in public_groups:
if isinstance(group, dict):
if 'group' in group:
Expand Down Expand Up @@ -202,7 +205,7 @@ def opensearch_dispatch(request):
'contact': settings.PYCSW['CONFIGURATION']['metadata:main']['contact_email'],
'attribution': settings.PYCSW['CONFIGURATION']['metadata:main']['provider_name'],
'tags': settings.PYCSW['CONFIGURATION']['metadata:main']['identification_keywords'].replace(',', ' '),
'url': settings.SITEURL.rstrip('/')
'url': settings.SITEURL.rstrip('/') if settings.SITEURL.startswith('http') else settings.SITEURL
}

return render(request, 'catalogue/opensearch_description.xml', context=ctx,
Expand Down
112 changes: 56 additions & 56 deletions geonode/client/admin_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def enable_theme(self, request, queryset):
request,
"'" + theme.name + "' Theme Activation Failed!",
level=messages.WARNING)
except:
except BaseException:
self.message_user(
request,
"Exception occurred while trying to activate theme: " + theme.name,
Expand Down Expand Up @@ -126,7 +126,7 @@ def disable_theme(self, request, queryset):
theme.is_enabled = False
theme.save()
self.message_user(request, "Disabled Theme: " + theme.name)
except:
except BaseException:
self.message_user(
request,
"Exception occurred while trying to deactivate theme: " + theme.name,
Expand Down Expand Up @@ -164,70 +164,70 @@ def disable_theme(self, request, queryset):


def refresh_theme(self, request, queryset):
"""
Refresh the selected Themes
"""
siteObjs = queryset.filter(is_enabled=True).all()
if len(siteObjs) == 0:
self.message_user(
request,
"Please select at least one active custom theme to disable!",
level=messages.ERROR)
return

if request.POST.get("post"):
value = None
for theme in siteObjs:
try:
if theme.is_enabled:
value = deactivate_theme(theme)
value = activate_theme(theme)
"""
Refresh the selected Themes
"""
siteObjs = queryset.filter(is_enabled=True).all()
if len(siteObjs) == 0:
self.message_user(
request,
"Please select at least one active custom theme to disable!",
level=messages.ERROR)
return

"""
if request.POST.get("post"):
value = None
for theme in siteObjs:
try:
if theme.is_enabled:
value = deactivate_theme(theme)
value = activate_theme(theme)

"""
Final checks if not exception has been raised until now
"""
if value:
self.message_user(request, "Enabled Theme: " + theme.name)
else:
self.message_user(
request,
"'" + theme.name + "' Theme Activation Failed!",
level=messages.WARNING)
except:
self.message_user(
request,
"Exception occurred while trying to activate theme: " + theme.name,
level=messages.ERROR)
tb = traceback.format_exc()
if value:
self.message_user(request, "Enabled Theme: " + theme.name)
else:
self.message_user(
request,
tb,
"'" + theme.name + "' Theme Activation Failed!",
level=messages.WARNING)
logger.debug(tb)
return
out = StringIO.StringIO()
call_command(
'collectstatic',
'--noinput',
stdout=out)
value = out.getvalue()
if not value:
except BaseException:
self.message_user(
request,
"Exception occurred while trying to activate theme: " + theme.name,
level=messages.ERROR)
tb = traceback.format_exc()
self.message_user(
request,
"Collectstatic Regeneration Failed!",
tb,
level=messages.WARNING)
else:
context = {
"objects_name": "Themes",
'title': "Refresh GeoNode Custom Themes",
'action_exec': "refresh_theme",
'cancellable_themes': siteObjs,
'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME,
}
return TemplateResponse(
logger.debug(tb)
return
out = StringIO.StringIO()
call_command(
'collectstatic',
'--noinput',
stdout=out)
value = out.getvalue()
if not value:
self.message_user(
request,
'admin/themes/confirm_cancel.html',
context=context)
"Collectstatic Regeneration Failed!",
level=messages.WARNING)
else:
context = {
"objects_name": "Themes",
'title': "Refresh GeoNode Custom Themes",
'action_exec': "refresh_theme",
'cancellable_themes': siteObjs,
'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME,
}
return TemplateResponse(
request,
'admin/themes/confirm_cancel.html',
context=context)


enable_theme.short_description = "Activate Theme"
Expand Down
24 changes: 21 additions & 3 deletions geonode/client/hooksets.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#########################################################################
try:
import json
except ImportError:
from django.utils import simplejson as json


class GeoExtHookSet(object):
Expand Down Expand Up @@ -60,13 +64,27 @@ def map_update_template(self, context=None):
return 'geoext/maps/map_geoexplorer.js'

def map_embed_template(self, context=None):
return 'geoext/maps/map_geoexplorer.js'
return 'geoext/maps/map_geoexplorer_viewer.js'

def map_download_template(self, context=None):
return 'geoext/maps/map_geoexplorer.js'

# Map Persisting
def viewer_json(self, conf, context=None):
if not context:
context = {}

if isinstance(conf, basestring):
conf = json.loads(conf)
return conf

def update_from_viewer(self, conf, context=None):
conf = self.viewer_json(conf, context=context)
context['config'] = conf
return 'geoext/maps/map_geoexplorer.js'


class LeafletHookSet(object):
class LeafletHookSet(GeoExtHookSet):

# Layers
def layer_detail_template(self, context=None):
Expand Down Expand Up @@ -113,7 +131,7 @@ def map_download_template(self, context=None):
return 'leaflet/maps/map_embed.html'


class ReactHookSet(object):
class ReactHookSet(GeoExtHookSet):

# Layers
def layer_detail_template(self, context=None):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
{% endif %}

{{ partners_header|safe }}
{% if theme.partners %}
{% if theme.partners_title %}
<section id="partners">
<div class="container text-center">
<h2>{{ theme.partners_title }}</h2>
Expand Down
1 change: 0 additions & 1 deletion geonode/client/templates/geoext/geo_header.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
OpenLayers.Util.onImageLoadError = function() {
this.src = '{{ STATIC_URL }}geonode/img/light_gray.jpg';
};
Ext.BLANK_IMAGE_URL = "{{ STATIC_URL }}geonode/img/light_gray.jpg";

OpenLayers.Request.DEFAULT_CONFIG.headers = {
'X-CSRFToken': '{{ csrf_token|escapejs }}'
Expand Down
4 changes: 2 additions & 2 deletions geonode/client/templates/geoext/layers/layer_geoext_map.html
Original file line number Diff line number Diff line change
Expand Up @@ -168,14 +168,14 @@

var zoomToData = function()
{
map.zoomToExtent(extent, true);
map.zoomToExtent(extent, false);
app.mapPanel.center = map.center;
app.mapPanel.zoom = map.zoom;
map.events.unregister('changebaselayer', null, zoomToData);
};
map.events.register('changebaselayer',null,zoomToData);
if(map.baseLayer){
map.zoomToExtent(extent, true);
map.zoomToExtent(extent, false);
}
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,14 +162,14 @@

var zoomToData = function()
{
map.zoomToExtent(extent, true);
map.zoomToExtent(extent, false);
app.mapPanel.center = map.center;
app.mapPanel.zoom = map.zoom;
map.events.unregister('changebaselayer', null, zoomToData);
};
map.events.register('changebaselayer',null,zoomToData);
if(map.baseLayer){
map.zoomToExtent(extent, true);
map.zoomToExtent(extent, false);
}
}
},
Expand Down
5 changes: 3 additions & 2 deletions geonode/client/templates/geoext/maps/map_geoexplorer.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{% include 'geoext/ext_header.html' %}
{% include 'geoext/geo_header.html' %}
{% include "geoext/ext_header.html" %}
{% include "geoext/app_header.html" %}
{% include "geoext/geo_header.html" %}
<link href="{{ STATIC_URL}}geonode/css/geoexplorer/map_geoexplorer.css" rel="stylesheet"/>
<script type="text/javascript" src="{{ STATIC_URL}}geonode/js/extjs/GeoNode-mixin.js"></script>
<script type="text/javascript" src="{{ STATIC_URL}}geonode/js/extjs/Geonode-CatalogueApiSearch.js"></script>
Expand Down
194 changes: 194 additions & 0 deletions geonode/client/templates/geoext/maps/map_geoexplorer_viewer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
{% include "geoext/ext_header.html" %}
{% include "geoext/app_header.html" %}
{% include "geoext/geo_header.html" %}
<link href="{{ STATIC_URL}}geonode/css/geoexplorer/map_geoexplorer.css" rel="stylesheet"/>
<script type="text/javascript" src="{{ STATIC_URL}}geonode/js/extjs/GeoNode-mixin.js"></script>
<script type="text/javascript" src="{{ STATIC_URL}}geonode/js/extjs/Geonode-CatalogueApiSearch.js"></script>
<script type="text/javascript" src="{{ STATIC_URL}}geonode/js/extjs/GeoNode-GeoExplorer.js"></script>
<script type="text/javascript">
var app;
Ext.onReady(function() {
{% autoescape off %}
GeoExt.Lang.set("{{ LANGUAGE_CODE }}");
var config = Ext.apply({
authStatus: {% if user.is_authenticated %} 200{% else %} 401{% endif %},
{% if PROXY_URL %}
proxy: '{{ PROXY_URL }}',
{% endif %}

{% if 'access_token' in request.session %}
access_token: "{{request.session.access_token}}",
{% else %}
access_token: null,
{% endif %}

{% if MAPFISH_PRINT_ENABLED %}
printService: "{{ GEOSERVER_BASE_URL }}pdf/",
{% else %}
printService: null,
printCapabilities: null,
{% endif %}

useCapabilities: false,
useToolbar: true,

/* The URL to a REST map configuration service. This service
* provides listing and, with an authenticated user, saving of
* maps on the server for sharing and editing.
*/
rest: "{% url "maps_browse" %}",
ajaxLoginUrl: "{% url "account_ajax_login" %}",
homeUrl: "{% url "home" %}",
localGeoServerBaseUrl: "{{ GEOSERVER_BASE_URL }}",
localCSWBaseUrl: "{{ CATALOGUE_BASE_URL }}",
csrfToken: "{{ csrf_token }}",
tools: [{ptype: "gxp_getfeedfeatureinfo"}],
listeners: {
"ready": function() {
app.mapPanel.map.getResolutions = function() {
return [156543.03390625, 78271.516953125, 39135.7584765625,
19567.87923828125, 9783.939619140625, 4891.9698095703125,
2445.9849047851562, 1222.9924523925781, 611.4962261962891,
305.74811309814453, 152.87405654907226, 76.43702827453613,
38.218514137268066, 19.109257068634033, 9.554628534317017,
4.777314267158508, 2.388657133579254, 1.194328566789627,
0.5971642833948135, 0.25, 0.1, 0.05];
}
app.mapPanel.map.getServerResolutions = function() {
return [156543.03390625, 78271.516953125, 39135.7584765625,
19567.87923828125, 9783.939619140625,
4891.9698095703125, 2445.9849047851562,
1222.9924523925781, 611.4962261962891,
305.74811309814453, 152.87405654907226,
76.43702827453613, 38.218514137268066,
19.109257068634033, 9.554628534317017,
4.777314267158508, 2.388657133579254,
1.194328566789627, 0.5971642833948135];
}
app.mapPanel.map.getMaxResolution = function() {
return 156543.0339 * 2;
}
app.mapPanel.map.getNumZoomLevels = function() {
return 28;
}
app.mapPanel.map.getMinZoom = function() {
return 0;
}
app.mapPanel.map.getMaxZoom = function() {
return 28;
}
app.mapPanel.map.getResolutionForZoom = function(zoom) {
zoom = Math.max(0, Math.min(zoom, this.getResolutions().length - 1));
var resolution;
var fractionalZoom = true;
if(fractionalZoom) {
var low = Math.floor(zoom);
var high = Math.ceil(zoom);
resolution = this.getResolutions()[low] -
((zoom-low) * (this.getResolutions()[low]-this.getResolutions()[high]));
} else {
resolution = this.getResolutions()[Math.round(zoom)];
}
return resolution;
}
app.mapPanel.map.adjustZoom = function(zoom) {
var maxResolution = 156543.0339 * 4;
if (this.baseLayer && this.baseLayer.wrapDateLine) {
var resolution, resolutions = this.getResolutions(),
// maxResolution = this.getMaxExtent().getWidth() / this.size.w;
maxResolution = this.getMaxResolution();
if (this.getResolutionForZoom(zoom) > maxResolution) {
var fractionalZoom = true;
if (fractionalZoom) {
zoom = this.getZoomForResolution(maxResolution);
} else {
for (var i=zoom|0, ii=resolutions.length; i<ii; ++i) {
if (resolutions[i] <= maxResolution) {
zoom = i;
break;
}
}
}
}
}
return zoom;
}

try {
l = app.selectedLayer.getLayer();
l.addOptions({wrapDateLine:true, displayOutsideMaxExtent: true});
l.addOptions({maxExtent:app.mapPanel.map.getMaxExtent()});
} catch(err) {
;
}

{% if 'access_token' in request.session %}
try {
if(l.url != undefined && (typeof l.url) == "string") {
l.url += ( !l.url.match(/\b\?/gi) || l.url.match(/\b\?/gi).length == 0 ? '?' : '&');
if((!l.url.match(/\baccess_token/gi))) {
l.url += "access_token={{request.session.access_token}}";
} else {
l.url =
l.url.replace(/(access_token)(.+?)(?=\&)/, "$1={{request.session.access_token}}");
}
}
} catch(err) {
console.log(err);
}
{% endif %}

for (var ll in app.mapPanel.map.layers) {
l = app.mapPanel.map.layers[ll];
if (l.url != undefined && (typeof l.url) == "string" && l.url.indexOf('{{GEOSERVER_BASE_URL}}') !== -1) {
l.addOptions({wrapDateLine:true, displayOutsideMaxExtent: true});
l.addOptions({maxExtent:app.mapPanel.map.getMaxExtent()});
{% if 'access_token' in request.session %}
try {
l.url += ( !l.url.match(/\b\?/gi) || l.url.match(/\b\?/gi).length == 0 ? '?' : '&');
if((!l.url.match(/\baccess_token/gi))) {
l.url += "access_token={{request.session.access_token}}";
} else {
l.url =
l.url.replace(/(access_token)(.+?)(?=\&)/, "$1={{request.session.access_token}}");
}
} catch(err) {
console.log(err);
}
{% endif %}
}
}

var map = app.mapPanel.map;
var layer = app.map.layers.slice(-1)[0];
var bbox = layer.bbox;
var crs = layer.srs;
if (bbox != undefined)
{
var extent = new OpenLayers.Bounds();

if (layer.capability.bbox &&
!Array.isArray(layer.capability.bbox) &&
map.projection in layer.capability.bbox) {
bbox = layer.capability.bbox[map.projection].bbox;
extent = OpenLayers.Bounds.fromArray(bbox);
} else {
if (crs != map.projection) {
extent = OpenLayers.Bounds.fromArray(bbox);
extent = extent.clone().transform(crs, map.projection);
} else {
extent = OpenLayers.Bounds.fromArray(bbox);
}
}
}
},
'save': function(obj_id) {
createMapThumbnail(obj_id);
}
}
}, {{ config }});

app = new GeoNode.Viewer(config);
{% endautoescape %}
});
</script>
1 change: 1 addition & 0 deletions geonode/client/templates/geoext/maps/map_include.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<script type="text/javascript" src="{{ STATIC_URL}}geonode/js/extjs/GeoNode-mixin.js"></script>
<script type="text/javascript" src="{{ STATIC_URL}}geonode/js/extjs/Geonode-CatalogueApiSearch.js"></script>
<script type="text/javascript" src="{{ STATIC_URL}}geonode/js/extjs/GeoNode-GeoExplorer.js"></script>
<script type="text/javascript" src="{{ STATIC_URL}}geonode/js/utils/thumbnail.js"></script>
<script type="text/javascript">
var app;
Ext.onReady(function() {
Expand Down
10 changes: 5 additions & 5 deletions geonode/client/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,15 @@ def get_default():
def get_template_loaders():
try:
return settings.TEMPLATE_LOADERS
except:
except BaseException:
try:
return settings.TEMPLATES[0]["OPTIONS"]["loaders"]
except:
except BaseException:
try:
from django.template.loader import get_template
return [get_template(DEFAULT_BASE_TEMPLATE).origin.loader,
get_template(DEFAULT_GEONODE_BASE_TEMPLATE).origin.loader, ]
except:
except BaseException:
return None


Expand All @@ -86,7 +86,7 @@ def find_all_templates(pattern='*.html'):
loader_class = getattr(import_module(module), klass)
try:
loader = loader_class(Engine.get_default())
except:
except BaseException:
loader = loader_class()
for dir in loader.get_template_sources(''):
dir = "%s" % dir
Expand All @@ -113,7 +113,7 @@ def find_all_templates(pattern='*.html'):
fnmatch.fnmatch(basename, pattern) or \
fnmatch.fnmatch(rel_filename, pattern):
templates.append(filename)
except:
except BaseException:
pass
return sorted(set(templates))

Expand Down
44 changes: 44 additions & 0 deletions geonode/context_processors.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
def resource_urls(request):
"""Global values to pass to templates"""
site = Site.objects.get_current()

defaults = dict(
STATIC_URL=settings.STATIC_URL,
CATALOGUE_BASE_URL=default_catalogue_backend()['URL'],
Expand Down Expand Up @@ -143,6 +144,7 @@ def resource_urls(request):
USE_GEOSERVER=settings.USE_GEOSERVER,
USE_NOTIFICATIONS=has_notifications,
USE_MONITORING='geonode.contrib.monitoring' in settings.INSTALLED_APPS and settings.MONITORING_ENABLED,
USE_WORLDMAP=settings.USE_WORLDMAP,
DEFAULT_ANONYMOUS_VIEW_PERMISSION=getattr(settings, 'DEFAULT_ANONYMOUS_VIEW_PERMISSION', False),
DEFAULT_ANONYMOUS_DOWNLOAD_PERMISSION=getattr(settings, 'DEFAULT_ANONYMOUS_DOWNLOAD_PERMISSION', False),
EXIF_ENABLED=getattr(
Expand All @@ -169,4 +171,46 @@ def resource_urls(request):
),
OGC_SERVER=getattr(settings, 'OGC_SERVER', None),
)
if settings.USE_WORLDMAP:
defaults['GEONODE_CLIENT_LOCATION'] = getattr(
settings,
'GEONODE_CLIENT_LOCATION',
'/static/worldmap/worldmap_client/'
)

defaults['USE_HYPERMAP'] = getattr(
settings,
'USE_HYPERMAP',
False
)

# TODO disable DB_DATASTORE setting
defaults['DB_DATASTORE'] = True

defaults['HYPERMAP_REGISTRY_URL'] = settings.HYPERMAP_REGISTRY_URL

defaults['MAPPROXY_URL'] = settings.HYPERMAP_REGISTRY_URL

defaults['SOLR_URL'] = settings.SOLR_URL

defaults['USE_GAZETTEER'] = settings.USE_GAZETTEER

defaults['GOOGLE_API_KEY'] = settings.GOOGLE_API_KEY

defaults['GOOGLE_MAPS_API_KEY'] = settings.GOOGLE_MAPS_API_KEY

defaults['WM_COPYRIGHT_URL'] = getattr(
settings,
'WM_COPYRIGHT_URL',
'http://gis.harvard.edu/'
)

defaults['WM_COPYRIGHT_TEXT'] = getattr(
settings,
'WM_COPYRIGHT_TEXT',
'Center for Geographic Analysis'
)

defaults['HYPERMAP_REGISTRY_URL'] = settings.HYPERMAP_REGISTRY_URL

return defaults
8 changes: 4 additions & 4 deletions geonode/contrib/createlayer/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#########################################################################

from django import forms

from django.utils.translation import ugettext as _

GEOMETRY_TYPES = (
('Point', 'Points'),
Expand All @@ -32,9 +32,9 @@ class NewLayerForm(forms.Form):
"""
A form to create an empty layer in PostGIS.
"""
name = forms.CharField(label='Layer name', max_length=255)
title = forms.CharField(label='Layer title', max_length=255)
geometry_type = forms.ChoiceField(choices=GEOMETRY_TYPES)
name = forms.CharField(label=_('Layer name'), max_length=255)
title = forms.CharField(label=_('Layer title'), max_length=255)
geometry_type = forms.ChoiceField(label=_('Geometry type'), choices=GEOMETRY_TYPES)

permissions = forms.CharField(
widget=forms.HiddenInput(
Expand Down
22 changes: 13 additions & 9 deletions geonode/contrib/createlayer/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@

logger = logging.getLogger(__name__)

BBOX = [-180, 180, -90, 90]
DATA_QUALITY_MESSAGE = "Created with GeoNode"


def create_layer(name, title, owner_name, geometry_type, attributes=None):
"""
Expand Down Expand Up @@ -70,11 +73,11 @@ def create_gn_layer(workspace, datastore, name, title, owner_name):
title=title,
owner=owner,
uuid=str(uuid.uuid4()),
bbox_x0=-180,
bbox_x1=180,
bbox_y0=-90,
bbox_y1=90,
srid='EPSG:4326',
bbox_x0=BBOX[0],
bbox_x1=BBOX[1],
bbox_y0=BBOX[2],
bbox_y1=BBOX[3],
data_quality_statement=DATA_QUALITY_MESSAGE,
)
return layer

Expand Down Expand Up @@ -142,16 +145,16 @@ def get_or_create_datastore(cat, workspace=None, charset="UTF-8"):
"""

# TODO refactor this and geoserver.helpers._create_db_featurestore
dsname = ogc_server_settings.DATASTORE
# dsname = ogc_server_settings.DATASTORE
dsname = ogc_server_settings.datastore_db['NAME']
if not ogc_server_settings.DATASTORE:
msg = ("To use the createlayer application you must set ogc_server_settings.datastore_db['ENGINE']"
" to 'django.contrib.gis.db.backends.postgis")
logger.error(msg)
raise GeoNodeException(msg)

try:
ds = cat.get_store(dsname, workspace) or\
cat.create_datastore(dsname, workspace=workspace)
ds = cat.get_store(dsname, workspace)
except FailedRequestError:
ds = cat.create_datastore(dsname, workspace=workspace)

Expand Down Expand Up @@ -228,12 +231,13 @@ def create_gs_layer(name, title, geometry_type, attributes=None):
"<nativeName>{native_name}</nativeName>"
"<title>{title}</title>"
"<srs>EPSG:4326</srs>"
"<latLonBoundingBox><minx>-180</minx><maxx>180</maxx><miny>-90</miny><maxy>90</maxy>"
"<latLonBoundingBox><minx>{minx}</minx><maxx>{maxx}</maxx><miny>{miny}</miny><maxy>{maxy}</maxy>"
"<crs>EPSG:4326</crs></latLonBoundingBox>"
"{attributes}"
"</featureType>").format(
name=name.encode('UTF-8', 'strict'), native_name=native_name.encode('UTF-8', 'strict'),
title=title.encode('UTF-8', 'strict'),
minx=BBOX[0], maxx=BBOX[1], miny=BBOX[2], maxy=BBOX[3],
attributes=attributes_block)

url = ('%s/workspaces/%s/datastores/%s/featuretypes'
Expand Down
2 changes: 1 addition & 1 deletion geonode/contrib/dynamic/postgis.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ def execute(sql):
cursor = db.connections['datastore'].cursor()
try:
cursor.execute(sql)
except:
except BaseException:
raise
finally:
cursor.close()
Expand Down
4 changes: 2 additions & 2 deletions geonode/contrib/exif/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ def exif_extract_dict(doc):
if date:
try:
date = convertExifDateToDjangoDate(date)
except:
except BaseException:
logger.error("Could not parse exif date")
date = None

Expand Down Expand Up @@ -162,7 +162,7 @@ def exif_extract_metadata_doc(doc):
if date:
try:
date = convertExifDateToDjangoDate(date)
except:
except BaseException:
logger.error("Could not parse exif date")
date = None

Expand Down
6 changes: 4 additions & 2 deletions geonode/contrib/metadataxsl/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
#
#########################################################################

from urlparse import urljoin

from django.conf import settings
from django.core.urlresolvers import reverse
from django.db.models import signals
Expand All @@ -44,8 +46,8 @@ def add_xsl_link(resourcebase):
"""

urlpath = reverse('prefix_xsl_line', args=[resourcebase.id])

url = '{}{}'.format(settings.SITEURL, urlpath)
site_url = settings.SITEURL.rstrip('/') if settings.SITEURL.startswith('http') else settings.SITEURL
url = urljoin(site_url, urlpath)

link, created = Link.objects.get_or_create(
resource=resourcebase,
Expand Down
1 change: 1 addition & 0 deletions geonode/contrib/metadataxsl/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class MetadataXSLTest(GeoNodeBaseTestSupport):
"""
Tests geonode.contrib.metadataxsl app/module
"""

def setUp(self):
super(MetadataXSLTest, self).setUp()
self.adm_un = "admin"
Expand Down
11 changes: 6 additions & 5 deletions geonode/contrib/metadataxsl/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,26 +43,27 @@ def prefix_xsl_line(req, id):
try:
catalogue = get_catalogue()
record = catalogue.get_record(resource.uuid)
except Exception, err:
if record:
logger.debug(record.xml)
except Exception as err:
msg = 'Could not connect to catalogue to save information for layer "%s"' % str(resource.title)
logger.warn(msg)
raise err

try:
xml = record.xml
# generate an XML document (GeoNode's default is ISO)
if resource.metadata_uploaded and resource.metadata_uploaded_preserve:
md_doc = etree.tostring(etree.fromstring(resource.metadata_xml))
else:
md_doc = catalogue.catalogue.csw_gen_xml(resource, 'catalogue/full_metadata.xml')
xml = md_doc
except:
except BaseException:
logger.error(traceback.format_exc())
return HttpResponse(
"Resource Metadata not available!"
)

xsl_path = '{}/static/metadataxsl/metadata.xsl'.format(settings.SITEURL.rstrip('/'))
site_url = settings.SITEURL.rstrip('/') if settings.SITEURL.startswith('http') else settings.SITEURL
xsl_path = '{}/static/metadataxsl/metadata.xsl'.format(site_url)
xsl_line = '<?xml-stylesheet type="text/xsl" href="{}"?>'.format(xsl_path)

return HttpResponse(
Expand Down
12 changes: 8 additions & 4 deletions geonode/contrib/monitoring/collector.py
Original file line number Diff line number Diff line change
Expand Up @@ -316,10 +316,10 @@ def process_host_geonode(self, service, data, valid_from, valid_to):
print MetricValue.add(**mdata)

if data['data'].get('cpu'):
l = data['data']['cpu']['usage']
mdata = {'value': l,
'value_raw': l,
'value_num': l,
_l = data['data']['cpu']['usage']
mdata = {'value': _l,
'value_raw': _l,
'value_num': _l,
'metric': 'cpu.usage',
'label': 'Seconds',
}
Expand Down Expand Up @@ -536,10 +536,13 @@ def set_error_values(self, requests, valid_from, valid_to,
'service': service}
cnt = with_errors.count()
print MetricValue.add(value=cnt, value_num=cnt, value_raw=cnt, **defaults)

defaults['metric'] = 'response.error.types'
for label in labels:
cnt = with_errors.filter(exceptions__error_type=label).count()

defaults['label'] = label

defaults['samples_count'] = cnt
print MetricValue.add(value=cnt, value_num=cnt, value_raw=cnt, **defaults)

Expand Down Expand Up @@ -786,6 +789,7 @@ def get_metrics_for(self, metric_name,
Returns metric data for given metric. Returned dataset contains list of periods and values in that periods
"""
utc = pytz.utc

default_interval = False
now = datetime.utcnow().replace(tzinfo=utc)
if not interval:
Expand Down
Loading